Remove tls12_copy_sigalgs_old()
[openssl.git] / ssl / t1_lib.c
index ca4e7d695667af3b2e4d1d2be1e5e651779b1ba5..e2e5f6025ef805d14055ab2321cc83ae46695381 100644 (file)
@@ -41,6 +41,8 @@ SSL3_ENC_METHOD const TLSv1_enc_data = {
     0,
     SSL3_HM_HEADER_LENGTH,
     ssl3_set_handshake_header,
+    ssl3_set_handshake_header2,
+    tls_close_construct_packet,
     ssl3_handshake_write
 };
 
@@ -59,6 +61,8 @@ SSL3_ENC_METHOD const TLSv1_1_enc_data = {
     SSL_ENC_FLAG_EXPLICIT_IV,
     SSL3_HM_HEADER_LENGTH,
     ssl3_set_handshake_header,
+    ssl3_set_handshake_header2,
+    tls_close_construct_packet,
     ssl3_handshake_write
 };
 
@@ -78,6 +82,8 @@ SSL3_ENC_METHOD const TLSv1_2_enc_data = {
         | SSL_ENC_FLAG_TLS1_2_CIPHERS,
     SSL3_HM_HEADER_LENGTH,
     ssl3_set_handshake_header,
+    ssl3_set_handshake_header2,
+    tls_close_construct_packet,
     ssl3_handshake_write
 };
 
@@ -209,7 +215,6 @@ static const unsigned char eccurves_all[] = {
     0, 3,                       /* sect163r2 (3) */
 };
 
-
 static const unsigned char suiteb_curves[] = {
     0, TLSEXT_curve_P_256,
     0, TLSEXT_curve_P_384
@@ -250,8 +255,7 @@ int tls1_ec_nid2curve_id(int nid)
  * so cannot happen in the 1.0.x series.)
  */
 static int tls1_get_curvelist(SSL *s, int sess,
-                              const unsigned char **pcurves,
-                              size_t *num_curves)
+                              const unsigned char **pcurves, size_t *num_curves)
 {
     size_t pcurveslen = 0;
     if (sess) {
@@ -384,8 +388,7 @@ int tls1_shared_curve(SSL *s, int nmatch)
         /* In practice, NID_undef == 0 but let's be precise. */
         return nmatch == -1 ? 0 : NID_undef;
     if (!tls1_get_curvelist
-        (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref,
-         &num_pref))
+        (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref, &num_pref))
         return nmatch == -1 ? 0 : NID_undef;
 
     /*
@@ -396,7 +399,7 @@ int tls1_shared_curve(SSL *s, int nmatch)
         supp = eccurves_all;
         num_supp = sizeof(eccurves_all) / 2;
     } else if (num_pref == 0 &&
-        (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) {
+               (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) {
         pref = eccurves_all;
         num_pref = sizeof(eccurves_all) / 2;
     }
@@ -489,8 +492,7 @@ static int nid_cb(const char *elem, int len, void *arg)
 }
 
 /* Set curves based on a colon separate list */
-int tls1_set_curves_list(unsigned char **pext, size_t *pextlen,
-                         const char *str)
+int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, const char *str)
 {
     nid_cb_st ncb;
     ncb.nidcnt = 0;
@@ -716,19 +718,19 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
  */
 
 #ifdef OPENSSL_NO_RSA
-# define tlsext_sigalg_rsa(md) /* */
+# define tlsext_sigalg_rsa(md)  /* */
 #else
 # define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
 #endif
 
 #ifdef OPENSSL_NO_DSA
-# define tlsext_sigalg_dsa(md) /* */
+# define tlsext_sigalg_dsa(md)  /* */
 #else
 # define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
 #endif
 
 #ifdef OPENSSL_NO_EC
-# define tlsext_sigalg_ecdsa(md) /* */
+# define tlsext_sigalg_ecdsa(md)/* */
 #else
 # define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
 #endif
@@ -746,8 +748,8 @@ static const unsigned char tls12_sigalgs[] = {
         tlsext_sigalg(TLSEXT_hash_sha1)
 #ifndef OPENSSL_NO_GOST
         TLSEXT_hash_gostr3411, TLSEXT_signature_gostr34102001,
-        TLSEXT_hash_gostr34112012_256, TLSEXT_signature_gostr34102012_256,
-        TLSEXT_hash_gostr34112012_512, TLSEXT_signature_gostr34102012_512
+    TLSEXT_hash_gostr34112012_256, TLSEXT_signature_gostr34102012_256,
+    TLSEXT_hash_gostr34112012_512, TLSEXT_signature_gostr34102012_512
 #endif
 };
 
@@ -862,8 +864,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
     }
     /* Make sure security callback allows algorithm */
     if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
-                      EVP_MD_size(*pmd) * 4, EVP_MD_type(*pmd),
-                      (void *)sig)) {
+                      EVP_MD_size(*pmd) * 4, EVP_MD_type(*pmd), (void *)sig)) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
@@ -890,13 +891,13 @@ void ssl_set_client_disabled(SSL *s)
     s->s3->tmp.mask_k = 0;
     ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
     ssl_get_client_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver);
-# ifndef OPENSSL_NO_PSK
+#ifndef OPENSSL_NO_PSK
     /* with PSK there must be client callback set */
     if (!s->psk_client_callback) {
         s->s3->tmp.mask_a |= SSL_aPSK;
         s->s3->tmp.mask_k |= SSL_PSK;
     }
-#endif                         /* OPENSSL_NO_PSK */
+#endif                          /* OPENSSL_NO_PSK */
 #ifndef OPENSSL_NO_SRP
     if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
         s->s3->tmp.mask_a |= SSL_aSRP;
@@ -921,10 +922,10 @@ int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
     if (s->s3->tmp.max_ver == 0)
         return 1;
     if (!SSL_IS_DTLS(s) && ((c->min_tls > s->s3->tmp.max_ver)
-            || (c->max_tls < s->s3->tmp.min_ver)))
+                            || (c->max_tls < s->s3->tmp.min_ver)))
         return 1;
     if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3->tmp.max_ver)
-            || DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver)))
+                           || DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver)))
         return 1;
 
     return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
