Fix for CVE-2014-0224
[openssl.git] / ssl / s3_clnt.c
index d959474fc04ac0186c4e8f50a43a8592732b10f8..c99a4c495efe66c9e63319fdd8c022d1eb5979c3 100644 (file)
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
@@ -200,6 +203,18 @@ int ssl3_connect(SSL *s)
        s->in_handshake++;
        if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 
 
+#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)
+               {
+               s->tlsext_hb_pending = 0;
+               s->tlsext_hb_seq++;
+               }
+#endif
+
        for (;;)
                {
                state=s->state;
@@ -277,24 +292,19 @@ int ssl3_connect(SSL *s)
                case SSL3_ST_CR_SRVR_HELLO_A:
                case SSL3_ST_CR_SRVR_HELLO_B:
                        ret=ssl3_get_server_hello(s);
-#ifndef OPENSSL_NO_SRP
-                       if (ret == 0 && s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME)
-                               {
-                               if (!SRP_have_to_put_srp_username(s))
-                                       {
-                                       SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_MISSING_SRP_USERNAME);
-                                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED);
-                                       goto end;
-                                       }
-                               s->state=SSL3_ST_CW_CLNT_HELLO_A;
-                               if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
-                               break;
-                               }
-#endif
                        if (ret <= 0) goto end;
 
                        if (s->hit)
+                               {
                                s->state=SSL3_ST_CR_FINISHED_A;
+#ifndef OPENSSL_NO_TLSEXT
+                               if (s->tlsext_ticket_expected)
+                                       {
+                                       /* receive renewed session ticket */
+                                       s->state=SSL3_ST_CR_SESSION_TICKET_A;
+                                       }
+#endif
+                               }
                        else
                                s->state=SSL3_ST_CR_CERT_A;
                        s->init_num=0;
@@ -377,7 +387,7 @@ int ssl3_connect(SSL *s)
                                {
                                if ((ret = SRP_Calc_A_param(s))<=0)
                                        {
-                                       SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_SRP_A_CALC);
+                                       SSLerr(SSL_F_SSL3_CONNECT,SSL_R_SRP_A_CALC);
                                        ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
                                        goto end;
                                        }
@@ -448,7 +458,15 @@ int ssl3_connect(SSL *s)
                        ret=ssl3_send_change_cipher_spec(s,
                                SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
                        if (ret <= 0) goto end;
+
+#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
                        s->state=SSL3_ST_CW_FINISHED_A;
+#else
+                       if (s->s3->next_proto_neg_seen)
+                               s->state=SSL3_ST_CW_NEXT_PROTO_A;
+                       else
+                               s->state=SSL3_ST_CW_FINISHED_A;
+#endif
                        s->init_num=0;
 
                        s->session->cipher=s->s3->tmp.new_cipher;
@@ -476,6 +494,15 @@ int ssl3_connect(SSL *s)
 
                        break;
 
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+               case SSL3_ST_CW_NEXT_PROTO_A:
+               case SSL3_ST_CW_NEXT_PROTO_B:
+                       ret=ssl3_send_next_proto(s);
+                       if (ret <= 0) goto end;
+                       s->state=SSL3_ST_CW_FINISHED_A;
+                       break;
+#endif
+
                case SSL3_ST_CW_FINISHED_A:
                case SSL3_ST_CW_FINISHED_B:
                        ret=ssl3_send_finished(s,
@@ -532,6 +559,7 @@ int ssl3_connect(SSL *s)
                case SSL3_ST_CR_FINISHED_A:
                case SSL3_ST_CR_FINISHED_B:
 
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
                                SSL3_ST_CR_FINISHED_B);
                        if (ret <= 0) goto end;
@@ -628,7 +656,7 @@ int ssl3_client_hello(SSL *s)
        unsigned char *buf;
        unsigned char *p,*d;
        int i;
-       unsigned long Time,l;
+       unsigned long l;
 #ifndef OPENSSL_NO_COMP
        int j;
        SSL_COMP *comp;
@@ -653,17 +681,50 @@ int ssl3_client_hello(SSL *s)
                /* else use the pre-loaded session */
 
                p=s->s3->client_random;
-               Time=(unsigned long)time(NULL);                 /* Time */
-               l2n(Time,p);
-               if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+
+               if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
                        goto err;
 
                /* Do the message type and length last */
                d=p= &(buf[4]);
 
+               /* version indicates the negotiated version: for example from
+                * an SSLv2/v3 compatible client hello). The client_version
+                * field is the maximum version we permit and it is also
+                * used in RSA encrypted premaster secrets. Some servers can
+                * choke if we initially report a higher version then
+                * renegotiate to a lower one in the premaster secret. This
+                * didn't happen with TLS 1.0 as most servers supported it
+                * but it can with TLS 1.1 or later if the server only supports
+                * 1.0.
+                *
+                * Possible scenario with previous logic:
+                *      1. Client hello indicates TLS 1.2
+                *      2. Server hello says TLS 1.0
+                *      3. RSA encrypted premaster secret uses 1.2.
+                *      4. Handhaked proceeds using TLS 1.0.
+                *      5. Server sends hello request to renegotiate.
+                *      6. Client hello indicates TLS v1.0 as we now
+                *         know that is maximum server supports.
+                *      7. Server chokes on RSA encrypted premaster secret
+                *         containing version 1.0.
+                *
+                * For interoperability it should be OK to always use the
+                * maximum version we support in client hello and then rely
+                * on the checking of version to ensure the servers isn't
+                * being inconsistent: for example initially negotiating with
+                * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
+                * client_version in client hello and not resetting it to
+                * the negotiated version.
+                */
+#if 0
                *(p++)=s->version>>8;
                *(p++)=s->version&0xff;
                s->client_version=s->version;
+#else
+               *(p++)=s->client_version>>8;
+               *(p++)=s->client_version&0xff;
+#endif
 
                /* Random stuff */
                memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
@@ -693,6 +754,15 @@ int ssl3_client_hello(SSL *s)
                        SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
                        goto err;
                        }