@@ -937,7 +938,8 @@ static int tls_use_ticket(SSL *s)
     return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
 }
 
-static int compare_uint(const void *p1, const void *p2) {
+static int compare_uint(const void *p1, const void *p2)
+{
     unsigned int u1 = *((const unsigned int *)p1);
     unsigned int u2 = *((const unsigned int *)p2);
     if (u1 < u2)
@@ -956,7 +958,8 @@ static int compare_uint(const void *p1, const void *p2) {
  * contain duplicates, could not be successfully parsed, or an internal error
  * occurred.
  */
-static int tls1_check_duplicate_extensions(const PACKET *packet) {
+static int tls1_check_duplicate_extensions(const PACKET *packet)
+{
     PACKET extensions = *packet;
     size_t num_extensions = 0, i = 0;
     unsigned int *extension_types = NULL;
@@ -1010,12 +1013,8 @@ static int tls1_check_duplicate_extensions(const PACKET *packet) {
     return ret;
 }
 
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
-                                          unsigned char *limit, int *al)
+int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
 {
-    int extdatalen = 0;
-    unsigned char *orig = buf;
-    unsigned char *ret = buf;
 #ifndef OPENSSL_NO_EC
     /* See if we support any ECC ciphersuites */
     int using_ecc = 0;
@@ -1030,7 +1029,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
             alg_k = c->algorithm_mkey;
             alg_a = c->algorithm_auth;
             if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
-                 || (alg_a & SSL_aECDSA)) {
+                || (alg_a & SSL_aECDSA)) {
                 using_ecc = 1;
                 break;
             }
@@ -1038,32 +1037,16 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     }
 #endif
 
-    ret += 2;
-
-    if (ret >= limit)
-        return NULL;            /* this really never occurs, but ... */
-
     /* Add RI if renegotiating */
     if (s->renegotiate) {
-        int el;
-
-        if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
-        }
-
-        if ((limit - ret - 4 - el) < 0)
-            return NULL;
-
-        s2n(TLSEXT_TYPE_renegotiate, ret);
-        s2n(el, ret);
-
-        if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished,
+                                   s->s3->previous_client_finished_len)
+                || !WPACKET_close(pkt)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
-
-        ret += el;
     }
     /* Only add RI for SSLv3 */
     if (s->client_version == SSL3_VERSION)
@@ -1071,62 +1054,36 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
 
     if (s->tlsext_hostname != NULL) {
         /* Add TLS extension servername to the Client Hello message */
-        unsigned long size_str;
-        long lenmax;
-
-        /*-
-         * check for enough space.
-         * 4 for the servername type and extension length
-         * 2 for servernamelist length
-         * 1 for the hostname type
-         * 2 for hostname length
-         * + hostname length
-         */
-
-        if ((lenmax = limit - ret - 9) < 0
-            || (size_str =
-                strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
-            return NULL;
-
-        /* extension type and length */
-        s2n(TLSEXT_TYPE_server_name, ret);
-        s2n(size_str + 5, ret);
-
-        /* length of servername list */
-        s2n(size_str + 3, ret);
-
-        /* hostname type, length and hostname */
-        *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name;
-        s2n(size_str, ret);
-        memcpy(ret, s->tlsext_hostname, size_str);
-        ret += size_str;
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
+                   /* Sub-packet for server_name extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                   /* Sub-packet for servername list (always 1 hostname)*/
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
+                || !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
+                                           strlen(s->tlsext_hostname))
+                || !WPACKET_close(pkt)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 #ifndef OPENSSL_NO_SRP
     /* Add SRP username if there is one */
-    if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
-                                     * Client Hello message */
-
-        int login_len = strlen(s->srp_ctx.login);
-        if (login_len > 255 || login_len == 0) {
+    if (s->srp_ctx.login != NULL) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
+                   /* Sub-packet for SRP extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_start_sub_packet_u8(pkt)
+                   /* login must not be zero...internal error if so */
+                || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
+                || !WPACKET_memcpy(pkt, s->srp_ctx.login,
+                                   strlen(s->srp_ctx.login))
+                || !WPACKET_close(pkt)
+                || !WPACKET_close(pkt)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
-
-        /*-
-         * check for enough space.
-         * 4 for the srp type type and extension length
-         * 1 for the srp user identity
-         * + srp user identity length
-         */
-        if ((limit - ret - 5 - login_len) < 0)
-            return NULL;
-
-        /* fill in the extension */
-        s2n(TLSEXT_TYPE_srp, ret);
-        s2n(login_len + 1, ret);
-        (*ret++) = (unsigned char)login_len;
-        memcpy(ret, s->srp_ctx.login, login_len);
-        ret += login_len;
     }
 #endif
 
@@ -1135,63 +1092,54 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         /*
          * Add TLS extension ECPointFormats to the ClientHello message
          */
-        long lenmax;
         const unsigned char *pcurves, *pformats;
-        size_t num_curves, num_formats, curves_list_len;
+        size_t num_curves, num_formats;
         size_t i;
-        unsigned char *etmp;
 
         tls1_get_formatlist(s, &pformats, &num_formats);
 
-        if ((lenmax = limit - ret - 5) < 0)
-            return NULL;
-        if (num_formats > (size_t)lenmax)
-            return NULL;
-        if (num_formats > 255) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
+                   /* Sub-packet for formats extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
+                || !WPACKET_close(pkt)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
 
-        s2n(TLSEXT_TYPE_ec_point_formats, ret);
-        /* The point format list has 1-byte length. */
-        s2n(num_formats + 1, ret);
-        *(ret++) = (unsigned char)num_formats;
-        memcpy(ret, pformats, num_formats);
-        ret += num_formats;
-
         /*
          * Add TLS extension EllipticCurves to the ClientHello message
          */
         pcurves = s->tlsext_ellipticcurvelist;
-        if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
-            return NULL;
-
-        if ((lenmax = limit - ret - 6) < 0)
-            return NULL;
-        if (num_curves > (size_t)lenmax / 2)
-            return NULL;
-        if (num_curves > 65532 / 2) {
+        if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
 
-        s2n(TLSEXT_TYPE_elliptic_curves, ret);
-        etmp = ret + 4;
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_elliptic_curves)
+                   /* Sub-packet for curves extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_start_sub_packet_u16(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
         /* Copy curve ID if supported */
         for (i = 0; i < num_curves; i++, pcurves += 2) {
             if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
-                *etmp++ = pcurves[0];
-                *etmp++ = pcurves[1];
+                if (!WPACKET_put_bytes_u8(pkt, pcurves[0])
+                    || !WPACKET_put_bytes_u8(pkt, pcurves[1])) {
+                        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
+                               ERR_R_INTERNAL_ERROR);
+                        return 0;
+                    }
             }
         }
-
-        curves_list_len = etmp - ret - 4;
-
-        s2n(curves_list_len + 2, ret);
-        s2n(curves_list_len, ret);
-        ret += curves_list_len;
+        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
-#endif                         /* OPENSSL_NO_EC */
+#endif                          /* OPENSSL_NO_EC */
 
     if (tls_use_ticket(s)) {
         int ticklen;
@@ -1201,8 +1149,10 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
                  s->tlsext_session_ticket->data) {
             ticklen = s->tlsext_session_ticket->length;
             s->session->tlsext_tick = OPENSSL_malloc(ticklen);
-            if (s->session->tlsext_tick == NULL)
-                return NULL;
+            if (s->session->tlsext_tick == NULL) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
             memcpy(s->session->tlsext_tick,
                    s->tlsext_session_ticket->data, ticklen);
             s->session->tlsext_ticklen = ticklen;
@@ -1211,17 +1161,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         if (ticklen == 0 && s->tlsext_session_ticket &&
             s->tlsext_session_ticket->data == NULL)
             goto skip_ext;
-        /*
-         * Check for enough room 2 for extension type, 2 for len rest for
-         * ticket
-         */
-        if ((long)(limit - ret - 4 - ticklen) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_session_ticket, ret);
-        s2n(ticklen, ret);
-        if (ticklen) {
-            memcpy(ret, s->session->tlsext_tick, ticklen);
-            ret += ticklen;
+
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
+                || !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick,
+                                           ticklen)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
         }
     }
  skip_ext:
@@ -1229,82 +1174,97 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     if (SSL_CLIENT_USE_SIGALGS(s)) {
         size_t salglen;
         const unsigned char *salg;
-        unsigned char *etmp;
+
         salglen = tls12_get_psigalgs(s, &salg);
-        if ((size_t)(limit - ret) < salglen + 6)
-            return NULL;
-        s2n(TLSEXT_TYPE_signature_algorithms, ret);
-        etmp = ret;
-        /* Skip over lengths for now */
-        ret += 4;
-        salglen = tls12_copy_sigalgs(s, ret, salg, salglen);
-        /* Fill in lengths */
-        s2n(salglen + 2, etmp);
-        s2n(salglen, etmp);
-        ret += salglen;
-    }
 
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
+                   /* Sub-packet for sig-algs extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                   /* Sub-packet for the actual list */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !tls12_copy_sigalgs(s, pkt, salg, salglen)
+                || !WPACKET_close(pkt)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
 #ifndef OPENSSL_NO_OCSP
     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
         int i;
-        long extlen, idlen, itmp;
-        OCSP_RESPID *id;
 
-        idlen = 0;
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
+                   /* Sub-packet for status request extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
+                   /* Sub-packet for the ids */
+                || !WPACKET_start_sub_packet_u16(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
+            unsigned char *idbytes;
+            int idlen;
+            OCSP_RESPID *id;
+
             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-            itmp = i2d_OCSP_RESPID(id, NULL);
-            if (itmp <= 0)
-                return NULL;
-            idlen += itmp + 2;
+            idlen = i2d_OCSP_RESPID(id, NULL);
+            if (idlen <= 0
+                       /* Sub-packet for an individual id */
+                    || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
+                    || i2d_OCSP_RESPID(id, &idbytes) != idlen) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+        }
+        if (!WPACKET_close(pkt)
+                || !WPACKET_start_sub_packet_u16(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
         }
-
         if (s->tlsext_ocsp_exts) {
-            extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
-            if (extlen < 0)
-                return NULL;
-        } else
-            extlen = 0;
+            unsigned char *extbytes;
+            int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
 
-        if ((long)(limit - ret - 7 - extlen - idlen) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_status_request, ret);
-        if (extlen + idlen > 0xFFF0)
-            return NULL;
-        s2n(extlen + idlen + 5, ret);
-        *(ret++) = TLSEXT_STATUSTYPE_ocsp;
-        s2n(idlen, ret);
-        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
-            /* save position of id len */
-            unsigned char *q = ret;
-            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-            /* skip over id len */
-            ret += 2;
-            itmp = i2d_OCSP_RESPID(id, &ret);
-            /* write id len */
-            s2n(itmp, q);
+            if (extlen < 0) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+            if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
+                    || i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
+                       != extlen) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+           }
+        }
+        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
         }
-        s2n(extlen, ret);
-        if (extlen > 0)
-            i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
     }
 #endif
 #ifndef OPENSSL_NO_HEARTBEATS
     if (SSL_IS_DTLS(s)) {
-        /* Add Heartbeat extension */
-        if ((limit - ret - 4 - 1) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_heartbeat, ret);
-        s2n(1, ret);
+        unsigned int mode;
+
         /*-
          * Set mode:
          * 1: peer may send requests
          * 2: peer not allowed to send requests
          */
         if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
-            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+            mode = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
         else
-            *(ret++) = SSL_DTLSEXT_HB_ENABLED;
+            mode = SSL_DTLSEXT_HB_ENABLED;
+
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_heartbeat)
+                   /* Sub-packet for Hearbeat extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_put_bytes_u8(pkt, mode)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 #endif
 
@@ -1314,10 +1274,11 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * The client advertises an empty extension to indicate its support
          * for Next Protocol Negotiation
          */
-        if (limit - ret - 4 < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_next_proto_neg, ret);
-        s2n(0, ret);
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
+                || !WPACKET_put_bytes_u16(pkt, 0)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 #endif
 
@@ -1327,52 +1288,77 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
      * (see longer comment below)
      */
     if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