+#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
+                       /* Some servers hang if client hello > 256 bytes
+                        * as hack workaround chop number of supported ciphers
+                        * to keep it well below this if we use TLS v1.2
+                        */
+                       if (TLS1_get_version(s) >= TLS1_2_VERSION
+                               && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
+                               i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
+#endif
                s2n(i,p);
                p+=i;
 
@@ -846,6 +916,7 @@ int ssl3_get_server_hello(SSL *s)
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
                goto f_err;
                }
+           s->s3->flags |= SSL3_FLAGS_CCS_OK;
            s->hit=1;
            }
        else    /* a miss or crap from the other end */
@@ -873,6 +944,14 @@ int ssl3_get_server_hello(SSL *s)
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED);
                goto f_err;
                }
+       /* TLS v1.2 only ciphersuites require v1.2 or later */
+       if ((c->algorithm_ssl & SSL_TLSV1_2) && 
+               (TLS1_get_version(s) < TLS1_2_VERSION))
+               {
+               al=SSL_AD_ILLEGAL_PARAMETER;
+               SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
+               goto f_err;
+               }
        p+=ssl_put_cipher_by_char(s,NULL,NULL);
 
        sk=ssl_get_ciphers_by_id(s);
@@ -904,9 +983,14 @@ int ssl3_get_server_hello(SSL *s)
                        }
                }
        s->s3->tmp.new_cipher=c;
-       if (!ssl3_digest_cached_records(s))
+       /* Don't digest cached records if TLS v1.2: we may need them for
+        * client authentication.
+        */
+       if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s))
+               {
+               al = SSL_AD_INTERNAL_ERROR;
                goto f_err;
-
+               }
        /* lets get the compression algorithm */
        /* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
@@ -979,7 +1063,7 @@ int ssl3_get_server_hello(SSL *s)
                /* wrong packet length */
                al=SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
-               goto err;
+               goto f_err;
                }
 
        return(1);
@@ -1185,6 +1269,7 @@ int ssl3_get_key_exchange(SSL *s)
        int al,i,j,param_len,ok;
        long n,alg_k,alg_a;
        EVP_PKEY *pkey=NULL;
+       const EVP_MD *md = NULL;
 #ifndef OPENSSL_NO_RSA
        RSA *rsa=NULL;
 #endif
@@ -1635,6 +1720,38 @@ int ssl3_get_key_exchange(SSL *s)
        /* if it was signed, check the signature */
        if (pkey != NULL)
                {
+               if (TLS1_get_version(s) >= TLS1_2_VERSION)
+                       {
+                       int sigalg = tls12_get_sigid(pkey);
+                       /* Should never happen */
+                       if (sigalg == -1)
+                               {
+                               SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+                               goto err;
+                               }
+                       /* Check key type is consistent with signature */
+                       if (sigalg != (int)p[1])
+                               {
+                               SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_TYPE);
+                               al=SSL_AD_DECODE_ERROR;
+                               goto f_err;
+                               }
+                       md = tls12_get_hash(p[0]);
+                       if (md == NULL)
+                               {
+                               SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
+                               al=SSL_AD_DECODE_ERROR;
+                               goto f_err;
+                               }
+#ifdef SSL_DEBUG
+fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+#endif
+                       p += 2;
+                       n -= 2;
+                       }
+               else
+                       md = EVP_sha1();
+                       
                n2s(p,i);
                n-=2;
                j=EVP_PKEY_size(pkey);