-        if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
-            return NULL;
-        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
-        s2n(2 + s->alpn_client_proto_list_len, ret);
-        s2n(s->alpn_client_proto_list_len, ret);
-        memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
-        ret += s->alpn_client_proto_list_len;
+        if (!WPACKET_put_bytes_u16(pkt,
+                    TLSEXT_TYPE_application_layer_protocol_negotiation)
+                   /* Sub-packet ALPN extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
+                                           s->alpn_client_proto_list_len)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
         s->s3->alpn_sent = 1;
     }
 #ifndef OPENSSL_NO_SRTP
     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
-        int el;
-
-        /* Returns 0 on success!! */
-        if (ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0)) {
+        STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
+        SRTP_PROTECTION_PROFILE *prof;
+        int i, ct;
+
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
+                   /* Sub-packet for SRTP extension */
+                || !WPACKET_start_sub_packet_u16(pkt)
+                   /* Sub-packet for the protection profile list */
+                || !WPACKET_start_sub_packet_u16(pkt)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
-
-        if ((limit - ret - 4 - el) < 0)
-            return NULL;
-
-        s2n(TLSEXT_TYPE_use_srtp, ret);
-        s2n(el, ret);
-
-        if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
+        ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
+        for (i = 0; i < ct; i++) {
+            prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+            if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+        }
+        if (!WPACKET_close(pkt)
+                   /* Add an empty use_mki value */
+                || !WPACKET_put_bytes_u8(pkt, 0)
+                || !WPACKET_close(pkt)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
-        ret += el;
     }
 #endif
     custom_ext_init(&s->cert->cli_ext);
     /* Add custom TLS Extensions to ClientHello */
-    if (!custom_ext_add(s, 0, &ret, limit, al))
-        return NULL;
-    s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
-    s2n(0, ret);
+    if (!custom_ext_add(s, 0, pkt, al)) {
+        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
 #ifndef OPENSSL_NO_CT
     if (s->ct_validation_callback != NULL) {
-        s2n(TLSEXT_TYPE_signed_certificate_timestamp, ret);
-        s2n(0, ret);
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
+                || !WPACKET_put_bytes_u16(pkt, 0)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 #endif
-    s2n(TLSEXT_TYPE_extended_master_secret, ret);
-    s2n(0, ret);
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
+            || !WPACKET_put_bytes_u16(pkt, 0)) {
+        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
 
     /*
      * Add padding to workaround bugs in F5 terminators. See
@@ -1381,7 +1367,13 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
      * appear last.
      */
     if (s->options & SSL_OP_TLSEXT_PADDING) {
-        int hlen = ret - (unsigned char *)s->init_buf->data;
+        unsigned char *padbytes;
+        size_t hlen;
+
+        if (!WPACKET_get_total_written(pkt, &hlen)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
 
         if (hlen > 0xff && hlen < 0x200) {
             hlen = 0x200 - hlen;
@@ -1390,28 +1382,21 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
             else
                 hlen = 0;
 
-            s2n(TLSEXT_TYPE_padding, ret);
-            s2n(hlen, ret);
-            memset(ret, 0, hlen);
-            ret += hlen;
+            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
+                    || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
+                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+            memset(padbytes, 0, hlen);
         }
     }
 
  done:
-
-    if ((extdatalen = ret - orig - 2) == 0)
-        return orig;
-
-    s2n(extdatalen, orig);
-    return ret;
+    return 1;
 }
 
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
-                                          unsigned char *limit, int *al)
+int ssl_add_serverhello_tlsext(SSL *s, WPACKET *pkt, int *al)
 {
-    int extdatalen = 0;
-    unsigned char *orig = buf;
-    unsigned char *ret = buf;
 #ifndef OPENSSL_NO_NEXTPROTONEG
     int next_proto_neg_seen;
 #endif
@@ -1422,30 +1407,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
     using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
 #endif
 
-    ret += 2;
-    if (ret >= limit)
-        return NULL;            /* this really never occurs, but ... */
-
-    if (s->s3->send_connection_binding) {
-        int el;
-
-        if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
-        }
-
-        if ((limit - ret - 4 - el) < 0)
-            return NULL;
-
-        s2n(TLSEXT_TYPE_renegotiate, ret);
-        s2n(el, ret);
-
-        if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
-        }
+    if (!WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) {
+        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
 
-        ret += el;
+    if (s->s3->send_connection_binding &&
+            !ssl_add_serverhello_renegotiate_ext(s, pkt)) {
+        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
     }
 
     /* Only add RI for SSLv3 */
@@ -1453,12 +1424,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         goto done;
 
     if (!s->hit && s->servername_done == 1
-        && s->session->tlsext_hostname != NULL) {
-        if ((long)(limit - ret - 4) < 0)
-            return NULL;
-
-        s2n(TLSEXT_TYPE_server_name, ret);
-        s2n(0, ret);
+            && s->session->tlsext_hostname != NULL) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
+                || !WPACKET_put_bytes_u16(pkt, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 #ifndef OPENSSL_NO_EC
     if (using_ecc) {
@@ -1467,69 +1438,54 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         /*
          * Add TLS extension ECPointFormats to the ServerHello message
          */
-        long lenmax;
-
         tls1_get_formatlist(s, &plist, &plistlen);
 
-        if ((lenmax = limit - ret - 5) < 0)
-            return NULL;
-        if (plistlen > (size_t)lenmax)
-            return NULL;
-        if (plistlen > 255) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen)
+                || !WPACKET_close(pkt)) {
             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
-
-        s2n(TLSEXT_TYPE_ec_point_formats, ret);
-        s2n(plistlen + 1, ret);
-        *(ret++) = (unsigned char)plistlen;
-        memcpy(ret, plist, plistlen);
-        ret += plistlen;
-
     }
     /*
      * Currently the server should not respond with a SupportedCurves
      * extension
      */
-#endif                         /* OPENSSL_NO_EC */
+#endif                          /* OPENSSL_NO_EC */
 
     if (s->tlsext_ticket_expected && tls_use_ticket(s)) {
-        if ((long)(limit - ret - 4) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_session_ticket, ret);
-        s2n(0, ret);
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
+                || !WPACKET_put_bytes_u16(pkt, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     } else {
-        /* if we don't add the above TLSEXT, we can't add a session ticket later */
+        /*
+         * if we don't add the above TLSEXT, we can't add a session ticket
+         * later
+         */
         s->tlsext_ticket_expected = 0;
     }
 
     if (s->tlsext_status_expected) {
-        if ((long)(limit - ret - 4) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_status_request, ret);
-        s2n(0, ret);
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
+                || !WPACKET_put_bytes_u16(pkt, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
-
 #ifndef OPENSSL_NO_SRTP
     if (SSL_IS_DTLS(s) && s->srtp_profile) {
-        int el;
-
-        /* Returns 0 on success!! */
-        if (ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
-        }
-        if ((limit - ret - 4 - el) < 0)
-            return NULL;
-
-        s2n(TLSEXT_TYPE_use_srtp, ret);
-        s2n(el, ret);
-
-        if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_put_bytes_u16(pkt, 2)
+                || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id)
+                || !WPACKET_put_bytes_u8(pkt, 0)
+                || !WPACKET_close(pkt)) {
             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return NULL;
+            return 0;
         }
-        ret += el;
     }
 #endif
 
@@ -1544,28 +1500,32 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
         };
-        if (limit - ret < 36)
-            return NULL;
-        memcpy(ret, cryptopro_ext, 36);
-        ret += 36;
-
+        if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 #ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension if we've received one */
     if (SSL_IS_DTLS(s) && (s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED)) {
-        if ((limit - ret - 4 - 1) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_heartbeat, ret);
-        s2n(1, ret);
+        unsigned int mode;
         /*-
          * Set mode:
          * 1: peer may send requests
          * 2: peer not allowed to send requests
          */
         if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
-            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+            mode = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
         else
-            *(ret++) = SSL_DTLSEXT_HB_ENABLED;
+            mode = SSL_DTLSEXT_HB_ENABLED;
+
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_heartbeat)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_put_bytes_u8(pkt, mode)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
 
     }
 #endif
@@ -1582,18 +1542,20 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
                                               s->
                                               ctx->next_protos_advertised_cb_arg);
         if (r == SSL_TLSEXT_ERR_OK) {
-            if ((long)(limit - ret - 4 - npalen) < 0)
-                return NULL;
-            s2n(TLSEXT_TYPE_next_proto_neg, ret);
-            s2n(npalen, ret);
-            memcpy(ret, npa, npalen);
-            ret += npalen;
+            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
+                    || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) {
+                SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
             s->s3->next_proto_neg_seen = 1;
         }
     }
 #endif