@@ -1648,7 +1765,7 @@ int ssl3_get_key_exchange(SSL *s)
                        }
 
 #ifndef OPENSSL_NO_RSA
-               if (pkey->type == EVP_PKEY_RSA)
+               if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION)
                        {
                        int num;
 
@@ -1656,6 +1773,8 @@ int ssl3_get_key_exchange(SSL *s)
                        q=md_buf;
                        for (num=2; num > 0; num--)
                                {
+                               EVP_MD_CTX_set_flags(&md_ctx,
+                                       EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
                                EVP_DigestInit_ex(&md_ctx,(num == 2)
                                        ?s->ctx->md5:s->ctx->sha1, NULL);
                                EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
@@ -1683,11 +1802,8 @@ int ssl3_get_key_exchange(SSL *s)
                        }
                else
 #endif
-#ifndef OPENSSL_NO_DSA
-                       if (pkey->type == EVP_PKEY_DSA)
                        {
-                       /* lets do DSS */
-                       EVP_VerifyInit_ex(&md_ctx,EVP_dss1(), NULL);
+                       EVP_VerifyInit_ex(&md_ctx, md, NULL);
                        EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
                        EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
                        EVP_VerifyUpdate(&md_ctx,param,param_len);
@@ -1699,30 +1815,6 @@ int ssl3_get_key_exchange(SSL *s)
                                goto f_err;
                                }
                        }
-               else
-#endif
-#ifndef OPENSSL_NO_ECDSA
-                       if (pkey->type == EVP_PKEY_EC)
-                       {
-                       /* let's do ECDSA */
-                       EVP_VerifyInit_ex(&md_ctx,EVP_ecdsa(), NULL);
-                       EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
-                       EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
-                       EVP_VerifyUpdate(&md_ctx,param,param_len);
-                       if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
-                               {
-                               /* bad signature */
-                               al=SSL_AD_DECRYPT_ERROR;
-                               SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
-                               goto f_err;
-                               }
-                       }
-               else
-#endif
-                       {
-                       SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
-                       goto err;
-                       }
                }
        else
                {
@@ -1769,7 +1861,7 @@ int ssl3_get_certificate_request(SSL *s)
        {
        int ok,ret=0;
        unsigned long n,nc,l;
-       unsigned int llen,ctype_num,i;
+       unsigned int llen, ctype_num,i;
        X509_NAME *xn=NULL;
        const unsigned char *p,*q;
        unsigned char *d;
@@ -1789,6 +1881,14 @@ int ssl3_get_certificate_request(SSL *s)
        if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
                {
                s->s3->tmp.reuse_message=1;
+               /* If we get here we don't need any cached handshake records
+                * as we wont be doing client auth.
+                */
+               if (s->s3->handshake_buffer)
+                       {
+                       if (!ssl3_digest_cached_records(s))
+                               goto err;
+                       }
                return(1);
                }
 
@@ -1825,6 +1925,26 @@ int ssl3_get_certificate_request(SSL *s)
        for (i=0; i<ctype_num; i++)
                s->s3->tmp.ctype[i]= p[i];
        p+=ctype_num;
+       if (TLS1_get_version(s) >= TLS1_2_VERSION)
+               {
+               n2s(p, llen);
+               /* Check we have enough room for signature algorithms and
+                * following length value.
+                */
+               if ((unsigned long)(p - d + llen + 2) > n)
+                       {
+                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+                       SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
+                       goto err;
+                       }
+               if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
+                       {
+                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
+                       SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+                       goto err;
+                       }
+               p += llen;
+               }
 
        /* get the CA RDNs */
        n2s(p,llen);
@@ -1837,7 +1957,7 @@ fclose(out);
 }
 #endif
 
-       if ((llen+ctype_num+2+1) != n)
+       if ((unsigned long)(p - d + llen) != n)
                {
                ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
                SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
@@ -1943,7 +2063,7 @@ int ssl3_get_new_session_ticket(SSL *s)
        if (n < 6)
                {
                /* need at least ticket_lifetime_hint + ticket length */
-               al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
+               al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
@@ -1954,7 +2074,7 @@ int ssl3_get_new_session_ticket(SSL *s)
        /* ticket_lifetime_hint + ticket_length + ticket */
        if (ticklen + 6 != n)
                {
-               al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
+               al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
@@ -2349,6 +2469,7 @@ int ssl3_send_client_key_exchange(SSL *s)
                        if (!DH_generate_key(dh_clnt))
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+                               DH_free(dh_clnt);
                                goto err;
                                }
 
@@ -2360,6 +2481,7 @@ int ssl3_send_client_key_exchange(SSL *s)
                        if (n <= 0)
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+                               DH_free(dh_clnt);
                                goto err;
                                }
 
@@ -2685,7 +2807,7 @@ int ssl3_send_client_key_exchange(SSL *s)
 
                        if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
                                {
-                               SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
                                goto err;
                                }
                        }
@@ -2809,12 +2931,13 @@ int ssl3_send_client_verify(SSL *s)
        unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
        EVP_PKEY *pkey;
        EVP_PKEY_CTX *pctx=NULL;
-#ifndef OPENSSL_NO_RSA
+       EVP_MD_CTX mctx;
        unsigned u=0;
-#endif
        unsigned long n;
        int j;
 
+       EVP_MD_CTX_init(&mctx);
+
        if (s->state == SSL3_ST_CW_CERT_VRFY_A)
                {
                d=(unsigned char *)s->init_buf->data;
@@ -2825,7 +2948,8 @@ int ssl3_send_client_verify(SSL *s)
                EVP_PKEY_sign_init(pctx);
                if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
                        {
-                       s->method->ssl3_enc->cert_verify_mac(s,
+                       if (TLS1_get_version(s) < TLS1_2_VERSION)
+                               s->method->ssl3_enc->cert_verify_mac(s,
                                                NID_sha1,
                                                &(data[MD5_DIGEST_LENGTH]));
                        }
@@ -2833,6 +2957,41 @@ int ssl3_send_client_verify(SSL *s)
                        {
                        ERR_clear_error();
                        }
+               /* For TLS v1.2 send signature algorithm and signature
+                * using agreed digest and cached handshake records.
+                */
+               if (TLS1_get_version(s) >= TLS1_2_VERSION)
+                       {
+                       long hdatalen = 0;
+                       void *hdata;
+                       const EVP_MD *md = s->cert->key->digest;
+                       hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,
+                                                               &hdata);
+                       if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+                                               ERR_R_INTERNAL_ERROR);
+                               goto err;
+                               }
+                       p += 2;
+#ifdef SSL_DEBUG
+                       fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
+                                                       EVP_MD_name(md));
+#endif
+                       if (!EVP_SignInit_ex(&mctx, md, NULL)
+                               || !EVP_SignUpdate(&mctx, hdata, hdatalen)
+                               || !EVP_SignFinal(&mctx, p + 2, &u, pkey))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+                                               ERR_R_EVP_LIB);
+                               goto err;
+                               }
+                       s2n(u,p);
+                       n = u + 4;
+                       if (!ssl3_digest_cached_records(s))
+                               goto err;
+                       }
+               else
 #ifndef OPENSSL_NO_RSA
                if (pkey->type == EVP_PKEY_RSA)
                        {
@@ -2915,9 +3074,11 @@ int ssl3_send_client_verify(SSL *s)
                s->init_num=(int)n+4;
                s->init_off=0;
                }
+       EVP_MD_CTX_cleanup(&mctx);
        EVP_PKEY_CTX_free(pctx);
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 err:
+       EVP_MD_CTX_cleanup(&mctx);
        EVP_PKEY_CTX_free(pctx);
        return(-1);
        }
@@ -3041,7 +3202,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
        if (idx == SSL_PKEY_ECC)
                {
                if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
-                   s->s3->tmp.new_cipher) == 0) 
+                                                               s) == 0) 
                        { /* check failed */
                        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT);
                        goto f_err;
@@ -3137,6 +3298,32 @@ err:
        return(0);
        }
 
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+int ssl3_send_next_proto(SSL *s)
+       {
+       unsigned int len, padding_len;
+       unsigned char *d;
+
+       if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
+               {
+               len = s->next_proto_negotiated_len;
+               padding_len = 32 - ((len + 2) % 32);
+               d = (unsigned char *)s->init_buf->data;
+               d[4] = len;
+               memcpy(d + 5, s->next_proto_negotiated, len);
+               d[5 + len] = padding_len;
+               memset(d + 6 + len, 0, padding_len);
+               *(d++)=SSL3_MT_NEXT_PROTO;
+               l2n3(2 + len + padding_len, d);
+               s->state = SSL3_ST_CW_NEXT_PROTO_B;
+               s->init_num = 4 + 2 + len + padding_len;
+               s->init_off = 0;
+               }
+
+       return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+}
+#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
+
 /* Check to see if handshake is full or resumed. Usually this is just a
  * case of checking to see if a cache hit has occurred. In the case of
  * session tickets we have to check the next message to be sure.