-    if (!custom_ext_add(s, 1, &ret, limit, al))
-        return NULL;
+    if (!custom_ext_add(s, 1, pkt, al)) {
+        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
     if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) {
         /*
          * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
@@ -1605,36 +1567,41 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
             || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12)
             s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
         else {
-            s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
-            s2n(0, ret);
+            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
+                    || !WPACKET_put_bytes_u16(pkt, 0)) {
+                SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
         }
     }
     if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
-        s2n(TLSEXT_TYPE_extended_master_secret, ret);
-        s2n(0, ret);
+        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
+                || !WPACKET_put_bytes_u16(pkt, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 
     if (s->s3->alpn_selected != NULL) {
-        const unsigned char *selected = s->s3->alpn_selected;
-        unsigned int len = s->s3->alpn_selected_len;
-
-        if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
-        s2n(3 + len, ret);
-        s2n(1 + len, ret);
-        *ret++ = len;
-        memcpy(ret, selected, len);
-        ret += len;
+        if (!WPACKET_put_bytes_u16(pkt,
+                    TLSEXT_TYPE_application_layer_protocol_negotiation)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_start_sub_packet_u16(pkt)
+                || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected,
+                                          s->s3->alpn_selected_len)
+                || !WPACKET_close(pkt)
+                || !WPACKET_close(pkt)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
     }
 
  done:
-
-    if ((extdatalen = ret - orig - 2) == 0)
-        return orig;
-
-    s2n(extdatalen, orig);
-    return ret;
+    if (!WPACKET_close(pkt)) {
+        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    return 1;
 }
 
 /*
@@ -1664,8 +1631,7 @@ static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al)
     } while (PACKET_remaining(&protocol_list) != 0);
 
     if (!PACKET_memdup(&save_protocol_list,
-                       &s->s3->alpn_proposed,
-                       &s->s3->alpn_proposed_len)) {
+                       &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) {
         *al = TLS1_AD_INTERNAL_ERROR;
         return 0;
     }
@@ -1773,7 +1739,7 @@ static void ssl_check_for_safari(SSL *s, const PACKET *pkt)
     s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
                                              ext_len);
 }
-#endif                         /* !OPENSSL_NO_EC */
+#endif                          /* !OPENSSL_NO_EC */
 
 /*
  * Parse ClientHello extensions and stash extension info in various parts of
@@ -1813,7 +1779,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
 #ifndef OPENSSL_NO_EC
     if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
         ssl_check_for_safari(s, pkt);
-# endif /* !OPENSSL_NO_EC */
+#endif                          /* !OPENSSL_NO_EC */
 
     /* Clear any signature algorithms extension received */
     OPENSSL_free(s->s3->tmp.peer_sigalgs);
@@ -1962,8 +1928,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
         else if (type == TLSEXT_TYPE_ec_point_formats) {
             PACKET ec_point_format_list;
 
-            if (!PACKET_as_length_prefixed_1(&extension,
-                                              &ec_point_format_list)
+            if (!PACKET_as_length_prefixed_1(&extension, &ec_point_format_list)
                 || PACKET_remaining(&ec_point_format_list) == 0) {
                 return 0;
             }
@@ -1971,7 +1936,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
             if (!s->hit) {
                 if (!PACKET_memdup(&ec_point_format_list,
                                    &s->session->tlsext_ecpointformatlist,
-                                   &s->session->tlsext_ecpointformatlist_length)) {
+                                   &s->
+                                   session->tlsext_ecpointformatlist_length)) {
                     *al = TLS1_AD_INTERNAL_ERROR;
                     return 0;
                 }
@@ -1980,8 +1946,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
             PACKET elliptic_curve_list;
 
             /* Each NamedCurve is 2 bytes and we must have at least 1. */
-            if (!PACKET_as_length_prefixed_2(&extension,
-                                             &elliptic_curve_list)
+            if (!PACKET_as_length_prefixed_2(&extension, &elliptic_curve_list)
                 || PACKET_remaining(&elliptic_curve_list) == 0
                 || (PACKET_remaining(&elliptic_curve_list) % 2) != 0) {
                 return 0;
@@ -1990,18 +1955,20 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
             if (!s->hit) {
                 if (!PACKET_memdup(&elliptic_curve_list,
                                    &s->session->tlsext_ellipticcurvelist,
-                                   &s->session->tlsext_ellipticcurvelist_length)) {
+                                   &s->
+                                   session->tlsext_ellipticcurvelist_length)) {
                     *al = TLS1_AD_INTERNAL_ERROR;
                     return 0;
                 }
             }
         }
-#endif                         /* OPENSSL_NO_EC */
+#endif                          /* OPENSSL_NO_EC */
         else if (type == TLSEXT_TYPE_session_ticket) {
             if (s->tls_session_ticket_ext_cb &&
                 !s->tls_session_ticket_ext_cb(s, PACKET_data(&extension),
                                               PACKET_remaining(&extension),
-                                              s->tls_session_ticket_ext_cb_arg)) {
+                                              s->tls_session_ticket_ext_cb_arg))
+            {
                 *al = TLS1_AD_INTERNAL_ERROR;
                 return 0;
             }
@@ -2014,7 +1981,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
                 return 0;
             }
 
-            if  (!s->hit) {
+            if (!s->hit) {
                 if (!tls1_save_sigalgs(s, PACKET_data(&supported_sig_algs),
                                        PACKET_remaining(&supported_sig_algs))) {
                     return 0;
@@ -2025,14 +1992,30 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
                               (unsigned int *)&s->tlsext_status_type)) {
                 return 0;
             }
-
 #ifndef OPENSSL_NO_OCSP
             if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
                 const unsigned char *ext_data;
                 PACKET responder_id_list, exts;
-                if (!PACKET_get_length_prefixed_2(&extension, &responder_id_list))
+                if (!PACKET_get_length_prefixed_2
+                    (&extension, &responder_id_list))
                     return 0;
 
+                /*
+                 * We remove any OCSP_RESPIDs from a previous handshake
+                 * to prevent unbounded memory growth - CVE-2016-6304
+                 */
+                sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
+                                        OCSP_RESPID_free);
+                if (PACKET_remaining(&responder_id_list) > 0) {
+                    s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
+                    if (s->tlsext_ocsp_ids == NULL) {
+                        *al = SSL_AD_INTERNAL_ERROR;
+                        return 0;
+                    }
+                } else {
+                    s->tlsext_ocsp_ids = NULL;
+                }
+
                 while (PACKET_remaining(&responder_id_list) > 0) {
                     OCSP_RESPID *id;
                     PACKET responder_id;
@@ -2044,13 +2027,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
                         return 0;
                     }
 
-                    if (s->tlsext_ocsp_ids == NULL
-                        && (s->tlsext_ocsp_ids =
-                            sk_OCSP_RESPID_new_null()) == NULL) {
-                        *al = SSL_AD_INTERNAL_ERROR;
-                        return 0;
-                    }
-
                     id_data = PACKET_data(&responder_id);
                     id = d2i_OCSP_RESPID(NULL, &id_data,
                                          PACKET_remaining(&responder_id));
@@ -2099,7 +2075,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
             unsigned int hbtype;
 
             if (!PACKET_get_1(&extension, &hbtype)
-                    || PACKET_remaining(&extension)) {
+                || PACKET_remaining(&extension)) {
                 *al = SSL_AD_DECODE_ERROR;
                 return 0;
             }
@@ -2177,7 +2153,9 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
     }
 
     if (PACKET_remaining(pkt) != 0) {
-        /* tls1_check_duplicate_extensions should ensure this never happens. */
+        /*
+         * tls1_check_duplicate_extensions should ensure this never happens.
+         */
         *al = SSL_AD_INTERNAL_ERROR;
         return 0;
     }
@@ -2230,7 +2208,7 @@ static char ssl_next_proto_validate(PACKET *pkt)
 
     while (PACKET_remaining(pkt)) {
         if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
-                || PACKET_remaining(&tmp_protocol) == 0)
+            || PACKET_remaining(&tmp_protocol) == 0)
             return 0;
     }
 
@@ -2278,7 +2256,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
         PACKET spkt;
 
         if (!PACKET_get_sub_packet(pkt, &spkt, size)
-                ||  !PACKET_peek_bytes(&spkt, &data, size))
+            || !PACKET_peek_bytes(&spkt, &data, size))
             goto ri_check;
 
         if (s->tlsext_debug_cb)
@@ -2300,7 +2278,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
         else if (type == TLSEXT_TYPE_ec_point_formats) {
             unsigned int ecpointformatlist_length;
             if (!PACKET_get_1(&spkt, &ecpointformatlist_length)
-                    || ecpointformatlist_length != size - 1) {
+                || ecpointformatlist_length != size - 1) {
                 *al = TLS1_AD_DECODE_ERROR;
                 return 0;
             }
@@ -2323,7 +2301,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
 
             }
         }
-#endif                         /* OPENSSL_NO_EC */
+#endif                          /* OPENSSL_NO_EC */
 
         else if (type == TLSEXT_TYPE_session_ticket) {
             if (s->tls_session_ticket_ext_cb &&
@@ -2338,8 +2316,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
                 return 0;
             }
             s->tlsext_ticket_expected = 1;
-        }
-        else if (type == TLSEXT_TYPE_status_request) {
+        } else if (type == TLSEXT_TYPE_status_request) {
             /*
              * MUST be empty and only sent if we've requested a status
              * request message.
@@ -2390,14 +2367,19 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
                 *al = TLS1_AD_DECODE_ERROR;
                 return 0;
             }
-            if (s->
-                ctx->next_proto_select_cb(s, &selected, &selected_len, data,
-                                          size,
-                                          s->ctx->next_proto_select_cb_arg) !=
+            if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data,
+                                             size,
+                                             s->
+                                             ctx->next_proto_select_cb_arg) !=
                 SSL_TLSEXT_ERR_OK) {
                 *al = TLS1_AD_INTERNAL_ERROR;
                 return 0;
             }
+            /*
+             * Could be non-NULL if server has sent multiple NPN extensions in
+             * a single Serverhello
+             */
+            OPENSSL_free(s->next_proto_negotiated);
             s->next_proto_negotiated = OPENSSL_malloc(selected_len);
             if (s->next_proto_negotiated == NULL) {
                 *al = TLS1_AD_INTERNAL_ERROR;
@@ -2423,9 +2405,8 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
              *   uint8 proto[proto_length];
              */
             if (!PACKET_get_net_2(&spkt, &len)
-                    || PACKET_remaining(&spkt) != len
-                    || !PACKET_get_1(&spkt, &len)
-                    || PACKET_remaining(&spkt) != len) {
+                || PACKET_remaining(&spkt) != len || !PACKET_get_1(&spkt, &len)
+                || PACKET_remaining(&spkt) != len) {
                 *al = TLS1_AD_DECODE_ERROR;
                 return 0;
             }
@@ -2473,8 +2454,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
             if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
                 && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
                 s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-        }
-        else if (type == TLSEXT_TYPE_extended_master_secret) {
+        } else if (type == TLSEXT_TYPE_extended_master_secret) {
             s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
             if (!s->hit)
                 s->session->flags |= SSL_SESS_FLAG_EXTMS;
@@ -2495,7 +2475,8 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
     if (!s->hit && tlsext_servername == 1) {
         if (s->tlsext_hostname) {
             if (s->session->tlsext_hostname == NULL) {
-                s->session->tlsext_hostname = OPENSSL_strdup(s->tlsext_hostname);
+                s->session->tlsext_hostname =
+                    OPENSSL_strdup(s->tlsext_hostname);
                 if (!s->session->tlsext_hostname) {
                     *al = SSL_AD_UNRECOGNIZED_NAME;
                     return 0;
@@ -2534,7 +2515,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
             *al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_INCONSISTENT_EXTMS);
             return 0;
-            }
+        }
     }
 
     return 1;
@@ -2593,6 +2574,7 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
         return 1;
     }
 }
+
 /* Initialise digests to default values */
 void ssl_set_default_md(SSL *s)
 {
@@ -2743,7 +2725,7 @@ int ssl_check_serverhello_tlsext(SSL *s)
         }
     }
     ret = SSL_TLSEXT_ERR_OK;
-#endif                         /* OPENSSL_NO_EC */
+#endif                          /* OPENSSL_NO_EC */
 
     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
         ret =
@@ -2864,7 +2846,7 @@ int tls_check_serverhello_tlsext_early(SSL *s, const PACKET *ext,
         unsigned int type, size;
 
         if (!PACKET_get_net_2(&local_ext, &type)
-                || !PACKET_get_net_2(&local_ext, &size)) {
+            || !PACKET_get_net_2(&local_ext, &size)) {
             /* Shouldn't ever happen */
             retv = -1;
             goto end;
@@ -2938,7 +2920,7 @@ int tls_check_serverhello_tlsext_early(SSL *s, const PACKET *ext,
     }
     if (have_ticket == 0)
         retv = 0;
-end:
+ end:
     return retv;
 }
 
@@ -2971,9 +2953,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     HMAC_CTX *hctx = NULL;
     EVP_CIPHER_CTX *ctx;
     SSL_CTX *tctx = s->initial_ctx;
-    /* Need at least keyname + iv + some encrypted data */
-    if (eticklen < 48)
-        return 2;
+
     /* Initialize session ticket encryption and HMAC contexts */
     hctx = HMAC_CTX_new();
     if (hctx == NULL)
@@ -3005,11 +2985,12 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
         if (HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key,
                          sizeof(tctx->tlsext_tick_hmac_key),
                          EVP_sha256(), NULL) <= 0
-                || EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
-                                      tctx->tlsext_tick_aes_key,
-                                      etick + sizeof(tctx->tlsext_tick_key_name)) <= 0) {
+            || EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
+                                  tctx->tlsext_tick_aes_key,
+                                  etick + sizeof(tctx->tlsext_tick_key_name)) <=
+            0) {
             goto err;
-       }
+        }
     }
     /*
      * Attempt to process session ticket, first conduct sanity and integrity
@@ -3019,10 +3000,16 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     if (mlen < 0) {
         goto err;
     }
+    /* Sanity check ticket length: must exceed keyname + IV + HMAC */
+    if (eticklen <=
+        TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx) + mlen) {
+        ret = 2;
+        goto err;
+    }
     eticklen -= mlen;
     /* Check HMAC of encrypted ticket */
     if (HMAC_Update(hctx, etick, eticklen) <= 0
-            || HMAC_Final(hctx, tick_hmac, NULL) <= 0) {
+        || HMAC_Final(hctx, tick_hmac, NULL) <= 0) {
         goto err;
     }
     HMAC_CTX_free(hctx);
@@ -3035,8 +3022,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     p = etick + 16 + EVP_CIPHER_CTX_iv_length(ctx);
     eticklen -= 16 + EVP_CIPHER_CTX_iv_length(ctx);
     sdec = OPENSSL_malloc(eticklen);
-    if (sdec == NULL
-            || EVP_DecryptUpdate(ctx, sdec, &slen, p, eticklen) <= 0) {
+    if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p, eticklen) <= 0) {
         EVP_CIPHER_CTX_free(ctx);
         OPENSSL_free(sdec);
         return -1;
@@ -3074,7 +3060,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
      * For session parse failure, indicate that we need to send a new ticket.
      */
     return 2;
-err:
+ err:
     EVP_CIPHER_CTX_free(ctx);
     HMAC_CTX_free(hctx);
     return ret;
@@ -3128,8 +3114,32 @@ static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen)
     return NID_undef;
 }
 
-int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
-                         const EVP_MD *md)
+int tls12_get_sigandhash(WPACKET *pkt, const EVP_PKEY *pk, const EVP_MD *md)
+{
+    int sig_id, md_id;
+
+    if (md == NULL)
+        return 0;
+    md_id = tls12_find_id(EVP_MD_type(md), tls12_md, OSSL_NELEM(tls12_md));
+    if (md_id == -1)
+        return 0;
+    sig_id = tls12_get_sigid(pk);
+    if (sig_id == -1)
+        return 0;
+    if (!WPACKET_put_bytes_u8(pkt, md_id) || !WPACKET_put_bytes_u8(pkt, sig_id))
+        return 0;
+
+    return 1;
+}
+
+/*
+ * Old version of the tls12_get_sigandhash function used by code that has not
+ * yet been converted to WPACKET yet. It will be deleted once WPACKET conversion
+ * is complete.
+ * TODO - DELETE ME
+ */
+int tls12_get_sigandhash_old(unsigned char *p, const EVP_PKEY *pk,
+                             const EVP_MD *md)
 {
     int sig_id, md_id;
     if (!md)
@@ -3164,9 +3174,11 @@ static const tls12_hash_info tls12_md_info[] = {
     {NID_sha256, 128, SSL_MD_SHA256_IDX, TLSEXT_hash_sha256},
     {NID_sha384, 192, SSL_MD_SHA384_IDX, TLSEXT_hash_sha384},
     {NID_sha512, 256, SSL_MD_SHA512_IDX, TLSEXT_hash_sha512},
-    {NID_id_GostR3411_94,       128, SSL_MD_GOST94_IDX, TLSEXT_hash_gostr3411},
-    {NID_id_GostR3411_2012_256, 128, SSL_MD_GOST12_256_IDX, TLSEXT_hash_gostr34112012_256},
-    {NID_id_GostR3411_2012_512, 256, SSL_MD_GOST12_512_IDX, TLSEXT_hash_gostr34112012_512},
+    {NID_id_GostR3411_94, 128, SSL_MD_GOST94_IDX, TLSEXT_hash_gostr3411},
+    {NID_id_GostR3411_2012_256, 128, SSL_MD_GOST12_256_IDX,
+     TLSEXT_hash_gostr34112012_256},
+    {NID_id_GostR3411_2012_512, 256, SSL_MD_GOST12_512_IDX,
+     TLSEXT_hash_gostr34112012_512},
 };
 
 static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg)
@@ -3175,8 +3187,7 @@ static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg)
     if (hash_alg == 0)
         return NULL;
 
-    for (i=0; i < OSSL_NELEM(tls12_md_info); i++)
-    {
+    for (i = 0; i < OSSL_NELEM(tls12_md_info); i++) {
         if (tls12_md_info[i].tlsext_hash == hash_alg)
             return tls12_md_info + i;
     }
@@ -3210,7 +3221,7 @@ static int tls12_get_pkey_idx(unsigned char sig_alg)
     case TLSEXT_signature_ecdsa:
         return SSL_PKEY_ECC;
 #endif
-# ifndef OPENSSL_NO_GOST
+#ifndef OPENSSL_NO_GOST
     case TLSEXT_signature_gostr34102001:
         return SSL_PKEY_GOST01;
 
@@ -3219,7 +3230,7 @@ static int tls12_get_pkey_idx(unsigned char sig_alg)
 
     case TLSEXT_signature_gostr34102012_512:
         return SSL_PKEY_GOST12_512;
-# endif
+#endif
     }
     return -1;
 }
@@ -3243,8 +3254,7 @@ static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
     }
     if (psignhash_nid) {
         if (sign_nid == NID_undef || hash_nid == NID_undef
-                || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid,
-                                          sign_nid) <= 0)
+            || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid) <= 0)
             *psignhash_nid = NID_undef;
     }
 }
@@ -3310,18 +3320,19 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
         *pmask_a |= SSL_aECDSA;
 }
 
-size_t tls12_copy_sigalgs(SSL *s, unsigned char *out,
-                          const unsigned char *psig, size_t psiglen)
+int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
+                       const unsigned char *psig, size_t psiglen)
 {
-    unsigned char *tmpout = out;
     size_t i;
+
     for (i = 0; i < psiglen; i += 2, psig += 2) {
         if (tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, psig)) {
-            *tmpout++ = psig[0];
-            *tmpout++ = psig[1];
+            if (!WPACKET_put_bytes_u8(pkt, psig[0])
+                    || !WPACKET_put_bytes_u8(pkt, psig[1]))
+                return 0;
         }
     }
-    return tmpout - out;
+    return 1;
 }
 
 /* Given preference and allowed sigalgs set shared sigalgs */
@@ -3470,14 +3481,16 @@ int tls1_process_sigalgs(SSL *s)
         if (pmd[SSL_PKEY_ECC] == NULL)
             pmd[SSL_PKEY_ECC] = EVP_sha1();
 #endif
-# ifndef OPENSSL_NO_GOST
+#ifndef OPENSSL_NO_GOST
         if (pmd[SSL_PKEY_GOST01] == NULL)
             pmd[SSL_PKEY_GOST01] = EVP_get_digestbynid(NID_id_GostR3411_94);
         if (pmd[SSL_PKEY_GOST12_256] == NULL)
-            pmd[SSL_PKEY_GOST12_256] = EVP_get_digestbynid(NID_id_GostR3411_2012_256);
+            pmd[SSL_PKEY_GOST12_256] =
+                EVP_get_digestbynid(NID_id_GostR3411_2012_256);
         if (pmd[SSL_PKEY_GOST12_512] == NULL)
-            pmd[SSL_PKEY_GOST12_512] = EVP_get_digestbynid(NID_id_GostR3411_2012_512);
-# endif
+            pmd[SSL_PKEY_GOST12_512] =
+                EVP_get_digestbynid(NID_id_GostR3411_2012_512);
+#endif
     }
     return 1;
 }
@@ -3598,8 +3611,7 @@ int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
     return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
 }
 
-int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
-                     int client)
+int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
 {
     unsigned char *sigalgs, *sptr;
     int rhash, rsign;
@@ -3945,7 +3957,6 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
     return tls1_check_chain(s, x, pk, chain, -1);
 }
 
-
 #ifndef OPENSSL_NO_DH
 DH *ssl_get_auto_dh(SSL *s)
 {