xref: /freebsd/crypto/openssl/ssl/t1_lib.c (revision 6f9291cea8b06d251243fd47a7234018541832a3)
174664626SKris Kennaway /* ssl/t1_lib.c */
274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
374664626SKris Kennaway  * All rights reserved.
474664626SKris Kennaway  *
574664626SKris Kennaway  * This package is an SSL implementation written
674664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
774664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
874664626SKris Kennaway  *
974664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1074664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1174664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1274664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1374664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1474664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1574664626SKris Kennaway  *
1674664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1774664626SKris Kennaway  * the code are not to be removed.
1874664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
1974664626SKris Kennaway  * as the author of the parts of the library used.
2074664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2174664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2274664626SKris Kennaway  *
2374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2474664626SKris Kennaway  * modification, are permitted provided that the following conditions
2574664626SKris Kennaway  * are met:
2674664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2774664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
2874664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3074664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3174664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3274664626SKris Kennaway  *    must display the following acknowledgement:
3374664626SKris Kennaway  *    "This product includes cryptographic software written by
3474664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3574664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3674664626SKris Kennaway  *    being used are not cryptographic related :-).
3774664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
3874664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
3974664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4074664626SKris Kennaway  *
4174664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4274664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4374664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4474664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4574664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4674664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4774664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4874664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4974664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5074664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5174664626SKris Kennaway  * SUCH DAMAGE.
5274664626SKris Kennaway  *
5374664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5474664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5574664626SKris Kennaway  * copied and put under another distribution licence
5674664626SKris Kennaway  * [including the GNU Public Licence.]
5774664626SKris Kennaway  */
581f13597dSJung-uk Kim /* ====================================================================
591f13597dSJung-uk Kim  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
601f13597dSJung-uk Kim  *
611f13597dSJung-uk Kim  * Redistribution and use in source and binary forms, with or without
621f13597dSJung-uk Kim  * modification, are permitted provided that the following conditions
631f13597dSJung-uk Kim  * are met:
641f13597dSJung-uk Kim  *
651f13597dSJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
661f13597dSJung-uk Kim  *    notice, this list of conditions and the following disclaimer.
671f13597dSJung-uk Kim  *
681f13597dSJung-uk Kim  * 2. Redistributions in binary form must reproduce the above copyright
691f13597dSJung-uk Kim  *    notice, this list of conditions and the following disclaimer in
701f13597dSJung-uk Kim  *    the documentation and/or other materials provided with the
711f13597dSJung-uk Kim  *    distribution.
721f13597dSJung-uk Kim  *
731f13597dSJung-uk Kim  * 3. All advertising materials mentioning features or use of this
741f13597dSJung-uk Kim  *    software must display the following acknowledgment:
751f13597dSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
761f13597dSJung-uk Kim  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
771f13597dSJung-uk Kim  *
781f13597dSJung-uk Kim  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
791f13597dSJung-uk Kim  *    endorse or promote products derived from this software without
801f13597dSJung-uk Kim  *    prior written permission. For written permission, please contact
811f13597dSJung-uk Kim  *    openssl-core@openssl.org.
821f13597dSJung-uk Kim  *
831f13597dSJung-uk Kim  * 5. Products derived from this software may not be called "OpenSSL"
841f13597dSJung-uk Kim  *    nor may "OpenSSL" appear in their names without prior written
851f13597dSJung-uk Kim  *    permission of the OpenSSL Project.
861f13597dSJung-uk Kim  *
871f13597dSJung-uk Kim  * 6. Redistributions of any form whatsoever must retain the following
881f13597dSJung-uk Kim  *    acknowledgment:
891f13597dSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
901f13597dSJung-uk Kim  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
911f13597dSJung-uk Kim  *
921f13597dSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
931f13597dSJung-uk Kim  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
941f13597dSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
951f13597dSJung-uk Kim  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
961f13597dSJung-uk Kim  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
971f13597dSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
981f13597dSJung-uk Kim  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
991f13597dSJung-uk Kim  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1001f13597dSJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1011f13597dSJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1021f13597dSJung-uk Kim  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1031f13597dSJung-uk Kim  * OF THE POSSIBILITY OF SUCH DAMAGE.
1041f13597dSJung-uk Kim  * ====================================================================
1051f13597dSJung-uk Kim  *
1061f13597dSJung-uk Kim  * This product includes cryptographic software written by Eric Young
1071f13597dSJung-uk Kim  * (eay@cryptsoft.com).  This product includes software written by Tim
1081f13597dSJung-uk Kim  * Hudson (tjh@cryptsoft.com).
1091f13597dSJung-uk Kim  *
1101f13597dSJung-uk Kim  */
11174664626SKris Kennaway 
11274664626SKris Kennaway #include <stdio.h>
11374664626SKris Kennaway #include <openssl/objects.h>
114db522d3aSSimon L. B. Nielsen #include <openssl/evp.h>
115db522d3aSSimon L. B. Nielsen #include <openssl/hmac.h>
116db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h>
1171f13597dSJung-uk Kim #include <openssl/rand.h>
11874664626SKris Kennaway #include "ssl_locl.h"
11974664626SKris Kennaway 
1205471f83eSSimon L. B. Nielsen const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT;
12174664626SKris Kennaway 
122db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
123db522d3aSSimon L. B. Nielsen static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
124db522d3aSSimon L. B. Nielsen                               const unsigned char *sess_id, int sesslen,
125db522d3aSSimon L. B. Nielsen                               SSL_SESSION **psess);
126db522d3aSSimon L. B. Nielsen #endif
127db522d3aSSimon L. B. Nielsen 
1283b4e3dcbSSimon L. B. Nielsen SSL3_ENC_METHOD TLSv1_enc_data = {
12974664626SKris Kennaway     tls1_enc,
13074664626SKris Kennaway     tls1_mac,
13174664626SKris Kennaway     tls1_setup_key_block,
13274664626SKris Kennaway     tls1_generate_master_secret,
13374664626SKris Kennaway     tls1_change_cipher_state,
13474664626SKris Kennaway     tls1_final_finish_mac,
13574664626SKris Kennaway     TLS1_FINISH_MAC_LENGTH,
13674664626SKris Kennaway     tls1_cert_verify_mac,
13774664626SKris Kennaway     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
13874664626SKris Kennaway     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
13974664626SKris Kennaway     tls1_alert_code,
1401f13597dSJung-uk Kim     tls1_export_keying_material,
14174664626SKris Kennaway };
14274664626SKris Kennaway 
1433b4e3dcbSSimon L. B. Nielsen long tls1_default_timeout(void)
14474664626SKris Kennaway {
145*6f9291ceSJung-uk Kim     /*
146*6f9291ceSJung-uk Kim      * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for
147*6f9291ceSJung-uk Kim      * http, the cache would over fill
148*6f9291ceSJung-uk Kim      */
14974664626SKris Kennaway     return (60 * 60 * 2);
15074664626SKris Kennaway }
15174664626SKris Kennaway 
15274664626SKris Kennaway int tls1_new(SSL *s)
15374664626SKris Kennaway {
154*6f9291ceSJung-uk Kim     if (!ssl3_new(s))
155*6f9291ceSJung-uk Kim         return (0);
15674664626SKris Kennaway     s->method->ssl_clear(s);
15774664626SKris Kennaway     return (1);
15874664626SKris Kennaway }
15974664626SKris Kennaway 
16074664626SKris Kennaway void tls1_free(SSL *s)
16174664626SKris Kennaway {
1621f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
163*6f9291ceSJung-uk Kim     if (s->tlsext_session_ticket) {
1641f13597dSJung-uk Kim         OPENSSL_free(s->tlsext_session_ticket);
1651f13597dSJung-uk Kim     }
1661f13597dSJung-uk Kim #endif                          /* OPENSSL_NO_TLSEXT */
16774664626SKris Kennaway     ssl3_free(s);
16874664626SKris Kennaway }
16974664626SKris Kennaway 
17074664626SKris Kennaway void tls1_clear(SSL *s)
17174664626SKris Kennaway {
17274664626SKris Kennaway     ssl3_clear(s);
1731f13597dSJung-uk Kim     s->version = s->method->version;
17474664626SKris Kennaway }
17574664626SKris Kennaway 
1761f13597dSJung-uk Kim #ifndef OPENSSL_NO_EC
1771f13597dSJung-uk Kim 
178*6f9291ceSJung-uk Kim static int nid_list[] = {
1791f13597dSJung-uk Kim     NID_sect163k1,              /* sect163k1 (1) */
1801f13597dSJung-uk Kim     NID_sect163r1,              /* sect163r1 (2) */
1811f13597dSJung-uk Kim     NID_sect163r2,              /* sect163r2 (3) */
1821f13597dSJung-uk Kim     NID_sect193r1,              /* sect193r1 (4) */
1831f13597dSJung-uk Kim     NID_sect193r2,              /* sect193r2 (5) */
1841f13597dSJung-uk Kim     NID_sect233k1,              /* sect233k1 (6) */
1851f13597dSJung-uk Kim     NID_sect233r1,              /* sect233r1 (7) */
1861f13597dSJung-uk Kim     NID_sect239k1,              /* sect239k1 (8) */
1871f13597dSJung-uk Kim     NID_sect283k1,              /* sect283k1 (9) */
1881f13597dSJung-uk Kim     NID_sect283r1,              /* sect283r1 (10) */
1891f13597dSJung-uk Kim     NID_sect409k1,              /* sect409k1 (11) */
1901f13597dSJung-uk Kim     NID_sect409r1,              /* sect409r1 (12) */
1911f13597dSJung-uk Kim     NID_sect571k1,              /* sect571k1 (13) */
1921f13597dSJung-uk Kim     NID_sect571r1,              /* sect571r1 (14) */
1931f13597dSJung-uk Kim     NID_secp160k1,              /* secp160k1 (15) */
1941f13597dSJung-uk Kim     NID_secp160r1,              /* secp160r1 (16) */
1951f13597dSJung-uk Kim     NID_secp160r2,              /* secp160r2 (17) */
1961f13597dSJung-uk Kim     NID_secp192k1,              /* secp192k1 (18) */
1971f13597dSJung-uk Kim     NID_X9_62_prime192v1,       /* secp192r1 (19) */
1981f13597dSJung-uk Kim     NID_secp224k1,              /* secp224k1 (20) */
1991f13597dSJung-uk Kim     NID_secp224r1,              /* secp224r1 (21) */
2001f13597dSJung-uk Kim     NID_secp256k1,              /* secp256k1 (22) */
2011f13597dSJung-uk Kim     NID_X9_62_prime256v1,       /* secp256r1 (23) */
2021f13597dSJung-uk Kim     NID_secp384r1,              /* secp384r1 (24) */
2031f13597dSJung-uk Kim     NID_secp521r1               /* secp521r1 (25) */
2041f13597dSJung-uk Kim };
2051f13597dSJung-uk Kim 
206*6f9291ceSJung-uk Kim static int pref_list[] = {
207751d2991SJung-uk Kim # ifndef OPENSSL_NO_EC2M
2081f13597dSJung-uk Kim     NID_sect571r1,              /* sect571r1 (14) */
2091f13597dSJung-uk Kim     NID_sect571k1,              /* sect571k1 (13) */
210751d2991SJung-uk Kim # endif
2111f13597dSJung-uk Kim     NID_secp521r1,              /* secp521r1 (25) */
212751d2991SJung-uk Kim # ifndef OPENSSL_NO_EC2M
2131f13597dSJung-uk Kim     NID_sect409k1,              /* sect409k1 (11) */
2141f13597dSJung-uk Kim     NID_sect409r1,              /* sect409r1 (12) */
215751d2991SJung-uk Kim # endif
2161f13597dSJung-uk Kim     NID_secp384r1,              /* secp384r1 (24) */
217751d2991SJung-uk Kim # ifndef OPENSSL_NO_EC2M
2181f13597dSJung-uk Kim     NID_sect283k1,              /* sect283k1 (9) */
2191f13597dSJung-uk Kim     NID_sect283r1,              /* sect283r1 (10) */
220751d2991SJung-uk Kim # endif
2211f13597dSJung-uk Kim     NID_secp256k1,              /* secp256k1 (22) */
2221f13597dSJung-uk Kim     NID_X9_62_prime256v1,       /* secp256r1 (23) */
223751d2991SJung-uk Kim # ifndef OPENSSL_NO_EC2M
2241f13597dSJung-uk Kim     NID_sect239k1,              /* sect239k1 (8) */
2251f13597dSJung-uk Kim     NID_sect233k1,              /* sect233k1 (6) */
2261f13597dSJung-uk Kim     NID_sect233r1,              /* sect233r1 (7) */
227751d2991SJung-uk Kim # endif
2281f13597dSJung-uk Kim     NID_secp224k1,              /* secp224k1 (20) */
2291f13597dSJung-uk Kim     NID_secp224r1,              /* secp224r1 (21) */
230751d2991SJung-uk Kim # ifndef OPENSSL_NO_EC2M
2311f13597dSJung-uk Kim     NID_sect193r1,              /* sect193r1 (4) */
2321f13597dSJung-uk Kim     NID_sect193r2,              /* sect193r2 (5) */
233751d2991SJung-uk Kim # endif
2341f13597dSJung-uk Kim     NID_secp192k1,              /* secp192k1 (18) */
2351f13597dSJung-uk Kim     NID_X9_62_prime192v1,       /* secp192r1 (19) */
236751d2991SJung-uk Kim # ifndef OPENSSL_NO_EC2M
2371f13597dSJung-uk Kim     NID_sect163k1,              /* sect163k1 (1) */
2381f13597dSJung-uk Kim     NID_sect163r1,              /* sect163r1 (2) */
2391f13597dSJung-uk Kim     NID_sect163r2,              /* sect163r2 (3) */
240751d2991SJung-uk Kim # endif
2411f13597dSJung-uk Kim     NID_secp160k1,              /* secp160k1 (15) */
2421f13597dSJung-uk Kim     NID_secp160r1,              /* secp160r1 (16) */
2431f13597dSJung-uk Kim     NID_secp160r2,              /* secp160r2 (17) */
2441f13597dSJung-uk Kim };
2451f13597dSJung-uk Kim 
2461f13597dSJung-uk Kim int tls1_ec_curve_id2nid(int curve_id)
2471f13597dSJung-uk Kim {
248751d2991SJung-uk Kim     /* ECC curves from RFC 4492 */
2491f13597dSJung-uk Kim     if ((curve_id < 1) || ((unsigned int)curve_id >
2501f13597dSJung-uk Kim                            sizeof(nid_list) / sizeof(nid_list[0])))
2511f13597dSJung-uk Kim         return 0;
2521f13597dSJung-uk Kim     return nid_list[curve_id - 1];
25374664626SKris Kennaway }
254f579bf8eSKris Kennaway 
2551f13597dSJung-uk Kim int tls1_ec_nid2curve_id(int nid)
256f579bf8eSKris Kennaway {
257751d2991SJung-uk Kim     /* ECC curves from RFC 4492 */
258*6f9291ceSJung-uk Kim     switch (nid) {
2591f13597dSJung-uk Kim     case NID_sect163k1:        /* sect163k1 (1) */
2601f13597dSJung-uk Kim         return 1;
2611f13597dSJung-uk Kim     case NID_sect163r1:        /* sect163r1 (2) */
2621f13597dSJung-uk Kim         return 2;
2631f13597dSJung-uk Kim     case NID_sect163r2:        /* sect163r2 (3) */
2641f13597dSJung-uk Kim         return 3;
2651f13597dSJung-uk Kim     case NID_sect193r1:        /* sect193r1 (4) */
2661f13597dSJung-uk Kim         return 4;
2671f13597dSJung-uk Kim     case NID_sect193r2:        /* sect193r2 (5) */
2681f13597dSJung-uk Kim         return 5;
2691f13597dSJung-uk Kim     case NID_sect233k1:        /* sect233k1 (6) */
2701f13597dSJung-uk Kim         return 6;
2711f13597dSJung-uk Kim     case NID_sect233r1:        /* sect233r1 (7) */
2721f13597dSJung-uk Kim         return 7;
2731f13597dSJung-uk Kim     case NID_sect239k1:        /* sect239k1 (8) */
2741f13597dSJung-uk Kim         return 8;
2751f13597dSJung-uk Kim     case NID_sect283k1:        /* sect283k1 (9) */
2761f13597dSJung-uk Kim         return 9;
2771f13597dSJung-uk Kim     case NID_sect283r1:        /* sect283r1 (10) */
2781f13597dSJung-uk Kim         return 10;
2791f13597dSJung-uk Kim     case NID_sect409k1:        /* sect409k1 (11) */
2801f13597dSJung-uk Kim         return 11;
2811f13597dSJung-uk Kim     case NID_sect409r1:        /* sect409r1 (12) */
2821f13597dSJung-uk Kim         return 12;
2831f13597dSJung-uk Kim     case NID_sect571k1:        /* sect571k1 (13) */
2841f13597dSJung-uk Kim         return 13;
2851f13597dSJung-uk Kim     case NID_sect571r1:        /* sect571r1 (14) */
2861f13597dSJung-uk Kim         return 14;
2871f13597dSJung-uk Kim     case NID_secp160k1:        /* secp160k1 (15) */
2881f13597dSJung-uk Kim         return 15;
2891f13597dSJung-uk Kim     case NID_secp160r1:        /* secp160r1 (16) */
2901f13597dSJung-uk Kim         return 16;
2911f13597dSJung-uk Kim     case NID_secp160r2:        /* secp160r2 (17) */
2921f13597dSJung-uk Kim         return 17;
2931f13597dSJung-uk Kim     case NID_secp192k1:        /* secp192k1 (18) */
2941f13597dSJung-uk Kim         return 18;
2951f13597dSJung-uk Kim     case NID_X9_62_prime192v1: /* secp192r1 (19) */
2961f13597dSJung-uk Kim         return 19;
2971f13597dSJung-uk Kim     case NID_secp224k1:        /* secp224k1 (20) */
2981f13597dSJung-uk Kim         return 20;
2991f13597dSJung-uk Kim     case NID_secp224r1:        /* secp224r1 (21) */
3001f13597dSJung-uk Kim         return 21;
3011f13597dSJung-uk Kim     case NID_secp256k1:        /* secp256k1 (22) */
3021f13597dSJung-uk Kim         return 22;
3031f13597dSJung-uk Kim     case NID_X9_62_prime256v1: /* secp256r1 (23) */
3041f13597dSJung-uk Kim         return 23;
3051f13597dSJung-uk Kim     case NID_secp384r1:        /* secp384r1 (24) */
3061f13597dSJung-uk Kim         return 24;
3071f13597dSJung-uk Kim     case NID_secp521r1:        /* secp521r1 (25) */
3081f13597dSJung-uk Kim         return 25;
3091f13597dSJung-uk Kim     default:
3101f13597dSJung-uk Kim         return 0;
311f579bf8eSKris Kennaway     }
3121f13597dSJung-uk Kim }
3131f13597dSJung-uk Kim #endif                          /* OPENSSL_NO_EC */
314db522d3aSSimon L. B. Nielsen 
315db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
3161f13597dSJung-uk Kim 
317*6f9291ceSJung-uk Kim /*
318*6f9291ceSJung-uk Kim  * List of supported signature algorithms and hashes. Should make this
3191f13597dSJung-uk Kim  * customisable at some point, for now include everything we support.
3201f13597dSJung-uk Kim  */
3211f13597dSJung-uk Kim 
3221f13597dSJung-uk Kim # ifdef OPENSSL_NO_RSA
3231f13597dSJung-uk Kim #  define tlsext_sigalg_rsa(md) /* */
3241f13597dSJung-uk Kim # else
3251f13597dSJung-uk Kim #  define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
3261f13597dSJung-uk Kim # endif
3271f13597dSJung-uk Kim 
3281f13597dSJung-uk Kim # ifdef OPENSSL_NO_DSA
3291f13597dSJung-uk Kim #  define tlsext_sigalg_dsa(md) /* */
3301f13597dSJung-uk Kim # else
3311f13597dSJung-uk Kim #  define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
3321f13597dSJung-uk Kim # endif
3331f13597dSJung-uk Kim 
3341f13597dSJung-uk Kim # ifdef OPENSSL_NO_ECDSA
335*6f9291ceSJung-uk Kim #  define tlsext_sigalg_ecdsa(md)
336*6f9291ceSJung-uk Kim                                 /* */
3371f13597dSJung-uk Kim # else
3381f13597dSJung-uk Kim #  define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
3391f13597dSJung-uk Kim # endif
3401f13597dSJung-uk Kim 
3411f13597dSJung-uk Kim # define tlsext_sigalg(md) \
3421f13597dSJung-uk Kim                 tlsext_sigalg_rsa(md) \
3431f13597dSJung-uk Kim                 tlsext_sigalg_dsa(md) \
3441f13597dSJung-uk Kim                 tlsext_sigalg_ecdsa(md)
3451f13597dSJung-uk Kim 
3461f13597dSJung-uk Kim static unsigned char tls12_sigalgs[] = {
3471f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
3481f13597dSJung-uk Kim     tlsext_sigalg(TLSEXT_hash_sha512)
3491f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha384)
3501f13597dSJung-uk Kim # endif
3511f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
3521f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha256)
3531f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha224)
3541f13597dSJung-uk Kim # endif
3551f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
3561f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha1)
3571f13597dSJung-uk Kim # endif
3581f13597dSJung-uk Kim };
3591f13597dSJung-uk Kim 
3601f13597dSJung-uk Kim int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
3611f13597dSJung-uk Kim {
3621f13597dSJung-uk Kim     size_t slen = sizeof(tls12_sigalgs);
3631f13597dSJung-uk Kim     if (p)
3641f13597dSJung-uk Kim         memcpy(p, tls12_sigalgs, slen);
3651f13597dSJung-uk Kim     return (int)slen;
3661f13597dSJung-uk Kim }
3671f13597dSJung-uk Kim 
368*6f9291ceSJung-uk Kim unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
369*6f9291ceSJung-uk Kim                                           unsigned char *limit)
370db522d3aSSimon L. B. Nielsen {
371db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
372a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
373a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
374db522d3aSSimon L. B. Nielsen 
3756a599222SSimon L. B. Nielsen     /* don't add extensions for SSLv3 unless doing secure renegotiation */
376*6f9291ceSJung-uk Kim     if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding)
377a93cbc2bSJung-uk Kim         return orig;
3786a599222SSimon L. B. Nielsen 
379db522d3aSSimon L. B. Nielsen     ret += 2;
380db522d3aSSimon L. B. Nielsen 
381*6f9291ceSJung-uk Kim     if (ret >= limit)
382*6f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
383db522d3aSSimon L. B. Nielsen 
384*6f9291ceSJung-uk Kim     if (s->tlsext_hostname != NULL) {
385db522d3aSSimon L. B. Nielsen         /* Add TLS extension servername to the Client Hello message */
386db522d3aSSimon L. B. Nielsen         unsigned long size_str;
387db522d3aSSimon L. B. Nielsen         long lenmax;
388db522d3aSSimon L. B. Nielsen 
389*6f9291ceSJung-uk Kim         /*-
390*6f9291ceSJung-uk Kim          * check for enough space.
391*6f9291ceSJung-uk Kim          * 4 for the servername type and entension length
392*6f9291ceSJung-uk Kim          * 2 for servernamelist length
393*6f9291ceSJung-uk Kim          * 1 for the hostname type
394*6f9291ceSJung-uk Kim          * 2 for hostname length
395*6f9291ceSJung-uk Kim          * + hostname length
396db522d3aSSimon L. B. Nielsen          */
397db522d3aSSimon L. B. Nielsen 
398db522d3aSSimon L. B. Nielsen         if ((lenmax = limit - ret - 9) < 0
399*6f9291ceSJung-uk Kim             || (size_str =
400*6f9291ceSJung-uk Kim                 strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
401db522d3aSSimon L. B. Nielsen             return NULL;
402db522d3aSSimon L. B. Nielsen 
403db522d3aSSimon L. B. Nielsen         /* extension type and length */
404db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_server_name, ret);
405db522d3aSSimon L. B. Nielsen         s2n(size_str + 5, ret);
406db522d3aSSimon L. B. Nielsen 
407db522d3aSSimon L. B. Nielsen         /* length of servername list */
408db522d3aSSimon L. B. Nielsen         s2n(size_str + 3, ret);
409db522d3aSSimon L. B. Nielsen 
410db522d3aSSimon L. B. Nielsen         /* hostname type, length and hostname */
411db522d3aSSimon L. B. Nielsen         *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name;
412db522d3aSSimon L. B. Nielsen         s2n(size_str, ret);
413db522d3aSSimon L. B. Nielsen         memcpy(ret, s->tlsext_hostname, size_str);
414db522d3aSSimon L. B. Nielsen         ret += size_str;
415db522d3aSSimon L. B. Nielsen     }
416db522d3aSSimon L. B. Nielsen 
4176a599222SSimon L. B. Nielsen     /* Add RI if renegotiating */
418*6f9291ceSJung-uk Kim     if (s->renegotiate) {
4196a599222SSimon L. B. Nielsen         int el;
4206a599222SSimon L. B. Nielsen 
421*6f9291ceSJung-uk Kim         if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
4226a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
4236a599222SSimon L. B. Nielsen             return NULL;
4246a599222SSimon L. B. Nielsen         }
4256a599222SSimon L. B. Nielsen 
426*6f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
427*6f9291ceSJung-uk Kim             return NULL;
4286a599222SSimon L. B. Nielsen 
4296a599222SSimon L. B. Nielsen         s2n(TLSEXT_TYPE_renegotiate, ret);
4306a599222SSimon L. B. Nielsen         s2n(el, ret);
4316a599222SSimon L. B. Nielsen 
432*6f9291ceSJung-uk Kim         if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
4336a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
4346a599222SSimon L. B. Nielsen             return NULL;
4356a599222SSimon L. B. Nielsen         }
4366a599222SSimon L. B. Nielsen 
4376a599222SSimon L. B. Nielsen         ret += el;
4386a599222SSimon L. B. Nielsen     }
4391f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP
4401f13597dSJung-uk Kim     /* Add SRP username if there is one */
441*6f9291ceSJung-uk Kim     if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
442*6f9291ceSJung-uk Kim                                      * Client Hello message */
4431f13597dSJung-uk Kim 
4441f13597dSJung-uk Kim         int login_len = strlen(s->srp_ctx.login);
445*6f9291ceSJung-uk Kim         if (login_len > 255 || login_len == 0) {
4461f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
4471f13597dSJung-uk Kim             return NULL;
4481f13597dSJung-uk Kim         }
4491f13597dSJung-uk Kim 
450*6f9291ceSJung-uk Kim         /*-
451*6f9291ceSJung-uk Kim          * check for enough space.
452*6f9291ceSJung-uk Kim          * 4 for the srp type type and entension length
453*6f9291ceSJung-uk Kim          * 1 for the srp user identity
454*6f9291ceSJung-uk Kim          * + srp user identity length
4551f13597dSJung-uk Kim          */
456*6f9291ceSJung-uk Kim         if ((limit - ret - 5 - login_len) < 0)
457*6f9291ceSJung-uk Kim             return NULL;
4581f13597dSJung-uk Kim 
4591f13597dSJung-uk Kim         /* fill in the extension */
4601f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_srp, ret);
4611f13597dSJung-uk Kim         s2n(login_len + 1, ret);
4621f13597dSJung-uk Kim         (*ret++) = (unsigned char)login_len;
4631f13597dSJung-uk Kim         memcpy(ret, s->srp_ctx.login, login_len);
4641f13597dSJung-uk Kim         ret += login_len;
4651f13597dSJung-uk Kim     }
4661f13597dSJung-uk Kim # endif
4671f13597dSJung-uk Kim 
4681f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
469*6f9291ceSJung-uk Kim     if (s->tlsext_ecpointformatlist != NULL) {
470*6f9291ceSJung-uk Kim         /*
471*6f9291ceSJung-uk Kim          * Add TLS extension ECPointFormats to the ClientHello message
472*6f9291ceSJung-uk Kim          */
4731f13597dSJung-uk Kim         long lenmax;
4741f13597dSJung-uk Kim 
475*6f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 5) < 0)
476*6f9291ceSJung-uk Kim             return NULL;
477*6f9291ceSJung-uk Kim         if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax)
478*6f9291ceSJung-uk Kim             return NULL;
479*6f9291ceSJung-uk Kim         if (s->tlsext_ecpointformatlist_length > 255) {
4801f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
4811f13597dSJung-uk Kim             return NULL;
4821f13597dSJung-uk Kim         }
4831f13597dSJung-uk Kim 
4841f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
4851f13597dSJung-uk Kim         s2n(s->tlsext_ecpointformatlist_length + 1, ret);
4861f13597dSJung-uk Kim         *(ret++) = (unsigned char)s->tlsext_ecpointformatlist_length;
487*6f9291ceSJung-uk Kim         memcpy(ret, s->tlsext_ecpointformatlist,
488*6f9291ceSJung-uk Kim                s->tlsext_ecpointformatlist_length);
4891f13597dSJung-uk Kim         ret += s->tlsext_ecpointformatlist_length;
4901f13597dSJung-uk Kim     }
491*6f9291ceSJung-uk Kim     if (s->tlsext_ellipticcurvelist != NULL) {
492*6f9291ceSJung-uk Kim         /*
493*6f9291ceSJung-uk Kim          * Add TLS extension EllipticCurves to the ClientHello message
494*6f9291ceSJung-uk Kim          */
4951f13597dSJung-uk Kim         long lenmax;
4961f13597dSJung-uk Kim 
497*6f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 6) < 0)
498*6f9291ceSJung-uk Kim             return NULL;
499*6f9291ceSJung-uk Kim         if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax)
500*6f9291ceSJung-uk Kim             return NULL;
501*6f9291ceSJung-uk Kim         if (s->tlsext_ellipticcurvelist_length > 65532) {
5021f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
5031f13597dSJung-uk Kim             return NULL;
5041f13597dSJung-uk Kim         }
5051f13597dSJung-uk Kim 
5061f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_elliptic_curves, ret);
5071f13597dSJung-uk Kim         s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
5081f13597dSJung-uk Kim 
5091f13597dSJung-uk Kim         s2n(s->tlsext_ellipticcurvelist_length, ret);
510*6f9291ceSJung-uk Kim         memcpy(ret, s->tlsext_ellipticcurvelist,
511*6f9291ceSJung-uk Kim                s->tlsext_ellipticcurvelist_length);
5121f13597dSJung-uk Kim         ret += s->tlsext_ellipticcurvelist_length;
5131f13597dSJung-uk Kim     }
5141f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
5156a599222SSimon L. B. Nielsen 
516*6f9291ceSJung-uk Kim     if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
517db522d3aSSimon L. B. Nielsen         int ticklen;
5186a599222SSimon L. B. Nielsen         if (!s->new_session && s->session && s->session->tlsext_tick)
519db522d3aSSimon L. B. Nielsen             ticklen = s->session->tlsext_ticklen;
5201f13597dSJung-uk Kim         else if (s->session && s->tlsext_session_ticket &&
521*6f9291ceSJung-uk Kim                  s->tlsext_session_ticket->data) {
5221f13597dSJung-uk Kim             ticklen = s->tlsext_session_ticket->length;
5231f13597dSJung-uk Kim             s->session->tlsext_tick = OPENSSL_malloc(ticklen);
5241f13597dSJung-uk Kim             if (!s->session->tlsext_tick)
5251f13597dSJung-uk Kim                 return NULL;
5261f13597dSJung-uk Kim             memcpy(s->session->tlsext_tick,
527*6f9291ceSJung-uk Kim                    s->tlsext_session_ticket->data, ticklen);
5281f13597dSJung-uk Kim             s->session->tlsext_ticklen = ticklen;
529*6f9291ceSJung-uk Kim         } else
530db522d3aSSimon L. B. Nielsen             ticklen = 0;
5311f13597dSJung-uk Kim         if (ticklen == 0 && s->tlsext_session_ticket &&
5321f13597dSJung-uk Kim             s->tlsext_session_ticket->data == NULL)
5331f13597dSJung-uk Kim             goto skip_ext;
534*6f9291ceSJung-uk Kim         /*
535*6f9291ceSJung-uk Kim          * Check for enough room 2 for extension type, 2 for len rest for
536*6f9291ceSJung-uk Kim          * ticket
537db522d3aSSimon L. B. Nielsen          */
538*6f9291ceSJung-uk Kim         if ((long)(limit - ret - 4 - ticklen) < 0)
539*6f9291ceSJung-uk Kim             return NULL;
540db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
541db522d3aSSimon L. B. Nielsen         s2n(ticklen, ret);
542*6f9291ceSJung-uk Kim         if (ticklen) {
543db522d3aSSimon L. B. Nielsen             memcpy(ret, s->session->tlsext_tick, ticklen);
544db522d3aSSimon L. B. Nielsen             ret += ticklen;
545db522d3aSSimon L. B. Nielsen         }
546db522d3aSSimon L. B. Nielsen     }
5471f13597dSJung-uk Kim  skip_ext:
5481f13597dSJung-uk Kim 
549*6f9291ceSJung-uk Kim     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
5501f13597dSJung-uk Kim         if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6)
5511f13597dSJung-uk Kim             return NULL;
5521f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_signature_algorithms, ret);
5531f13597dSJung-uk Kim         s2n(sizeof(tls12_sigalgs) + 2, ret);
5541f13597dSJung-uk Kim         s2n(sizeof(tls12_sigalgs), ret);
5551f13597dSJung-uk Kim         memcpy(ret, tls12_sigalgs, sizeof(tls12_sigalgs));
5561f13597dSJung-uk Kim         ret += sizeof(tls12_sigalgs);
5571f13597dSJung-uk Kim     }
5581f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
559*6f9291ceSJung-uk Kim     if (s->s3->client_opaque_prf_input != NULL && s->version != DTLS1_VERSION) {
5601f13597dSJung-uk Kim         size_t col = s->s3->client_opaque_prf_input_len;
5611f13597dSJung-uk Kim 
5621f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - col < 0))
5631f13597dSJung-uk Kim             return NULL;
5641f13597dSJung-uk Kim         if (col > 0xFFFD)       /* can't happen */
5651f13597dSJung-uk Kim             return NULL;
5661f13597dSJung-uk Kim 
5671f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
5681f13597dSJung-uk Kim         s2n(col + 2, ret);
5691f13597dSJung-uk Kim         s2n(col, ret);
5701f13597dSJung-uk Kim         memcpy(ret, s->s3->client_opaque_prf_input, col);
5711f13597dSJung-uk Kim         ret += col;
5721f13597dSJung-uk Kim     }
5731f13597dSJung-uk Kim # endif
574db522d3aSSimon L. B. Nielsen 
5756a599222SSimon L. B. Nielsen     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
576*6f9291ceSJung-uk Kim         s->version != DTLS1_VERSION) {
577db522d3aSSimon L. B. Nielsen         int i;
578db522d3aSSimon L. B. Nielsen         long extlen, idlen, itmp;
579db522d3aSSimon L. B. Nielsen         OCSP_RESPID *id;
580db522d3aSSimon L. B. Nielsen 
581db522d3aSSimon L. B. Nielsen         idlen = 0;
582*6f9291ceSJung-uk Kim         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
583db522d3aSSimon L. B. Nielsen             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
584db522d3aSSimon L. B. Nielsen             itmp = i2d_OCSP_RESPID(id, NULL);
585db522d3aSSimon L. B. Nielsen             if (itmp <= 0)
586db522d3aSSimon L. B. Nielsen                 return NULL;
587db522d3aSSimon L. B. Nielsen             idlen += itmp + 2;
588db522d3aSSimon L. B. Nielsen         }
589db522d3aSSimon L. B. Nielsen 
590*6f9291ceSJung-uk Kim         if (s->tlsext_ocsp_exts) {
591db522d3aSSimon L. B. Nielsen             extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
592db522d3aSSimon L. B. Nielsen             if (extlen < 0)
593db522d3aSSimon L. B. Nielsen                 return NULL;
594*6f9291ceSJung-uk Kim         } else
595db522d3aSSimon L. B. Nielsen             extlen = 0;
596db522d3aSSimon L. B. Nielsen 
597*6f9291ceSJung-uk Kim         if ((long)(limit - ret - 7 - extlen - idlen) < 0)
598*6f9291ceSJung-uk Kim             return NULL;
599db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_status_request, ret);
600db522d3aSSimon L. B. Nielsen         if (extlen + idlen > 0xFFF0)
601db522d3aSSimon L. B. Nielsen             return NULL;
602db522d3aSSimon L. B. Nielsen         s2n(extlen + idlen + 5, ret);
603db522d3aSSimon L. B. Nielsen         *(ret++) = TLSEXT_STATUSTYPE_ocsp;
604db522d3aSSimon L. B. Nielsen         s2n(idlen, ret);
605*6f9291ceSJung-uk Kim         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
606db522d3aSSimon L. B. Nielsen             /* save position of id len */
607db522d3aSSimon L. B. Nielsen             unsigned char *q = ret;
608db522d3aSSimon L. B. Nielsen             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
609db522d3aSSimon L. B. Nielsen             /* skip over id len */
610db522d3aSSimon L. B. Nielsen             ret += 2;
611db522d3aSSimon L. B. Nielsen             itmp = i2d_OCSP_RESPID(id, &ret);
612db522d3aSSimon L. B. Nielsen             /* write id len */
613db522d3aSSimon L. B. Nielsen             s2n(itmp, q);
614db522d3aSSimon L. B. Nielsen         }
615db522d3aSSimon L. B. Nielsen         s2n(extlen, ret);
616db522d3aSSimon L. B. Nielsen         if (extlen > 0)
617db522d3aSSimon L. B. Nielsen             i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
618db522d3aSSimon L. B. Nielsen     }
6191f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
6201f13597dSJung-uk Kim     /* Add Heartbeat extension */
62194ad176cSJung-uk Kim     if ((limit - ret - 4 - 1) < 0)
62294ad176cSJung-uk Kim         return NULL;
6231f13597dSJung-uk Kim     s2n(TLSEXT_TYPE_heartbeat, ret);
6241f13597dSJung-uk Kim     s2n(1, ret);
625*6f9291ceSJung-uk Kim     /*-
626*6f9291ceSJung-uk Kim      * Set mode:
6271f13597dSJung-uk Kim      * 1: peer may send requests
6281f13597dSJung-uk Kim      * 2: peer not allowed to send requests
6291f13597dSJung-uk Kim      */
6301f13597dSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
6311f13597dSJung-uk Kim         *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
6321f13597dSJung-uk Kim     else
6331f13597dSJung-uk Kim         *(ret++) = SSL_TLSEXT_HB_ENABLED;
6341f13597dSJung-uk Kim # endif
6351f13597dSJung-uk Kim 
6361f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
637*6f9291ceSJung-uk Kim     if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
638*6f9291ceSJung-uk Kim         /*
639*6f9291ceSJung-uk Kim          * The client advertises an emtpy extension to indicate its support
640*6f9291ceSJung-uk Kim          * for Next Protocol Negotiation
641*6f9291ceSJung-uk Kim          */
6421f13597dSJung-uk Kim         if (limit - ret - 4 < 0)
6431f13597dSJung-uk Kim             return NULL;
6441f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_next_proto_neg, ret);
6451f13597dSJung-uk Kim         s2n(0, ret);
6461f13597dSJung-uk Kim     }
6471f13597dSJung-uk Kim # endif
6481f13597dSJung-uk Kim 
64909286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
650*6f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
6511f13597dSJung-uk Kim         int el;
6521f13597dSJung-uk Kim 
6531f13597dSJung-uk Kim         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
6541f13597dSJung-uk Kim 
655*6f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
656*6f9291ceSJung-uk Kim             return NULL;
6571f13597dSJung-uk Kim 
6581f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
6591f13597dSJung-uk Kim         s2n(el, ret);
6601f13597dSJung-uk Kim 
661*6f9291ceSJung-uk Kim         if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
6621f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
6631f13597dSJung-uk Kim             return NULL;
6641f13597dSJung-uk Kim         }
6651f13597dSJung-uk Kim         ret += el;
6661f13597dSJung-uk Kim     }
66709286989SJung-uk Kim # endif
668*6f9291ceSJung-uk Kim     /*
669*6f9291ceSJung-uk Kim      * Add padding to workaround bugs in F5 terminators. See
670*6f9291ceSJung-uk Kim      * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
671*6f9291ceSJung-uk Kim      * code works out the length of all existing extensions it MUST always
672*6f9291ceSJung-uk Kim      * appear last.
673560ede85SJung-uk Kim      */
674*6f9291ceSJung-uk Kim     if (s->options & SSL_OP_TLSEXT_PADDING) {
675560ede85SJung-uk Kim         int hlen = ret - (unsigned char *)s->init_buf->data;
676*6f9291ceSJung-uk Kim         /*
677*6f9291ceSJung-uk Kim          * The code in s23_clnt.c to build ClientHello messages includes the
678*6f9291ceSJung-uk Kim          * 5-byte record header in the buffer, while the code in s3_clnt.c
679*6f9291ceSJung-uk Kim          * does not.
68094ad176cSJung-uk Kim          */
681560ede85SJung-uk Kim         if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
682560ede85SJung-uk Kim             hlen -= 5;
683*6f9291ceSJung-uk Kim         if (hlen > 0xff && hlen < 0x200) {
684560ede85SJung-uk Kim             hlen = 0x200 - hlen;
685560ede85SJung-uk Kim             if (hlen >= 4)
686560ede85SJung-uk Kim                 hlen -= 4;
687560ede85SJung-uk Kim             else
688560ede85SJung-uk Kim                 hlen = 0;
689560ede85SJung-uk Kim 
690560ede85SJung-uk Kim             s2n(TLSEXT_TYPE_padding, ret);
691560ede85SJung-uk Kim             s2n(hlen, ret);
692560ede85SJung-uk Kim             memset(ret, 0, hlen);
693560ede85SJung-uk Kim             ret += hlen;
694560ede85SJung-uk Kim         }
695560ede85SJung-uk Kim     }
696560ede85SJung-uk Kim 
697a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
698a93cbc2bSJung-uk Kim         return orig;
699db522d3aSSimon L. B. Nielsen 
700a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
701db522d3aSSimon L. B. Nielsen     return ret;
702db522d3aSSimon L. B. Nielsen }
703db522d3aSSimon L. B. Nielsen 
704*6f9291ceSJung-uk Kim unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
705*6f9291ceSJung-uk Kim                                           unsigned char *limit)
706db522d3aSSimon L. B. Nielsen {
707db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
708a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
709a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
7101f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
7111f13597dSJung-uk Kim     int next_proto_neg_seen;
7121f13597dSJung-uk Kim # endif
713db522d3aSSimon L. B. Nielsen 
714*6f9291ceSJung-uk Kim     /*
715*6f9291ceSJung-uk Kim      * don't add extensions for SSLv3, unless doing secure renegotiation
716*6f9291ceSJung-uk Kim      */
7176a599222SSimon L. B. Nielsen     if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
718a93cbc2bSJung-uk Kim         return orig;
7196a599222SSimon L. B. Nielsen 
720db522d3aSSimon L. B. Nielsen     ret += 2;
721*6f9291ceSJung-uk Kim     if (ret >= limit)
722*6f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
723db522d3aSSimon L. B. Nielsen 
724*6f9291ceSJung-uk Kim     if (!s->hit && s->servername_done == 1
725*6f9291ceSJung-uk Kim         && s->session->tlsext_hostname != NULL) {
726*6f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
727*6f9291ceSJung-uk Kim             return NULL;
728db522d3aSSimon L. B. Nielsen 
729db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_server_name, ret);
730db522d3aSSimon L. B. Nielsen         s2n(0, ret);
731db522d3aSSimon L. B. Nielsen     }
732db522d3aSSimon L. B. Nielsen 
733*6f9291ceSJung-uk Kim     if (s->s3->send_connection_binding) {
7346a599222SSimon L. B. Nielsen         int el;
7356a599222SSimon L. B. Nielsen 
736*6f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
7376a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
7386a599222SSimon L. B. Nielsen             return NULL;
7396a599222SSimon L. B. Nielsen         }
7406a599222SSimon L. B. Nielsen 
741*6f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
742*6f9291ceSJung-uk Kim             return NULL;
7436a599222SSimon L. B. Nielsen 
7446a599222SSimon L. B. Nielsen         s2n(TLSEXT_TYPE_renegotiate, ret);
7456a599222SSimon L. B. Nielsen         s2n(el, ret);
7466a599222SSimon L. B. Nielsen 
747*6f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
7486a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
7496a599222SSimon L. B. Nielsen             return NULL;
7506a599222SSimon L. B. Nielsen         }
7516a599222SSimon L. B. Nielsen 
7526a599222SSimon L. B. Nielsen         ret += el;
7536a599222SSimon L. B. Nielsen     }
7541f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
755*6f9291ceSJung-uk Kim     if (s->tlsext_ecpointformatlist != NULL) {
756*6f9291ceSJung-uk Kim         /*
757*6f9291ceSJung-uk Kim          * Add TLS extension ECPointFormats to the ServerHello message
758*6f9291ceSJung-uk Kim          */
7591f13597dSJung-uk Kim         long lenmax;
7601f13597dSJung-uk Kim 
761*6f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 5) < 0)
762*6f9291ceSJung-uk Kim             return NULL;
763*6f9291ceSJung-uk Kim         if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax)
764*6f9291ceSJung-uk Kim             return NULL;
765*6f9291ceSJung-uk Kim         if (s->tlsext_ecpointformatlist_length > 255) {
7661f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
7671f13597dSJung-uk Kim             return NULL;
7681f13597dSJung-uk Kim         }
7691f13597dSJung-uk Kim 
7701f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
7711f13597dSJung-uk Kim         s2n(s->tlsext_ecpointformatlist_length + 1, ret);
7721f13597dSJung-uk Kim         *(ret++) = (unsigned char)s->tlsext_ecpointformatlist_length;
773*6f9291ceSJung-uk Kim         memcpy(ret, s->tlsext_ecpointformatlist,
774*6f9291ceSJung-uk Kim                s->tlsext_ecpointformatlist_length);
7751f13597dSJung-uk Kim         ret += s->tlsext_ecpointformatlist_length;
7761f13597dSJung-uk Kim 
7771f13597dSJung-uk Kim     }
778*6f9291ceSJung-uk Kim     /*
779*6f9291ceSJung-uk Kim      * Currently the server should not respond with a SupportedCurves
780*6f9291ceSJung-uk Kim      * extension
781*6f9291ceSJung-uk Kim      */
7821f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
7831f13597dSJung-uk Kim 
784*6f9291ceSJung-uk Kim     if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
785*6f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
786*6f9291ceSJung-uk Kim             return NULL;
787db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
788db522d3aSSimon L. B. Nielsen         s2n(0, ret);
789db522d3aSSimon L. B. Nielsen     }
790db522d3aSSimon L. B. Nielsen 
791*6f9291ceSJung-uk Kim     if (s->tlsext_status_expected) {
792*6f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
793*6f9291ceSJung-uk Kim             return NULL;
794db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_status_request, ret);
795db522d3aSSimon L. B. Nielsen         s2n(0, ret);
796db522d3aSSimon L. B. Nielsen     }
7971f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
798*6f9291ceSJung-uk Kim     if (s->s3->server_opaque_prf_input != NULL && s->version != DTLS1_VERSION) {
7991f13597dSJung-uk Kim         size_t sol = s->s3->server_opaque_prf_input_len;
8001f13597dSJung-uk Kim 
8011f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - sol) < 0)
8021f13597dSJung-uk Kim             return NULL;
8031f13597dSJung-uk Kim         if (sol > 0xFFFD)       /* can't happen */
8041f13597dSJung-uk Kim             return NULL;
8051f13597dSJung-uk Kim 
8061f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
8071f13597dSJung-uk Kim         s2n(sol + 2, ret);
8081f13597dSJung-uk Kim         s2n(sol, ret);
8091f13597dSJung-uk Kim         memcpy(ret, s->s3->server_opaque_prf_input, sol);
8101f13597dSJung-uk Kim         ret += sol;
8111f13597dSJung-uk Kim     }
8121f13597dSJung-uk Kim # endif
8131f13597dSJung-uk Kim 
81409286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
815*6f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && s->srtp_profile) {
8161f13597dSJung-uk Kim         int el;
8171f13597dSJung-uk Kim 
8181f13597dSJung-uk Kim         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
8191f13597dSJung-uk Kim 
820*6f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
821*6f9291ceSJung-uk Kim             return NULL;
8221f13597dSJung-uk Kim 
8231f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
8241f13597dSJung-uk Kim         s2n(el, ret);
8251f13597dSJung-uk Kim 
826*6f9291ceSJung-uk Kim         if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
8271f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
8281f13597dSJung-uk Kim             return NULL;
8291f13597dSJung-uk Kim         }
8301f13597dSJung-uk Kim         ret += el;
8311f13597dSJung-uk Kim     }
83209286989SJung-uk Kim # endif
8331f13597dSJung-uk Kim 
834*6f9291ceSJung-uk Kim     if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
835*6f9291ceSJung-uk Kim          || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
836*6f9291ceSJung-uk Kim         && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
837*6f9291ceSJung-uk Kim         const unsigned char cryptopro_ext[36] = {
8381f13597dSJung-uk Kim             0xfd, 0xe8,         /* 65000 */
8391f13597dSJung-uk Kim             0x00, 0x20,         /* 32 bytes length */
8401f13597dSJung-uk Kim             0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
8411f13597dSJung-uk Kim             0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
8421f13597dSJung-uk Kim             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
843*6f9291ceSJung-uk Kim             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
844*6f9291ceSJung-uk Kim         };
845*6f9291ceSJung-uk Kim         if (limit - ret < 36)
846*6f9291ceSJung-uk Kim             return NULL;
8471f13597dSJung-uk Kim         memcpy(ret, cryptopro_ext, 36);
8481f13597dSJung-uk Kim         ret += 36;
8491f13597dSJung-uk Kim 
8501f13597dSJung-uk Kim     }
8511f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
8521f13597dSJung-uk Kim     /* Add Heartbeat extension if we've received one */
853*6f9291ceSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
85494ad176cSJung-uk Kim         if ((limit - ret - 4 - 1) < 0)
85594ad176cSJung-uk Kim             return NULL;
8561f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_heartbeat, ret);
8571f13597dSJung-uk Kim         s2n(1, ret);
858*6f9291ceSJung-uk Kim         /*-
859*6f9291ceSJung-uk Kim          * Set mode:
8601f13597dSJung-uk Kim          * 1: peer may send requests
8611f13597dSJung-uk Kim          * 2: peer not allowed to send requests
8621f13597dSJung-uk Kim          */
8631f13597dSJung-uk Kim         if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
8641f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
8651f13597dSJung-uk Kim         else
8661f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_ENABLED;
8671f13597dSJung-uk Kim 
8681f13597dSJung-uk Kim     }
8691f13597dSJung-uk Kim # endif
8701f13597dSJung-uk Kim 
8711f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
8721f13597dSJung-uk Kim     next_proto_neg_seen = s->s3->next_proto_neg_seen;
8731f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
874*6f9291ceSJung-uk Kim     if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
8751f13597dSJung-uk Kim         const unsigned char *npa;
8761f13597dSJung-uk Kim         unsigned int npalen;
8771f13597dSJung-uk Kim         int r;
8781f13597dSJung-uk Kim 
879*6f9291ceSJung-uk Kim         r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
880*6f9291ceSJung-uk Kim                                               s->
881*6f9291ceSJung-uk Kim                                               ctx->next_protos_advertised_cb_arg);
882*6f9291ceSJung-uk Kim         if (r == SSL_TLSEXT_ERR_OK) {
883*6f9291ceSJung-uk Kim             if ((long)(limit - ret - 4 - npalen) < 0)
884*6f9291ceSJung-uk Kim                 return NULL;
8851f13597dSJung-uk Kim             s2n(TLSEXT_TYPE_next_proto_neg, ret);
8861f13597dSJung-uk Kim             s2n(npalen, ret);
8871f13597dSJung-uk Kim             memcpy(ret, npa, npalen);
8881f13597dSJung-uk Kim             ret += npalen;
8891f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
8901f13597dSJung-uk Kim         }
8911f13597dSJung-uk Kim     }
8921f13597dSJung-uk Kim # endif
8931f13597dSJung-uk Kim 
894a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
895a93cbc2bSJung-uk Kim         return orig;
896db522d3aSSimon L. B. Nielsen 
897a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
898db522d3aSSimon L. B. Nielsen     return ret;
899db522d3aSSimon L. B. Nielsen }
900db522d3aSSimon L. B. Nielsen 
901de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
902*6f9291ceSJung-uk Kim /*-
903*6f9291ceSJung-uk Kim  * ssl_check_for_safari attempts to fingerprint Safari using OS X
904de78d5d8SJung-uk Kim  * SecureTransport using the TLS extension block in |d|, of length |n|.
905de78d5d8SJung-uk Kim  * Safari, since 10.6, sends exactly these extensions, in this order:
906de78d5d8SJung-uk Kim  *   SNI,
907de78d5d8SJung-uk Kim  *   elliptic_curves
908de78d5d8SJung-uk Kim  *   ec_point_formats
909de78d5d8SJung-uk Kim  *
910de78d5d8SJung-uk Kim  * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
911de78d5d8SJung-uk Kim  * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
912de78d5d8SJung-uk Kim  * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
913de78d5d8SJung-uk Kim  * 10.8..10.8.3 (which don't work).
914de78d5d8SJung-uk Kim  */
915*6f9291ceSJung-uk Kim static void ssl_check_for_safari(SSL *s, const unsigned char *data,
916*6f9291ceSJung-uk Kim                                  const unsigned char *d, int n)
917*6f9291ceSJung-uk Kim {
918de78d5d8SJung-uk Kim     unsigned short type, size;
919de78d5d8SJung-uk Kim     static const unsigned char kSafariExtensionsBlock[] = {
920de78d5d8SJung-uk Kim         0x00, 0x0a,             /* elliptic_curves extension */
921de78d5d8SJung-uk Kim         0x00, 0x08,             /* 8 bytes */
922de78d5d8SJung-uk Kim         0x00, 0x06,             /* 6 bytes of curve ids */
923de78d5d8SJung-uk Kim         0x00, 0x17,             /* P-256 */
924de78d5d8SJung-uk Kim         0x00, 0x18,             /* P-384 */
925de78d5d8SJung-uk Kim         0x00, 0x19,             /* P-521 */
926de78d5d8SJung-uk Kim 
927de78d5d8SJung-uk Kim         0x00, 0x0b,             /* ec_point_formats */
928de78d5d8SJung-uk Kim         0x00, 0x02,             /* 2 bytes */
929de78d5d8SJung-uk Kim         0x01,                   /* 1 point format */
930de78d5d8SJung-uk Kim         0x00,                   /* uncompressed */
931de78d5d8SJung-uk Kim     };
932de78d5d8SJung-uk Kim 
933de78d5d8SJung-uk Kim     /* The following is only present in TLS 1.2 */
934de78d5d8SJung-uk Kim     static const unsigned char kSafariTLS12ExtensionsBlock[] = {
935de78d5d8SJung-uk Kim         0x00, 0x0d,             /* signature_algorithms */
936de78d5d8SJung-uk Kim         0x00, 0x0c,             /* 12 bytes */
937de78d5d8SJung-uk Kim         0x00, 0x0a,             /* 10 bytes */
938de78d5d8SJung-uk Kim         0x05, 0x01,             /* SHA-384/RSA */
939de78d5d8SJung-uk Kim         0x04, 0x01,             /* SHA-256/RSA */
940de78d5d8SJung-uk Kim         0x02, 0x01,             /* SHA-1/RSA */
941de78d5d8SJung-uk Kim         0x04, 0x03,             /* SHA-256/ECDSA */
942de78d5d8SJung-uk Kim         0x02, 0x03,             /* SHA-1/ECDSA */
943de78d5d8SJung-uk Kim     };
944de78d5d8SJung-uk Kim 
945de78d5d8SJung-uk Kim     if (data >= (d + n - 2))
946de78d5d8SJung-uk Kim         return;
947de78d5d8SJung-uk Kim     data += 2;
948de78d5d8SJung-uk Kim 
949de78d5d8SJung-uk Kim     if (data > (d + n - 4))
950de78d5d8SJung-uk Kim         return;
951de78d5d8SJung-uk Kim     n2s(data, type);
952de78d5d8SJung-uk Kim     n2s(data, size);
953de78d5d8SJung-uk Kim 
954de78d5d8SJung-uk Kim     if (type != TLSEXT_TYPE_server_name)
955de78d5d8SJung-uk Kim         return;
956de78d5d8SJung-uk Kim 
957de78d5d8SJung-uk Kim     if (data + size > d + n)
958de78d5d8SJung-uk Kim         return;
959de78d5d8SJung-uk Kim     data += size;
960de78d5d8SJung-uk Kim 
961*6f9291ceSJung-uk Kim     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
962de78d5d8SJung-uk Kim         const size_t len1 = sizeof(kSafariExtensionsBlock);
963de78d5d8SJung-uk Kim         const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
964de78d5d8SJung-uk Kim 
965de78d5d8SJung-uk Kim         if (data + len1 + len2 != d + n)
966de78d5d8SJung-uk Kim             return;
967de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
968de78d5d8SJung-uk Kim             return;
969de78d5d8SJung-uk Kim         if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
970de78d5d8SJung-uk Kim             return;
971*6f9291ceSJung-uk Kim     } else {
972de78d5d8SJung-uk Kim         const size_t len = sizeof(kSafariExtensionsBlock);
973de78d5d8SJung-uk Kim 
974de78d5d8SJung-uk Kim         if (data + len != d + n)
975de78d5d8SJung-uk Kim             return;
976de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len) != 0)
977de78d5d8SJung-uk Kim             return;
978de78d5d8SJung-uk Kim     }
979de78d5d8SJung-uk Kim 
980de78d5d8SJung-uk Kim     s->s3->is_probably_safari = 1;
981de78d5d8SJung-uk Kim }
982de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
983de78d5d8SJung-uk Kim 
984*6f9291ceSJung-uk Kim int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
985*6f9291ceSJung-uk Kim                                  int n, int *al)
986db522d3aSSimon L. B. Nielsen {
987db522d3aSSimon L. B. Nielsen     unsigned short type;
988db522d3aSSimon L. B. Nielsen     unsigned short size;
989db522d3aSSimon L. B. Nielsen     unsigned short len;
990db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
9916a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
9921f13597dSJung-uk Kim     int sigalg_seen = 0;
9936a599222SSimon L. B. Nielsen 
994db522d3aSSimon L. B. Nielsen     s->servername_done = 0;
995db522d3aSSimon L. B. Nielsen     s->tlsext_status_type = -1;
9961f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
9971f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
9981f13597dSJung-uk Kim # endif
9991f13597dSJung-uk Kim 
10001f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
10011f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
10021f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
10031f13597dSJung-uk Kim # endif
1004db522d3aSSimon L. B. Nielsen 
1005de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
1006de78d5d8SJung-uk Kim     if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
1007de78d5d8SJung-uk Kim         ssl_check_for_safari(s, data, d, n);
1008de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
1009de78d5d8SJung-uk Kim 
1010751d2991SJung-uk Kim # ifndef OPENSSL_NO_SRP
1011*6f9291ceSJung-uk Kim     if (s->srp_ctx.login != NULL) {
1012751d2991SJung-uk Kim         OPENSSL_free(s->srp_ctx.login);
1013751d2991SJung-uk Kim         s->srp_ctx.login = NULL;
1014751d2991SJung-uk Kim     }
1015751d2991SJung-uk Kim # endif
1016751d2991SJung-uk Kim 
1017751d2991SJung-uk Kim     s->srtp_profile = NULL;
1018751d2991SJung-uk Kim 
1019db522d3aSSimon L. B. Nielsen     if (data >= (d + n - 2))
10206a599222SSimon L. B. Nielsen         goto ri_check;
1021db522d3aSSimon L. B. Nielsen     n2s(data, len);
1022db522d3aSSimon L. B. Nielsen 
1023db522d3aSSimon L. B. Nielsen     if (data > (d + n - len))
10246a599222SSimon L. B. Nielsen         goto ri_check;
1025db522d3aSSimon L. B. Nielsen 
1026*6f9291ceSJung-uk Kim     while (data <= (d + n - 4)) {
1027db522d3aSSimon L. B. Nielsen         n2s(data, type);
1028db522d3aSSimon L. B. Nielsen         n2s(data, size);
1029db522d3aSSimon L. B. Nielsen 
1030db522d3aSSimon L. B. Nielsen         if (data + size > (d + n))
10316a599222SSimon L. B. Nielsen             goto ri_check;
10321f13597dSJung-uk Kim # if 0
10331f13597dSJung-uk Kim         fprintf(stderr, "Received extension type %d size %d\n", type, size);
10341f13597dSJung-uk Kim # endif
1035db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
1036*6f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
1037*6f9291ceSJung-uk Kim /*-
1038*6f9291ceSJung-uk Kim  * The servername extension is treated as follows:
1039*6f9291ceSJung-uk Kim  *
1040*6f9291ceSJung-uk Kim  * - Only the hostname type is supported with a maximum length of 255.
1041*6f9291ceSJung-uk Kim  * - The servername is rejected if too long or if it contains zeros,
1042*6f9291ceSJung-uk Kim  *   in which case an fatal alert is generated.
1043*6f9291ceSJung-uk Kim  * - The servername field is maintained together with the session cache.
1044*6f9291ceSJung-uk Kim  * - When a session is resumed, the servername call back invoked in order
1045*6f9291ceSJung-uk Kim  *   to allow the application to position itself to the right context.
1046*6f9291ceSJung-uk Kim  * - The servername is acknowledged if it is new for a session or when
1047*6f9291ceSJung-uk Kim  *   it is identical to a previously used for the same session.
1048*6f9291ceSJung-uk Kim  *   Applications can control the behaviour.  They can at any time
1049*6f9291ceSJung-uk Kim  *   set a 'desirable' servername for a new SSL object. This can be the
1050*6f9291ceSJung-uk Kim  *   case for example with HTTPS when a Host: header field is received and
1051*6f9291ceSJung-uk Kim  *   a renegotiation is requested. In this case, a possible servername
1052*6f9291ceSJung-uk Kim  *   presented in the new client hello is only acknowledged if it matches
1053*6f9291ceSJung-uk Kim  *   the value of the Host: field.
1054*6f9291ceSJung-uk Kim  * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
1055*6f9291ceSJung-uk Kim  *   if they provide for changing an explicit servername context for the
1056*6f9291ceSJung-uk Kim  *   session, i.e. when the session has been established with a servername
1057*6f9291ceSJung-uk Kim  *   extension.
1058*6f9291ceSJung-uk Kim  * - On session reconnect, the servername extension may be absent.
1059*6f9291ceSJung-uk Kim  *
1060db522d3aSSimon L. B. Nielsen  */
1061db522d3aSSimon L. B. Nielsen 
1062*6f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
1063db522d3aSSimon L. B. Nielsen             unsigned char *sdata;
1064db522d3aSSimon L. B. Nielsen             int servname_type;
1065db522d3aSSimon L. B. Nielsen             int dsize;
1066db522d3aSSimon L. B. Nielsen 
1067*6f9291ceSJung-uk Kim             if (size < 2) {
1068db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
1069db522d3aSSimon L. B. Nielsen                 return 0;
1070db522d3aSSimon L. B. Nielsen             }
1071db522d3aSSimon L. B. Nielsen             n2s(data, dsize);
1072db522d3aSSimon L. B. Nielsen             size -= 2;
1073*6f9291ceSJung-uk Kim             if (dsize > size) {
1074db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
1075db522d3aSSimon L. B. Nielsen                 return 0;
1076db522d3aSSimon L. B. Nielsen             }
1077db522d3aSSimon L. B. Nielsen 
1078db522d3aSSimon L. B. Nielsen             sdata = data;
1079*6f9291ceSJung-uk Kim             while (dsize > 3) {
1080db522d3aSSimon L. B. Nielsen                 servname_type = *(sdata++);
1081db522d3aSSimon L. B. Nielsen                 n2s(sdata, len);
1082db522d3aSSimon L. B. Nielsen                 dsize -= 3;
1083db522d3aSSimon L. B. Nielsen 
1084*6f9291ceSJung-uk Kim                 if (len > dsize) {
1085db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_DECODE_ERROR;
1086db522d3aSSimon L. B. Nielsen                     return 0;
1087db522d3aSSimon L. B. Nielsen                 }
1088db522d3aSSimon L. B. Nielsen                 if (s->servername_done == 0)
1089*6f9291ceSJung-uk Kim                     switch (servname_type) {
1090db522d3aSSimon L. B. Nielsen                     case TLSEXT_NAMETYPE_host_name:
1091*6f9291ceSJung-uk Kim                         if (!s->hit) {
1092*6f9291ceSJung-uk Kim                             if (s->session->tlsext_hostname) {
1093a3ddd25aSSimon L. B. Nielsen                                 *al = SSL_AD_DECODE_ERROR;
1094a3ddd25aSSimon L. B. Nielsen                                 return 0;
1095a3ddd25aSSimon L. B. Nielsen                             }
1096*6f9291ceSJung-uk Kim                             if (len > TLSEXT_MAXLEN_host_name) {
1097db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
1098db522d3aSSimon L. B. Nielsen                                 return 0;
1099db522d3aSSimon L. B. Nielsen                             }
1100*6f9291ceSJung-uk Kim                             if ((s->session->tlsext_hostname =
1101*6f9291ceSJung-uk Kim                                  OPENSSL_malloc(len + 1)) == NULL) {
1102a3ddd25aSSimon L. B. Nielsen                                 *al = TLS1_AD_INTERNAL_ERROR;
1103a3ddd25aSSimon L. B. Nielsen                                 return 0;
1104a3ddd25aSSimon L. B. Nielsen                             }
1105db522d3aSSimon L. B. Nielsen                             memcpy(s->session->tlsext_hostname, sdata, len);
1106db522d3aSSimon L. B. Nielsen                             s->session->tlsext_hostname[len] = '\0';
1107db522d3aSSimon L. B. Nielsen                             if (strlen(s->session->tlsext_hostname) != len) {
1108db522d3aSSimon L. B. Nielsen                                 OPENSSL_free(s->session->tlsext_hostname);
1109db522d3aSSimon L. B. Nielsen                                 s->session->tlsext_hostname = NULL;
1110db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
1111db522d3aSSimon L. B. Nielsen                                 return 0;
1112db522d3aSSimon L. B. Nielsen                             }
1113db522d3aSSimon L. B. Nielsen                             s->servername_done = 1;
1114db522d3aSSimon L. B. Nielsen 
1115*6f9291ceSJung-uk Kim                         } else
1116a3ddd25aSSimon L. B. Nielsen                             s->servername_done = s->session->tlsext_hostname
1117a3ddd25aSSimon L. B. Nielsen                                 && strlen(s->session->tlsext_hostname) == len
1118*6f9291ceSJung-uk Kim                                 && strncmp(s->session->tlsext_hostname,
1119*6f9291ceSJung-uk Kim                                            (char *)sdata, len) == 0;
1120db522d3aSSimon L. B. Nielsen 
1121db522d3aSSimon L. B. Nielsen                         break;
1122db522d3aSSimon L. B. Nielsen 
1123db522d3aSSimon L. B. Nielsen                     default:
1124db522d3aSSimon L. B. Nielsen                         break;
1125db522d3aSSimon L. B. Nielsen                     }
1126db522d3aSSimon L. B. Nielsen 
1127db522d3aSSimon L. B. Nielsen                 dsize -= len;
1128db522d3aSSimon L. B. Nielsen             }
1129*6f9291ceSJung-uk Kim             if (dsize != 0) {
1130db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
1131db522d3aSSimon L. B. Nielsen                 return 0;
1132db522d3aSSimon L. B. Nielsen             }
1133db522d3aSSimon L. B. Nielsen 
1134db522d3aSSimon L. B. Nielsen         }
11351f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP
1136*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_srp) {
1137*6f9291ceSJung-uk Kim             if (size <= 0 || ((len = data[0])) != (size - 1)) {
11381f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
11391f13597dSJung-uk Kim                 return 0;
11401f13597dSJung-uk Kim             }
1141*6f9291ceSJung-uk Kim             if (s->srp_ctx.login != NULL) {
11421f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
11431f13597dSJung-uk Kim                 return 0;
11441f13597dSJung-uk Kim             }
11451f13597dSJung-uk Kim             if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
11461f13597dSJung-uk Kim                 return -1;
11471f13597dSJung-uk Kim             memcpy(s->srp_ctx.login, &data[1], len);
11481f13597dSJung-uk Kim             s->srp_ctx.login[len] = '\0';
11491f13597dSJung-uk Kim 
1150*6f9291ceSJung-uk Kim             if (strlen(s->srp_ctx.login) != len) {
11511f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
11521f13597dSJung-uk Kim                 return 0;
11531f13597dSJung-uk Kim             }
11541f13597dSJung-uk Kim         }
11551f13597dSJung-uk Kim # endif
11561f13597dSJung-uk Kim 
11571f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
1158*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
11591f13597dSJung-uk Kim             unsigned char *sdata = data;
11601f13597dSJung-uk Kim             int ecpointformatlist_length = *(sdata++);
11611f13597dSJung-uk Kim 
1162*6f9291ceSJung-uk Kim             if (ecpointformatlist_length != size - 1) {
11631f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
11641f13597dSJung-uk Kim                 return 0;
11651f13597dSJung-uk Kim             }
1166*6f9291ceSJung-uk Kim             if (!s->hit) {
1167*6f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist) {
11681f13597dSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
11691f13597dSJung-uk Kim                     s->session->tlsext_ecpointformatlist = NULL;
11701f13597dSJung-uk Kim                 }
11711f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
1172*6f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
1173*6f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
11741f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
11751f13597dSJung-uk Kim                     return 0;
11761f13597dSJung-uk Kim                 }
1177*6f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
1178*6f9291ceSJung-uk Kim                     ecpointformatlist_length;
1179*6f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
1180*6f9291ceSJung-uk Kim                        ecpointformatlist_length);
11811f13597dSJung-uk Kim             }
11821f13597dSJung-uk Kim #  if 0
1183*6f9291ceSJung-uk Kim             fprintf(stderr,
1184*6f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ",
1185*6f9291ceSJung-uk Kim                     s->session->tlsext_ecpointformatlist_length);
11861f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
11871f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
11881f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
11891f13597dSJung-uk Kim             fprintf(stderr, "\n");
11901f13597dSJung-uk Kim #  endif
1191*6f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_elliptic_curves) {
11921f13597dSJung-uk Kim             unsigned char *sdata = data;
11931f13597dSJung-uk Kim             int ellipticcurvelist_length = (*(sdata++) << 8);
11941f13597dSJung-uk Kim             ellipticcurvelist_length += (*(sdata++));
11951f13597dSJung-uk Kim 
119609286989SJung-uk Kim             if (ellipticcurvelist_length != size - 2 ||
1197751d2991SJung-uk Kim                 ellipticcurvelist_length < 1 ||
1198751d2991SJung-uk Kim                 /* Each NamedCurve is 2 bytes. */
1199*6f9291ceSJung-uk Kim                 ellipticcurvelist_length & 1) {
12001f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
12011f13597dSJung-uk Kim                 return 0;
12021f13597dSJung-uk Kim             }
1203*6f9291ceSJung-uk Kim             if (!s->hit) {
1204*6f9291ceSJung-uk Kim                 if (s->session->tlsext_ellipticcurvelist) {
12051f13597dSJung-uk Kim                     *al = TLS1_AD_DECODE_ERROR;
12061f13597dSJung-uk Kim                     return 0;
12071f13597dSJung-uk Kim                 }
12081f13597dSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length = 0;
1209*6f9291ceSJung-uk Kim                 if ((s->session->tlsext_ellipticcurvelist =
1210*6f9291ceSJung-uk Kim                      OPENSSL_malloc(ellipticcurvelist_length)) == NULL) {
12111f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
12121f13597dSJung-uk Kim                     return 0;
12131f13597dSJung-uk Kim                 }
1214*6f9291ceSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length =
1215*6f9291ceSJung-uk Kim                     ellipticcurvelist_length;
1216*6f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ellipticcurvelist, sdata,
1217*6f9291ceSJung-uk Kim                        ellipticcurvelist_length);
12181f13597dSJung-uk Kim             }
12191f13597dSJung-uk Kim #  if 0
1220*6f9291ceSJung-uk Kim             fprintf(stderr,
1221*6f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ",
1222*6f9291ceSJung-uk Kim                     s->session->tlsext_ellipticcurvelist_length);
12231f13597dSJung-uk Kim             sdata = s->session->tlsext_ellipticcurvelist;
12241f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
12251f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
12261f13597dSJung-uk Kim             fprintf(stderr, "\n");
12271f13597dSJung-uk Kim #  endif
12281f13597dSJung-uk Kim         }
12291f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
12301f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
12311f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input &&
1232*6f9291ceSJung-uk Kim                  s->version != DTLS1_VERSION) {
12331f13597dSJung-uk Kim             unsigned char *sdata = data;
12341f13597dSJung-uk Kim 
1235*6f9291ceSJung-uk Kim             if (size < 2) {
12361f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
12371f13597dSJung-uk Kim                 return 0;
12381f13597dSJung-uk Kim             }
12391f13597dSJung-uk Kim             n2s(sdata, s->s3->client_opaque_prf_input_len);
1240*6f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input_len != size - 2) {
12411f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
12421f13597dSJung-uk Kim                 return 0;
12431f13597dSJung-uk Kim             }
12441f13597dSJung-uk Kim 
1245*6f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
1246*6f9291ceSJung-uk Kim                 /* shouldn't really happen */
12471f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
1248*6f9291ceSJung-uk Kim             }
1249*6f9291ceSJung-uk Kim 
1250*6f9291ceSJung-uk Kim             /* dummy byte just to get non-NULL */
12511f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input_len == 0)
1252*6f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
12531f13597dSJung-uk Kim             else
1254*6f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
1255*6f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
1256*6f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
12571f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
12581f13597dSJung-uk Kim                 return 0;
12591f13597dSJung-uk Kim             }
12601f13597dSJung-uk Kim         }
12611f13597dSJung-uk Kim # endif
1262*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
12631f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
1264*6f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
1265*6f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
12661f13597dSJung-uk Kim             {
12671f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
12681f13597dSJung-uk Kim                 return 0;
12691f13597dSJung-uk Kim             }
1270*6f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_renegotiate) {
12716a599222SSimon L. B. Nielsen             if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
12726a599222SSimon L. B. Nielsen                 return 0;
12736a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
1274*6f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_signature_algorithms) {
12751f13597dSJung-uk Kim             int dsize;
1276*6f9291ceSJung-uk Kim             if (sigalg_seen || size < 2) {
12771f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
12781f13597dSJung-uk Kim                 return 0;
12791f13597dSJung-uk Kim             }
12801f13597dSJung-uk Kim             sigalg_seen = 1;
12811f13597dSJung-uk Kim             n2s(data, dsize);
12821f13597dSJung-uk Kim             size -= 2;
1283*6f9291ceSJung-uk Kim             if (dsize != size || dsize & 1) {
12841f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
12851f13597dSJung-uk Kim                 return 0;
12861f13597dSJung-uk Kim             }
1287*6f9291ceSJung-uk Kim             if (!tls1_process_sigalgs(s, data, dsize)) {
12881f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
12891f13597dSJung-uk Kim                 return 0;
12901f13597dSJung-uk Kim             }
1291*6f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_status_request &&
1292*6f9291ceSJung-uk Kim                    s->version != DTLS1_VERSION) {
1293db522d3aSSimon L. B. Nielsen 
1294*6f9291ceSJung-uk Kim             if (size < 5) {
1295db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
1296db522d3aSSimon L. B. Nielsen                 return 0;
1297db522d3aSSimon L. B. Nielsen             }
1298db522d3aSSimon L. B. Nielsen 
1299db522d3aSSimon L. B. Nielsen             s->tlsext_status_type = *data++;
1300db522d3aSSimon L. B. Nielsen             size--;
1301*6f9291ceSJung-uk Kim             if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
1302db522d3aSSimon L. B. Nielsen                 const unsigned char *sdata;
1303db522d3aSSimon L. B. Nielsen                 int dsize;
1304db522d3aSSimon L. B. Nielsen                 /* Read in responder_id_list */
1305db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
1306db522d3aSSimon L. B. Nielsen                 size -= 2;
1307*6f9291ceSJung-uk Kim                 if (dsize > size) {
1308db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_DECODE_ERROR;
1309db522d3aSSimon L. B. Nielsen                     return 0;
1310db522d3aSSimon L. B. Nielsen                 }
1311*6f9291ceSJung-uk Kim                 while (dsize > 0) {
1312db522d3aSSimon L. B. Nielsen                     OCSP_RESPID *id;
1313db522d3aSSimon L. B. Nielsen                     int idsize;
1314*6f9291ceSJung-uk Kim                     if (dsize < 4) {
1315db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_DECODE_ERROR;
1316db522d3aSSimon L. B. Nielsen                         return 0;
1317db522d3aSSimon L. B. Nielsen                     }
1318db522d3aSSimon L. B. Nielsen                     n2s(data, idsize);
1319db522d3aSSimon L. B. Nielsen                     dsize -= 2 + idsize;
13200a704568SSimon L. B. Nielsen                     size -= 2 + idsize;
1321*6f9291ceSJung-uk Kim                     if (dsize < 0) {
1322db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_DECODE_ERROR;
1323db522d3aSSimon L. B. Nielsen                         return 0;
1324db522d3aSSimon L. B. Nielsen                     }
1325db522d3aSSimon L. B. Nielsen                     sdata = data;
1326db522d3aSSimon L. B. Nielsen                     data += idsize;
1327*6f9291ceSJung-uk Kim                     id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
1328*6f9291ceSJung-uk Kim                     if (!id) {
1329db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_DECODE_ERROR;
1330db522d3aSSimon L. B. Nielsen                         return 0;
1331db522d3aSSimon L. B. Nielsen                     }
1332*6f9291ceSJung-uk Kim                     if (data != sdata) {
1333db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
1334db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_DECODE_ERROR;
1335db522d3aSSimon L. B. Nielsen                         return 0;
1336db522d3aSSimon L. B. Nielsen                     }
1337db522d3aSSimon L. B. Nielsen                     if (!s->tlsext_ocsp_ids
1338db522d3aSSimon L. B. Nielsen                         && !(s->tlsext_ocsp_ids =
1339*6f9291ceSJung-uk Kim                              sk_OCSP_RESPID_new_null())) {
1340db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
1341db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_INTERNAL_ERROR;
1342db522d3aSSimon L. B. Nielsen                         return 0;
1343db522d3aSSimon L. B. Nielsen                     }
1344*6f9291ceSJung-uk Kim                     if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
1345db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
1346db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_INTERNAL_ERROR;
1347db522d3aSSimon L. B. Nielsen                         return 0;
1348db522d3aSSimon L. B. Nielsen                     }
1349db522d3aSSimon L. B. Nielsen                 }
1350db522d3aSSimon L. B. Nielsen 
1351db522d3aSSimon L. B. Nielsen                 /* Read in request_extensions */
1352*6f9291ceSJung-uk Kim                 if (size < 2) {
13530a704568SSimon L. B. Nielsen                     *al = SSL_AD_DECODE_ERROR;
13540a704568SSimon L. B. Nielsen                     return 0;
13550a704568SSimon L. B. Nielsen                 }
1356db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
1357db522d3aSSimon L. B. Nielsen                 size -= 2;
1358*6f9291ceSJung-uk Kim                 if (dsize != size) {
1359db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_DECODE_ERROR;
1360db522d3aSSimon L. B. Nielsen                     return 0;
1361db522d3aSSimon L. B. Nielsen                 }
1362db522d3aSSimon L. B. Nielsen                 sdata = data;
1363*6f9291ceSJung-uk Kim                 if (dsize > 0) {
1364*6f9291ceSJung-uk Kim                     if (s->tlsext_ocsp_exts) {
136512de4ed2SJung-uk Kim                         sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
136612de4ed2SJung-uk Kim                                                    X509_EXTENSION_free);
136712de4ed2SJung-uk Kim                     }
136812de4ed2SJung-uk Kim 
1369db522d3aSSimon L. B. Nielsen                     s->tlsext_ocsp_exts =
1370*6f9291ceSJung-uk Kim                         d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
1371*6f9291ceSJung-uk Kim                     if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) {
1372db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_DECODE_ERROR;
1373db522d3aSSimon L. B. Nielsen                         return 0;
1374db522d3aSSimon L. B. Nielsen                     }
1375db522d3aSSimon L. B. Nielsen                 }
1376db522d3aSSimon L. B. Nielsen             }
1377*6f9291ceSJung-uk Kim             /*
1378*6f9291ceSJung-uk Kim              * We don't know what to do with any other type * so ignore it.
1379db522d3aSSimon L. B. Nielsen              */
1380db522d3aSSimon L. B. Nielsen             else
1381db522d3aSSimon L. B. Nielsen                 s->tlsext_status_type = -1;
1382db522d3aSSimon L. B. Nielsen         }
13831f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
1384*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
1385*6f9291ceSJung-uk Kim             switch (data[0]) {
13861f13597dSJung-uk Kim             case 0x01:         /* Client allows us to send HB requests */
13871f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
13881f13597dSJung-uk Kim                 break;
13891f13597dSJung-uk Kim             case 0x02:         /* Client doesn't accept HB requests */
13901f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
13911f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
13921f13597dSJung-uk Kim                 break;
1393*6f9291ceSJung-uk Kim             default:
1394*6f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
13951f13597dSJung-uk Kim                 return 0;
13961f13597dSJung-uk Kim             }
13971f13597dSJung-uk Kim         }
13981f13597dSJung-uk Kim # endif
13991f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
14001f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
1401*6f9291ceSJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
1402*6f9291ceSJung-uk Kim             /*-
1403*6f9291ceSJung-uk Kim              * We shouldn't accept this extension on a
14041f13597dSJung-uk Kim              * renegotiation.
14051f13597dSJung-uk Kim              *
14061f13597dSJung-uk Kim              * s->new_session will be set on renegotiation, but we
14071f13597dSJung-uk Kim              * probably shouldn't rely that it couldn't be set on
14081f13597dSJung-uk Kim              * the initial renegotation too in certain cases (when
14091f13597dSJung-uk Kim              * there's some other reason to disallow resuming an
14101f13597dSJung-uk Kim              * earlier session -- the current code won't be doing
14111f13597dSJung-uk Kim              * anything like that, but this might change).
1412*6f9291ceSJung-uk Kim              *
14131f13597dSJung-uk Kim              * A valid sign that there's been a previous handshake
14141f13597dSJung-uk Kim              * in this connection is if s->s3->tmp.finish_md_len >
14151f13597dSJung-uk Kim              * 0.  (We are talking about a check that will happen
14161f13597dSJung-uk Kim              * in the Hello protocol round, well before a new
1417*6f9291ceSJung-uk Kim              * Finished message could have been computed.)
1418*6f9291ceSJung-uk Kim              */
14191f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
14201f13597dSJung-uk Kim         }
14211f13597dSJung-uk Kim # endif
14226a599222SSimon L. B. Nielsen 
1423db522d3aSSimon L. B. Nielsen         /* session ticket processed earlier */
142409286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
1425fa5fddf1SJung-uk Kim         else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
1426*6f9291ceSJung-uk Kim                  && type == TLSEXT_TYPE_use_srtp) {
1427*6f9291ceSJung-uk Kim             if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al))
14281f13597dSJung-uk Kim                 return 0;
14291f13597dSJung-uk Kim         }
143009286989SJung-uk Kim # endif
1431db522d3aSSimon L. B. Nielsen 
1432db522d3aSSimon L. B. Nielsen         data += size;
1433db522d3aSSimon L. B. Nielsen     }
14341f13597dSJung-uk Kim 
1435db522d3aSSimon L. B. Nielsen     *p = data;
14366a599222SSimon L. B. Nielsen 
14376a599222SSimon L. B. Nielsen  ri_check:
14386a599222SSimon L. B. Nielsen 
14396a599222SSimon L. B. Nielsen     /* Need RI if renegotiating */
14406a599222SSimon L. B. Nielsen 
14411f13597dSJung-uk Kim     if (!renegotiate_seen && s->renegotiate &&
1442*6f9291ceSJung-uk Kim         !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
14436a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
14446a599222SSimon L. B. Nielsen         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
14456a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
14466a599222SSimon L. B. Nielsen         return 0;
14476a599222SSimon L. B. Nielsen     }
14486a599222SSimon L. B. Nielsen 
1449db522d3aSSimon L. B. Nielsen     return 1;
1450db522d3aSSimon L. B. Nielsen }
1451db522d3aSSimon L. B. Nielsen 
14521f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
1453*6f9291ceSJung-uk Kim /*
1454*6f9291ceSJung-uk Kim  * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
1455*6f9291ceSJung-uk Kim  * elements of zero length are allowed and the set of elements must exactly
1456*6f9291ceSJung-uk Kim  * fill the length of the block.
1457*6f9291ceSJung-uk Kim  */
14581f13597dSJung-uk Kim static char ssl_next_proto_validate(unsigned char *d, unsigned len)
14591f13597dSJung-uk Kim {
14601f13597dSJung-uk Kim     unsigned int off = 0;
14611f13597dSJung-uk Kim 
1462*6f9291ceSJung-uk Kim     while (off < len) {
14631f13597dSJung-uk Kim         if (d[off] == 0)
14641f13597dSJung-uk Kim             return 0;
14651f13597dSJung-uk Kim         off += d[off];
14661f13597dSJung-uk Kim         off++;
14671f13597dSJung-uk Kim     }
14681f13597dSJung-uk Kim 
14691f13597dSJung-uk Kim     return off == len;
14701f13597dSJung-uk Kim }
14711f13597dSJung-uk Kim # endif
14721f13597dSJung-uk Kim 
1473*6f9291ceSJung-uk Kim int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1474*6f9291ceSJung-uk Kim                                  int n, int *al)
1475db522d3aSSimon L. B. Nielsen {
1476a3ddd25aSSimon L. B. Nielsen     unsigned short length;
1477db522d3aSSimon L. B. Nielsen     unsigned short type;
1478db522d3aSSimon L. B. Nielsen     unsigned short size;
1479db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
1480db522d3aSSimon L. B. Nielsen     int tlsext_servername = 0;
14816a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
1482db522d3aSSimon L. B. Nielsen 
14831f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
14841f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
14851f13597dSJung-uk Kim # endif
1486751d2991SJung-uk Kim     s->tlsext_ticket_expected = 0;
14871f13597dSJung-uk Kim 
14881f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
14891f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
14901f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
14911f13597dSJung-uk Kim # endif
14921f13597dSJung-uk Kim 
1493db522d3aSSimon L. B. Nielsen     if (data >= (d + n - 2))
14946a599222SSimon L. B. Nielsen         goto ri_check;
1495db522d3aSSimon L. B. Nielsen 
1496a3ddd25aSSimon L. B. Nielsen     n2s(data, length);
1497*6f9291ceSJung-uk Kim     if (data + length != d + n) {
1498a3ddd25aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
1499a3ddd25aSSimon L. B. Nielsen         return 0;
1500a3ddd25aSSimon L. B. Nielsen     }
1501db522d3aSSimon L. B. Nielsen 
1502*6f9291ceSJung-uk Kim     while (data <= (d + n - 4)) {
1503db522d3aSSimon L. B. Nielsen         n2s(data, type);
1504db522d3aSSimon L. B. Nielsen         n2s(data, size);
1505db522d3aSSimon L. B. Nielsen 
1506db522d3aSSimon L. B. Nielsen         if (data + size > (d + n))
15076a599222SSimon L. B. Nielsen             goto ri_check;
1508db522d3aSSimon L. B. Nielsen 
1509db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
1510*6f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
1511db522d3aSSimon L. B. Nielsen 
1512*6f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
1513*6f9291ceSJung-uk Kim             if (s->tlsext_hostname == NULL || size > 0) {
1514db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNRECOGNIZED_NAME;
1515db522d3aSSimon L. B. Nielsen                 return 0;
1516db522d3aSSimon L. B. Nielsen             }
1517db522d3aSSimon L. B. Nielsen             tlsext_servername = 1;
1518db522d3aSSimon L. B. Nielsen         }
15191f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
1520*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
15211f13597dSJung-uk Kim             unsigned char *sdata = data;
15221f13597dSJung-uk Kim             int ecpointformatlist_length = *(sdata++);
15231f13597dSJung-uk Kim 
152409286989SJung-uk Kim             if (ecpointformatlist_length != size - 1 ||
1525*6f9291ceSJung-uk Kim                 ecpointformatlist_length < 1) {
15261f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
15271f13597dSJung-uk Kim                 return 0;
15281f13597dSJung-uk Kim             }
1529*6f9291ceSJung-uk Kim             if (!s->hit) {
15301f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
1531*6f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist != NULL)
1532*6f9291ceSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
1533*6f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
1534*6f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
15351f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
15361f13597dSJung-uk Kim                     return 0;
15371f13597dSJung-uk Kim                 }
1538*6f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
1539*6f9291ceSJung-uk Kim                     ecpointformatlist_length;
1540*6f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
1541*6f9291ceSJung-uk Kim                        ecpointformatlist_length);
1542a93cbc2bSJung-uk Kim             }
15431f13597dSJung-uk Kim #  if 0
1544*6f9291ceSJung-uk Kim             fprintf(stderr,
1545*6f9291ceSJung-uk Kim                     "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
15461f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
15471f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
15481f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
15491f13597dSJung-uk Kim             fprintf(stderr, "\n");
15501f13597dSJung-uk Kim #  endif
15511f13597dSJung-uk Kim         }
15521f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
15531f13597dSJung-uk Kim 
1554*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
15551f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
1556*6f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
1557*6f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
15581f13597dSJung-uk Kim             {
15591f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
15601f13597dSJung-uk Kim                 return 0;
15611f13597dSJung-uk Kim             }
1562db522d3aSSimon L. B. Nielsen             if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
1563*6f9291ceSJung-uk Kim                 || (size > 0)) {
1564db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
1565db522d3aSSimon L. B. Nielsen                 return 0;
1566db522d3aSSimon L. B. Nielsen             }
1567db522d3aSSimon L. B. Nielsen             s->tlsext_ticket_expected = 1;
1568db522d3aSSimon L. B. Nielsen         }
15691f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
15701f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input &&
1571*6f9291ceSJung-uk Kim                  s->version != DTLS1_VERSION) {
15721f13597dSJung-uk Kim             unsigned char *sdata = data;
15731f13597dSJung-uk Kim 
1574*6f9291ceSJung-uk Kim             if (size < 2) {
15751f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
15761f13597dSJung-uk Kim                 return 0;
15771f13597dSJung-uk Kim             }
15781f13597dSJung-uk Kim             n2s(sdata, s->s3->server_opaque_prf_input_len);
1579*6f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len != size - 2) {
15801f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
15811f13597dSJung-uk Kim                 return 0;
15821f13597dSJung-uk Kim             }
15831f13597dSJung-uk Kim 
1584*6f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input != NULL) {
1585*6f9291ceSJung-uk Kim                 /* shouldn't really happen */
15861f13597dSJung-uk Kim                 OPENSSL_free(s->s3->server_opaque_prf_input);
1587*6f9291ceSJung-uk Kim             }
1588*6f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len == 0) {
1589*6f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
1590*6f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
1591*6f9291ceSJung-uk Kim             } else {
1592*6f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input =
1593*6f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
1594*6f9291ceSJung-uk Kim             }
15951f13597dSJung-uk Kim 
1596*6f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input == NULL) {
15971f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
15981f13597dSJung-uk Kim                 return 0;
15991f13597dSJung-uk Kim             }
16001f13597dSJung-uk Kim         }
16011f13597dSJung-uk Kim # endif
16026a599222SSimon L. B. Nielsen         else if (type == TLSEXT_TYPE_status_request &&
1603*6f9291ceSJung-uk Kim                  s->version != DTLS1_VERSION) {
1604*6f9291ceSJung-uk Kim             /*
1605*6f9291ceSJung-uk Kim              * MUST be empty and only sent if we've requested a status
1606*6f9291ceSJung-uk Kim              * request message.
1607db522d3aSSimon L. B. Nielsen              */
1608*6f9291ceSJung-uk Kim             if ((s->tlsext_status_type == -1) || (size > 0)) {
1609db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
1610db522d3aSSimon L. B. Nielsen                 return 0;
1611db522d3aSSimon L. B. Nielsen             }
1612db522d3aSSimon L. B. Nielsen             /* Set flag to expect CertificateStatus message */
1613db522d3aSSimon L. B. Nielsen             s->tlsext_status_expected = 1;
1614db522d3aSSimon L. B. Nielsen         }
16151f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
16161f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
1617*6f9291ceSJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
16181f13597dSJung-uk Kim             unsigned char *selected;
16191f13597dSJung-uk Kim             unsigned char selected_len;
16201f13597dSJung-uk Kim 
16211f13597dSJung-uk Kim             /* We must have requested it. */
1622*6f9291ceSJung-uk Kim             if (s->ctx->next_proto_select_cb == NULL) {
16231f13597dSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
16241f13597dSJung-uk Kim                 return 0;
16251f13597dSJung-uk Kim             }
16261f13597dSJung-uk Kim             /* The data must be valid */
1627*6f9291ceSJung-uk Kim             if (!ssl_next_proto_validate(data, size)) {
16281f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
16291f13597dSJung-uk Kim                 return 0;
16301f13597dSJung-uk Kim             }
1631*6f9291ceSJung-uk Kim             if (s->
1632*6f9291ceSJung-uk Kim                 ctx->next_proto_select_cb(s, &selected, &selected_len, data,
1633*6f9291ceSJung-uk Kim                                           size,
1634*6f9291ceSJung-uk Kim                                           s->ctx->next_proto_select_cb_arg) !=
1635*6f9291ceSJung-uk Kim                 SSL_TLSEXT_ERR_OK) {
16361f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
16371f13597dSJung-uk Kim                 return 0;
16381f13597dSJung-uk Kim             }
16391f13597dSJung-uk Kim             s->next_proto_negotiated = OPENSSL_malloc(selected_len);
1640*6f9291ceSJung-uk Kim             if (!s->next_proto_negotiated) {
16411f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
16421f13597dSJung-uk Kim                 return 0;
16431f13597dSJung-uk Kim             }
16441f13597dSJung-uk Kim             memcpy(s->next_proto_negotiated, selected, selected_len);
16451f13597dSJung-uk Kim             s->next_proto_negotiated_len = selected_len;
16461f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
16471f13597dSJung-uk Kim         }
16481f13597dSJung-uk Kim # endif
1649*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_renegotiate) {
16506a599222SSimon L. B. Nielsen             if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
16516a599222SSimon L. B. Nielsen                 return 0;
16526a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
16536a599222SSimon L. B. Nielsen         }
16541f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
1655*6f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
1656*6f9291ceSJung-uk Kim             switch (data[0]) {
16571f13597dSJung-uk Kim             case 0x01:         /* Server allows us to send HB requests */
16581f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
16591f13597dSJung-uk Kim                 break;
16601f13597dSJung-uk Kim             case 0x02:         /* Server doesn't accept HB requests */
16611f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
16621f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
16631f13597dSJung-uk Kim                 break;
1664*6f9291ceSJung-uk Kim             default:
1665*6f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
16661f13597dSJung-uk Kim                 return 0;
16671f13597dSJung-uk Kim             }
16681f13597dSJung-uk Kim         }
16691f13597dSJung-uk Kim # endif
167009286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
1671*6f9291ceSJung-uk Kim         else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
1672*6f9291ceSJung-uk Kim             if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al))
16731f13597dSJung-uk Kim                 return 0;
16741f13597dSJung-uk Kim         }
167509286989SJung-uk Kim # endif
16761f13597dSJung-uk Kim 
1677db522d3aSSimon L. B. Nielsen         data += size;
1678db522d3aSSimon L. B. Nielsen     }
1679db522d3aSSimon L. B. Nielsen 
1680*6f9291ceSJung-uk Kim     if (data != d + n) {
1681db522d3aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
1682db522d3aSSimon L. B. Nielsen         return 0;
1683db522d3aSSimon L. B. Nielsen     }
1684db522d3aSSimon L. B. Nielsen 
1685*6f9291ceSJung-uk Kim     if (!s->hit && tlsext_servername == 1) {
1686*6f9291ceSJung-uk Kim         if (s->tlsext_hostname) {
1687*6f9291ceSJung-uk Kim             if (s->session->tlsext_hostname == NULL) {
1688db522d3aSSimon L. B. Nielsen                 s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
1689*6f9291ceSJung-uk Kim                 if (!s->session->tlsext_hostname) {
1690db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_UNRECOGNIZED_NAME;
1691db522d3aSSimon L. B. Nielsen                     return 0;
1692db522d3aSSimon L. B. Nielsen                 }
1693*6f9291ceSJung-uk Kim             } else {
1694db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
1695db522d3aSSimon L. B. Nielsen                 return 0;
1696db522d3aSSimon L. B. Nielsen             }
1697db522d3aSSimon L. B. Nielsen         }
1698db522d3aSSimon L. B. Nielsen     }
1699db522d3aSSimon L. B. Nielsen 
1700db522d3aSSimon L. B. Nielsen     *p = data;
17016a599222SSimon L. B. Nielsen 
17026a599222SSimon L. B. Nielsen  ri_check:
17036a599222SSimon L. B. Nielsen 
1704*6f9291ceSJung-uk Kim     /*
1705*6f9291ceSJung-uk Kim      * Determine if we need to see RI. Strictly speaking if we want to avoid
1706*6f9291ceSJung-uk Kim      * an attack we should *always* see RI even on initial server hello
1707*6f9291ceSJung-uk Kim      * because the client doesn't see any renegotiation during an attack.
1708*6f9291ceSJung-uk Kim      * However this would mean we could not connect to any server which
1709*6f9291ceSJung-uk Kim      * doesn't support RI so for the immediate future tolerate RI absence on
1710*6f9291ceSJung-uk Kim      * initial connect only.
17116a599222SSimon L. B. Nielsen      */
1712*6f9291ceSJung-uk Kim     if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
1713*6f9291ceSJung-uk Kim         && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
17146a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
17156a599222SSimon L. B. Nielsen         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
17166a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
17176a599222SSimon L. B. Nielsen         return 0;
17186a599222SSimon L. B. Nielsen     }
17196a599222SSimon L. B. Nielsen 
1720db522d3aSSimon L. B. Nielsen     return 1;
1721db522d3aSSimon L. B. Nielsen }
1722db522d3aSSimon L. B. Nielsen 
17231f13597dSJung-uk Kim int ssl_prepare_clienthello_tlsext(SSL *s)
17241f13597dSJung-uk Kim {
17251f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
1726*6f9291ceSJung-uk Kim     /*
1727*6f9291ceSJung-uk Kim      * If we are client and using an elliptic curve cryptography cipher
1728*6f9291ceSJung-uk Kim      * suite, send the point formats and elliptic curves we support.
17291f13597dSJung-uk Kim      */
17301f13597dSJung-uk Kim     int using_ecc = 0;
17311f13597dSJung-uk Kim     int i;
17321f13597dSJung-uk Kim     unsigned char *j;
17331f13597dSJung-uk Kim     unsigned long alg_k, alg_a;
17341f13597dSJung-uk Kim     STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
17351f13597dSJung-uk Kim 
1736*6f9291ceSJung-uk Kim     for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
17371f13597dSJung-uk Kim         SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
17381f13597dSJung-uk Kim 
17391f13597dSJung-uk Kim         alg_k = c->algorithm_mkey;
17401f13597dSJung-uk Kim         alg_a = c->algorithm_auth;
1741*6f9291ceSJung-uk Kim         if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)
1742*6f9291ceSJung-uk Kim              || (alg_a & SSL_aECDSA))) {
17431f13597dSJung-uk Kim             using_ecc = 1;
17441f13597dSJung-uk Kim             break;
17451f13597dSJung-uk Kim         }
17461f13597dSJung-uk Kim     }
17471f13597dSJung-uk Kim     using_ecc = using_ecc && (s->version >= TLS1_VERSION);
1748*6f9291ceSJung-uk Kim     if (using_ecc) {
1749*6f9291ceSJung-uk Kim         if (s->tlsext_ecpointformatlist != NULL)
1750*6f9291ceSJung-uk Kim             OPENSSL_free(s->tlsext_ecpointformatlist);
1751*6f9291ceSJung-uk Kim         if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL) {
1752*6f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1753*6f9291ceSJung-uk Kim                    ERR_R_MALLOC_FAILURE);
17541f13597dSJung-uk Kim             return -1;
17551f13597dSJung-uk Kim         }
17561f13597dSJung-uk Kim         s->tlsext_ecpointformatlist_length = 3;
17571f13597dSJung-uk Kim         s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
1758*6f9291ceSJung-uk Kim         s->tlsext_ecpointformatlist[1] =
1759*6f9291ceSJung-uk Kim             TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
1760*6f9291ceSJung-uk Kim         s->tlsext_ecpointformatlist[2] =
1761*6f9291ceSJung-uk Kim             TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
17621f13597dSJung-uk Kim 
1763751d2991SJung-uk Kim         /* we support all named elliptic curves in RFC 4492 */
1764*6f9291ceSJung-uk Kim         if (s->tlsext_ellipticcurvelist != NULL)
1765*6f9291ceSJung-uk Kim             OPENSSL_free(s->tlsext_ellipticcurvelist);
1766*6f9291ceSJung-uk Kim         s->tlsext_ellipticcurvelist_length =
1767*6f9291ceSJung-uk Kim             sizeof(pref_list) / sizeof(pref_list[0]) * 2;
1768*6f9291ceSJung-uk Kim         if ((s->tlsext_ellipticcurvelist =
1769*6f9291ceSJung-uk Kim              OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL) {
17701f13597dSJung-uk Kim             s->tlsext_ellipticcurvelist_length = 0;
1771*6f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1772*6f9291ceSJung-uk Kim                    ERR_R_MALLOC_FAILURE);
17731f13597dSJung-uk Kim             return -1;
17741f13597dSJung-uk Kim         }
17751f13597dSJung-uk Kim         for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i <
1776*6f9291ceSJung-uk Kim              sizeof(pref_list) / sizeof(pref_list[0]); i++) {
17771f13597dSJung-uk Kim             int id = tls1_ec_nid2curve_id(pref_list[i]);
17781f13597dSJung-uk Kim             s2n(id, j);
17791f13597dSJung-uk Kim         }
17801f13597dSJung-uk Kim     }
17811f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
17821f13597dSJung-uk Kim 
17831f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
17841f13597dSJung-uk Kim     {
17851f13597dSJung-uk Kim         int r = 1;
17861f13597dSJung-uk Kim 
1787*6f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
1788*6f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
1789*6f9291ceSJung-uk Kim                                                          s->
1790*6f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
17911f13597dSJung-uk Kim             if (!r)
17921f13597dSJung-uk Kim                 return -1;
17931f13597dSJung-uk Kim         }
17941f13597dSJung-uk Kim 
1795*6f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
1796*6f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
1797*6f9291ceSJung-uk Kim                 /* shouldn't really happen */
17981f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
1799*6f9291ceSJung-uk Kim             }
18001f13597dSJung-uk Kim 
1801*6f9291ceSJung-uk Kim             if (s->tlsext_opaque_prf_input_len == 0) {
1802*6f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
1803*6f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
1804*6f9291ceSJung-uk Kim             } else {
1805*6f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
1806*6f9291ceSJung-uk Kim                     BUF_memdup(s->tlsext_opaque_prf_input,
1807*6f9291ceSJung-uk Kim                                s->tlsext_opaque_prf_input_len);
1808*6f9291ceSJung-uk Kim             }
1809*6f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
1810*6f9291ceSJung-uk Kim                 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
1811*6f9291ceSJung-uk Kim                        ERR_R_MALLOC_FAILURE);
18121f13597dSJung-uk Kim                 return -1;
18131f13597dSJung-uk Kim             }
1814*6f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len =
1815*6f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
18161f13597dSJung-uk Kim         }
18171f13597dSJung-uk Kim 
18181f13597dSJung-uk Kim         if (r == 2)
1819*6f9291ceSJung-uk Kim             /*
1820*6f9291ceSJung-uk Kim              * at callback's request, insist on receiving an appropriate
1821*6f9291ceSJung-uk Kim              * server opaque PRF input
1822*6f9291ceSJung-uk Kim              */
1823*6f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len =
1824*6f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
18251f13597dSJung-uk Kim     }
18261f13597dSJung-uk Kim # endif
18271f13597dSJung-uk Kim 
18281f13597dSJung-uk Kim     return 1;
18291f13597dSJung-uk Kim }
18301f13597dSJung-uk Kim 
18311f13597dSJung-uk Kim int ssl_prepare_serverhello_tlsext(SSL *s)
18321f13597dSJung-uk Kim {
18331f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
1834*6f9291ceSJung-uk Kim     /*
1835*6f9291ceSJung-uk Kim      * If we are server and using an ECC cipher suite, send the point formats
1836*6f9291ceSJung-uk Kim      * we support if the client sent us an ECPointsFormat extension.  Note
1837*6f9291ceSJung-uk Kim      * that the server is not supposed to send an EllipticCurves extension.
18381f13597dSJung-uk Kim      */
18391f13597dSJung-uk Kim 
18401f13597dSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
18411f13597dSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
1842*6f9291ceSJung-uk Kim     int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
1843*6f9291ceSJung-uk Kim         || (alg_a & SSL_aECDSA);
18441f13597dSJung-uk Kim     using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
18451f13597dSJung-uk Kim 
1846*6f9291ceSJung-uk Kim     if (using_ecc) {
1847*6f9291ceSJung-uk Kim         if (s->tlsext_ecpointformatlist != NULL)
1848*6f9291ceSJung-uk Kim             OPENSSL_free(s->tlsext_ecpointformatlist);
1849*6f9291ceSJung-uk Kim         if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL) {
1850*6f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,
1851*6f9291ceSJung-uk Kim                    ERR_R_MALLOC_FAILURE);
18521f13597dSJung-uk Kim             return -1;
18531f13597dSJung-uk Kim         }
18541f13597dSJung-uk Kim         s->tlsext_ecpointformatlist_length = 3;
18551f13597dSJung-uk Kim         s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
1856*6f9291ceSJung-uk Kim         s->tlsext_ecpointformatlist[1] =
1857*6f9291ceSJung-uk Kim             TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
1858*6f9291ceSJung-uk Kim         s->tlsext_ecpointformatlist[2] =
1859*6f9291ceSJung-uk Kim             TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
18601f13597dSJung-uk Kim     }
18611f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
18621f13597dSJung-uk Kim 
18631f13597dSJung-uk Kim     return 1;
18641f13597dSJung-uk Kim }
18651f13597dSJung-uk Kim 
186609286989SJung-uk Kim int ssl_check_clienthello_tlsext_early(SSL *s)
1867db522d3aSSimon L. B. Nielsen {
1868db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
1869db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
1870db522d3aSSimon L. B. Nielsen 
18711f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
1872*6f9291ceSJung-uk Kim     /*
1873*6f9291ceSJung-uk Kim      * The handling of the ECPointFormats extension is done elsewhere, namely
1874*6f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
18751f13597dSJung-uk Kim      */
1876*6f9291ceSJung-uk Kim     /*
1877*6f9291ceSJung-uk Kim      * The handling of the EllipticCurves extension is done elsewhere, namely
1878*6f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
18791f13597dSJung-uk Kim      */
18801f13597dSJung-uk Kim # endif
18811f13597dSJung-uk Kim 
1882db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
1883*6f9291ceSJung-uk Kim         ret =
1884*6f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
1885*6f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
1886*6f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
1887*6f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
1888*6f9291ceSJung-uk Kim         ret =
1889*6f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
1890*6f9291ceSJung-uk Kim                                                        s->
1891*6f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
1892db522d3aSSimon L. B. Nielsen 
18931f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
18941f13597dSJung-uk Kim     {
1895*6f9291ceSJung-uk Kim         /*
1896*6f9291ceSJung-uk Kim          * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we
1897*6f9291ceSJung-uk Kim          * might be sending an alert in response to the client hello, so this
1898*6f9291ceSJung-uk Kim          * has to happen here in ssl_check_clienthello_tlsext_early().
1899*6f9291ceSJung-uk Kim          */
19001f13597dSJung-uk Kim 
19011f13597dSJung-uk Kim         int r = 1;
19021f13597dSJung-uk Kim 
1903*6f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
1904*6f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
1905*6f9291ceSJung-uk Kim                                                          s->
1906*6f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
1907*6f9291ceSJung-uk Kim             if (!r) {
19081f13597dSJung-uk Kim                 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
19091f13597dSJung-uk Kim                 al = SSL_AD_INTERNAL_ERROR;
19101f13597dSJung-uk Kim                 goto err;
19111f13597dSJung-uk Kim             }
19121f13597dSJung-uk Kim         }
19131f13597dSJung-uk Kim 
1914*6f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input != NULL) {
1915*6f9291ceSJung-uk Kim             /* shouldn't really happen */
19161f13597dSJung-uk Kim             OPENSSL_free(s->s3->server_opaque_prf_input);
1917*6f9291ceSJung-uk Kim         }
19181f13597dSJung-uk Kim         s->s3->server_opaque_prf_input = NULL;
19191f13597dSJung-uk Kim 
1920*6f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
19211f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL &&
1922*6f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input_len ==
1923*6f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len) {
1924*6f9291ceSJung-uk Kim                 /*
1925*6f9291ceSJung-uk Kim                  * can only use this extension if we have a server opaque PRF
1926*6f9291ceSJung-uk Kim                  * input of the same length as the client opaque PRF input!
1927*6f9291ceSJung-uk Kim                  */
19281f13597dSJung-uk Kim 
1929*6f9291ceSJung-uk Kim                 if (s->tlsext_opaque_prf_input_len == 0) {
1930*6f9291ceSJung-uk Kim                     /* dummy byte just to get non-NULL */
1931*6f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
1932*6f9291ceSJung-uk Kim                 } else {
1933*6f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input =
1934*6f9291ceSJung-uk Kim                         BUF_memdup(s->tlsext_opaque_prf_input,
1935*6f9291ceSJung-uk Kim                                    s->tlsext_opaque_prf_input_len);
1936*6f9291ceSJung-uk Kim                 }
1937*6f9291ceSJung-uk Kim                 if (s->s3->server_opaque_prf_input == NULL) {
19381f13597dSJung-uk Kim                     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
19391f13597dSJung-uk Kim                     al = SSL_AD_INTERNAL_ERROR;
19401f13597dSJung-uk Kim                     goto err;
19411f13597dSJung-uk Kim                 }
1942*6f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input_len =
1943*6f9291ceSJung-uk Kim                     s->tlsext_opaque_prf_input_len;
19441f13597dSJung-uk Kim             }
19451f13597dSJung-uk Kim         }
19461f13597dSJung-uk Kim 
1947*6f9291ceSJung-uk Kim         if (r == 2 && s->s3->server_opaque_prf_input == NULL) {
1948*6f9291ceSJung-uk Kim             /*
1949*6f9291ceSJung-uk Kim              * The callback wants to enforce use of the extension, but we
1950*6f9291ceSJung-uk Kim              * can't do that with the client opaque PRF input; abort the
1951*6f9291ceSJung-uk Kim              * handshake.
19521f13597dSJung-uk Kim              */
19531f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
19541f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
19551f13597dSJung-uk Kim         }
19561f13597dSJung-uk Kim     }
19571f13597dSJung-uk Kim 
1958db522d3aSSimon L. B. Nielsen  err:
195909286989SJung-uk Kim # endif
1960*6f9291ceSJung-uk Kim     switch (ret) {
1961db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
1962db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
1963db522d3aSSimon L. B. Nielsen         return -1;
1964db522d3aSSimon L. B. Nielsen 
1965db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
1966db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
1967db522d3aSSimon L. B. Nielsen         return 1;
1968db522d3aSSimon L. B. Nielsen 
1969db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
1970db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
1971db522d3aSSimon L. B. Nielsen     default:
1972db522d3aSSimon L. B. Nielsen         return 1;
1973db522d3aSSimon L. B. Nielsen     }
1974db522d3aSSimon L. B. Nielsen }
1975db522d3aSSimon L. B. Nielsen 
197609286989SJung-uk Kim int ssl_check_clienthello_tlsext_late(SSL *s)
197709286989SJung-uk Kim {
197809286989SJung-uk Kim     int ret = SSL_TLSEXT_ERR_OK;
197909286989SJung-uk Kim     int al;
198009286989SJung-uk Kim 
1981*6f9291ceSJung-uk Kim     /*
1982*6f9291ceSJung-uk Kim      * If status request then ask callback what to do. Note: this must be
1983*6f9291ceSJung-uk Kim      * called after servername callbacks in case the certificate has
1984*6f9291ceSJung-uk Kim      * changed, and must be called after the cipher has been chosen because
1985*6f9291ceSJung-uk Kim      * this may influence which certificate is sent
198609286989SJung-uk Kim      */
1987*6f9291ceSJung-uk Kim     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
198809286989SJung-uk Kim         int r;
198909286989SJung-uk Kim         CERT_PKEY *certpkey;
199009286989SJung-uk Kim         certpkey = ssl_get_server_send_pkey(s);
199109286989SJung-uk Kim         /* If no certificate can't return certificate status */
1992*6f9291ceSJung-uk Kim         if (certpkey == NULL) {
199309286989SJung-uk Kim             s->tlsext_status_expected = 0;
199409286989SJung-uk Kim             return 1;
199509286989SJung-uk Kim         }
1996*6f9291ceSJung-uk Kim         /*
1997*6f9291ceSJung-uk Kim          * Set current certificate to one we will use so SSL_get_certificate
1998*6f9291ceSJung-uk Kim          * et al can pick it up.
199909286989SJung-uk Kim          */
200009286989SJung-uk Kim         s->cert->key = certpkey;
200109286989SJung-uk Kim         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
2002*6f9291ceSJung-uk Kim         switch (r) {
200309286989SJung-uk Kim             /* We don't want to send a status request response */
200409286989SJung-uk Kim         case SSL_TLSEXT_ERR_NOACK:
200509286989SJung-uk Kim             s->tlsext_status_expected = 0;
200609286989SJung-uk Kim             break;
200709286989SJung-uk Kim             /* status request response should be sent */
200809286989SJung-uk Kim         case SSL_TLSEXT_ERR_OK:
200909286989SJung-uk Kim             if (s->tlsext_ocsp_resp)
201009286989SJung-uk Kim                 s->tlsext_status_expected = 1;
201109286989SJung-uk Kim             else
201209286989SJung-uk Kim                 s->tlsext_status_expected = 0;
201309286989SJung-uk Kim             break;
201409286989SJung-uk Kim             /* something bad happened */
201509286989SJung-uk Kim         case SSL_TLSEXT_ERR_ALERT_FATAL:
201609286989SJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
201709286989SJung-uk Kim             al = SSL_AD_INTERNAL_ERROR;
201809286989SJung-uk Kim             goto err;
201909286989SJung-uk Kim         }
2020*6f9291ceSJung-uk Kim     } else
202109286989SJung-uk Kim         s->tlsext_status_expected = 0;
202209286989SJung-uk Kim 
202309286989SJung-uk Kim  err:
2024*6f9291ceSJung-uk Kim     switch (ret) {
202509286989SJung-uk Kim     case SSL_TLSEXT_ERR_ALERT_FATAL:
202609286989SJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
202709286989SJung-uk Kim         return -1;
202809286989SJung-uk Kim 
202909286989SJung-uk Kim     case SSL_TLSEXT_ERR_ALERT_WARNING:
203009286989SJung-uk Kim         ssl3_send_alert(s, SSL3_AL_WARNING, al);
203109286989SJung-uk Kim         return 1;
203209286989SJung-uk Kim 
203309286989SJung-uk Kim     default:
203409286989SJung-uk Kim         return 1;
203509286989SJung-uk Kim     }
203609286989SJung-uk Kim }
203709286989SJung-uk Kim 
2038db522d3aSSimon L. B. Nielsen int ssl_check_serverhello_tlsext(SSL *s)
2039db522d3aSSimon L. B. Nielsen {
2040db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
2041db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
2042db522d3aSSimon L. B. Nielsen 
20431f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
2044*6f9291ceSJung-uk Kim     /*
2045*6f9291ceSJung-uk Kim      * If we are client and using an elliptic curve cryptography cipher
2046*6f9291ceSJung-uk Kim      * suite, then if server returns an EC point formats lists extension it
2047*6f9291ceSJung-uk Kim      * must contain uncompressed.
20481f13597dSJung-uk Kim      */
20491f13597dSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
20501f13597dSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
2051*6f9291ceSJung-uk Kim     if ((s->tlsext_ecpointformatlist != NULL)
2052*6f9291ceSJung-uk Kim         && (s->tlsext_ecpointformatlist_length > 0)
2053*6f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist != NULL)
2054*6f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist_length > 0)
2055*6f9291ceSJung-uk Kim         && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
2056*6f9291ceSJung-uk Kim             || (alg_a & SSL_aECDSA))) {
20571f13597dSJung-uk Kim         /* we are using an ECC cipher */
20581f13597dSJung-uk Kim         size_t i;
20591f13597dSJung-uk Kim         unsigned char *list;
20601f13597dSJung-uk Kim         int found_uncompressed = 0;
20611f13597dSJung-uk Kim         list = s->session->tlsext_ecpointformatlist;
2062*6f9291ceSJung-uk Kim         for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
2063*6f9291ceSJung-uk Kim             if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
20641f13597dSJung-uk Kim                 found_uncompressed = 1;
20651f13597dSJung-uk Kim                 break;
20661f13597dSJung-uk Kim             }
20671f13597dSJung-uk Kim         }
2068*6f9291ceSJung-uk Kim         if (!found_uncompressed) {
2069*6f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
2070*6f9291ceSJung-uk Kim                    SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
20711f13597dSJung-uk Kim             return -1;
20721f13597dSJung-uk Kim         }
20731f13597dSJung-uk Kim     }
20741f13597dSJung-uk Kim     ret = SSL_TLSEXT_ERR_OK;
20751f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
20761f13597dSJung-uk Kim 
2077db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
2078*6f9291ceSJung-uk Kim         ret =
2079*6f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
2080*6f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
2081*6f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
2082*6f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
2083*6f9291ceSJung-uk Kim         ret =
2084*6f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
2085*6f9291ceSJung-uk Kim                                                        s->
2086*6f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
2087db522d3aSSimon L. B. Nielsen 
20881f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
2089*6f9291ceSJung-uk Kim     if (s->s3->server_opaque_prf_input_len > 0) {
2090*6f9291ceSJung-uk Kim         /*
2091*6f9291ceSJung-uk Kim          * This case may indicate that we, as a client, want to insist on
2092*6f9291ceSJung-uk Kim          * using opaque PRF inputs. So first verify that we really have a
2093*6f9291ceSJung-uk Kim          * value from the server too.
2094*6f9291ceSJung-uk Kim          */
20951f13597dSJung-uk Kim 
2096*6f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input == NULL) {
20971f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
20981f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
20991f13597dSJung-uk Kim         }
21001f13597dSJung-uk Kim 
2101*6f9291ceSJung-uk Kim         /*
2102*6f9291ceSJung-uk Kim          * Anytime the server *has* sent an opaque PRF input, we need to
2103*6f9291ceSJung-uk Kim          * check that we have a client opaque PRF input of the same size.
2104*6f9291ceSJung-uk Kim          */
21051f13597dSJung-uk Kim         if (s->s3->client_opaque_prf_input == NULL ||
2106*6f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len !=
2107*6f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len) {
21081f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
21091f13597dSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
21101f13597dSJung-uk Kim         }
21111f13597dSJung-uk Kim     }
21121f13597dSJung-uk Kim # endif
21131f13597dSJung-uk Kim 
2114*6f9291ceSJung-uk Kim     /*
2115*6f9291ceSJung-uk Kim      * If we've requested certificate status and we wont get one tell the
2116*6f9291ceSJung-uk Kim      * callback
2117db522d3aSSimon L. B. Nielsen      */
2118db522d3aSSimon L. B. Nielsen     if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
2119*6f9291ceSJung-uk Kim         && s->ctx && s->ctx->tlsext_status_cb) {
2120db522d3aSSimon L. B. Nielsen         int r;
2121*6f9291ceSJung-uk Kim         /*
2122*6f9291ceSJung-uk Kim          * Set resp to NULL, resplen to -1 so callback knows there is no
2123*6f9291ceSJung-uk Kim          * response.
2124db522d3aSSimon L. B. Nielsen          */
2125*6f9291ceSJung-uk Kim         if (s->tlsext_ocsp_resp) {
2126db522d3aSSimon L. B. Nielsen             OPENSSL_free(s->tlsext_ocsp_resp);
2127db522d3aSSimon L. B. Nielsen             s->tlsext_ocsp_resp = NULL;
2128db522d3aSSimon L. B. Nielsen         }
2129db522d3aSSimon L. B. Nielsen         s->tlsext_ocsp_resplen = -1;
2130db522d3aSSimon L. B. Nielsen         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
2131*6f9291ceSJung-uk Kim         if (r == 0) {
2132db522d3aSSimon L. B. Nielsen             al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
2133db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
2134db522d3aSSimon L. B. Nielsen         }
2135*6f9291ceSJung-uk Kim         if (r < 0) {
2136db522d3aSSimon L. B. Nielsen             al = SSL_AD_INTERNAL_ERROR;
2137db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
2138db522d3aSSimon L. B. Nielsen         }
2139db522d3aSSimon L. B. Nielsen     }
2140db522d3aSSimon L. B. Nielsen 
2141*6f9291ceSJung-uk Kim     switch (ret) {
2142db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
2143db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
2144db522d3aSSimon L. B. Nielsen         return -1;
2145db522d3aSSimon L. B. Nielsen 
2146db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
2147db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
2148db522d3aSSimon L. B. Nielsen         return 1;
2149db522d3aSSimon L. B. Nielsen 
2150db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
2151db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
2152db522d3aSSimon L. B. Nielsen     default:
2153db522d3aSSimon L. B. Nielsen         return 1;
2154db522d3aSSimon L. B. Nielsen     }
2155db522d3aSSimon L. B. Nielsen }
2156db522d3aSSimon L. B. Nielsen 
2157*6f9291ceSJung-uk Kim /*-
2158*6f9291ceSJung-uk Kim  * Since the server cache lookup is done early on in the processing of the
21591f13597dSJung-uk Kim  * ClientHello, and other operations depend on the result, we need to handle
21601f13597dSJung-uk Kim  * any TLS session ticket extension at the same time.
21611f13597dSJung-uk Kim  *
21621f13597dSJung-uk Kim  *   session_id: points at the session ID in the ClientHello. This code will
21631f13597dSJung-uk Kim  *       read past the end of this in order to parse out the session ticket
21641f13597dSJung-uk Kim  *       extension, if any.
21651f13597dSJung-uk Kim  *   len: the length of the session ID.
21661f13597dSJung-uk Kim  *   limit: a pointer to the first byte after the ClientHello.
21671f13597dSJung-uk Kim  *   ret: (output) on return, if a ticket was decrypted, then this is set to
21681f13597dSJung-uk Kim  *       point to the resulting session.
21691f13597dSJung-uk Kim  *
21701f13597dSJung-uk Kim  * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
21711f13597dSJung-uk Kim  * ciphersuite, in which case we have no use for session tickets and one will
21721f13597dSJung-uk Kim  * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
21731f13597dSJung-uk Kim  *
21741f13597dSJung-uk Kim  * Returns:
21751f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
21761f13597dSJung-uk Kim  *    0: no ticket was found (or was ignored, based on settings).
21771f13597dSJung-uk Kim  *    1: a zero length extension was found, indicating that the client supports
21781f13597dSJung-uk Kim  *       session tickets but doesn't currently have one to offer.
21791f13597dSJung-uk Kim  *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
21801f13597dSJung-uk Kim  *       couldn't be decrypted because of a non-fatal error.
21811f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *ret was set.
21821f13597dSJung-uk Kim  *
21831f13597dSJung-uk Kim  * Side effects:
21841f13597dSJung-uk Kim  *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
21851f13597dSJung-uk Kim  *   a new session ticket to the client because the client indicated support
21861f13597dSJung-uk Kim  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
21871f13597dSJung-uk Kim  *   a session ticket or we couldn't use the one it gave us, or if
21881f13597dSJung-uk Kim  *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
21891f13597dSJung-uk Kim  *   Otherwise, s->tlsext_ticket_expected is set to 0.
2190db522d3aSSimon L. B. Nielsen  */
2191db522d3aSSimon L. B. Nielsen int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
2192db522d3aSSimon L. B. Nielsen                         const unsigned char *limit, SSL_SESSION **ret)
2193db522d3aSSimon L. B. Nielsen {
2194db522d3aSSimon L. B. Nielsen     /* Point after session ID in client hello */
2195db522d3aSSimon L. B. Nielsen     const unsigned char *p = session_id + len;
2196db522d3aSSimon L. B. Nielsen     unsigned short i;
2197db522d3aSSimon L. B. Nielsen 
21981f13597dSJung-uk Kim     *ret = NULL;
21991f13597dSJung-uk Kim     s->tlsext_ticket_expected = 0;
22001f13597dSJung-uk Kim 
2201*6f9291ceSJung-uk Kim     /*
2202*6f9291ceSJung-uk Kim      * If tickets disabled behave as if no ticket present to permit stateful
2203*6f9291ceSJung-uk Kim      * resumption.
2204db522d3aSSimon L. B. Nielsen      */
2205db522d3aSSimon L. B. Nielsen     if (SSL_get_options(s) & SSL_OP_NO_TICKET)
22061f13597dSJung-uk Kim         return 0;
2207db522d3aSSimon L. B. Nielsen     if ((s->version <= SSL3_VERSION) || !limit)
22081f13597dSJung-uk Kim         return 0;
2209db522d3aSSimon L. B. Nielsen     if (p >= limit)
2210db522d3aSSimon L. B. Nielsen         return -1;
22116a599222SSimon L. B. Nielsen     /* Skip past DTLS cookie */
2212*6f9291ceSJung-uk Kim     if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
22136a599222SSimon L. B. Nielsen         i = *(p++);
22146a599222SSimon L. B. Nielsen         p += i;
22156a599222SSimon L. B. Nielsen         if (p >= limit)
22166a599222SSimon L. B. Nielsen             return -1;
22176a599222SSimon L. B. Nielsen     }
2218db522d3aSSimon L. B. Nielsen     /* Skip past cipher list */
2219db522d3aSSimon L. B. Nielsen     n2s(p, i);
2220db522d3aSSimon L. B. Nielsen     p += i;
2221db522d3aSSimon L. B. Nielsen     if (p >= limit)
2222db522d3aSSimon L. B. Nielsen         return -1;
2223db522d3aSSimon L. B. Nielsen     /* Skip past compression algorithm list */
2224db522d3aSSimon L. B. Nielsen     i = *(p++);
2225db522d3aSSimon L. B. Nielsen     p += i;
2226db522d3aSSimon L. B. Nielsen     if (p > limit)
2227db522d3aSSimon L. B. Nielsen         return -1;
2228db522d3aSSimon L. B. Nielsen     /* Now at start of extensions */
2229db522d3aSSimon L. B. Nielsen     if ((p + 2) >= limit)
22301f13597dSJung-uk Kim         return 0;
2231db522d3aSSimon L. B. Nielsen     n2s(p, i);
2232*6f9291ceSJung-uk Kim     while ((p + 4) <= limit) {
2233db522d3aSSimon L. B. Nielsen         unsigned short type, size;
2234db522d3aSSimon L. B. Nielsen         n2s(p, type);
2235db522d3aSSimon L. B. Nielsen         n2s(p, size);
2236db522d3aSSimon L. B. Nielsen         if (p + size > limit)
22371f13597dSJung-uk Kim             return 0;
2238*6f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_session_ticket) {
22391f13597dSJung-uk Kim             int r;
2240*6f9291ceSJung-uk Kim             if (size == 0) {
2241*6f9291ceSJung-uk Kim                 /*
2242*6f9291ceSJung-uk Kim                  * The client will accept a ticket but doesn't currently have
2243*6f9291ceSJung-uk Kim                  * one.
2244*6f9291ceSJung-uk Kim                  */
2245db522d3aSSimon L. B. Nielsen                 s->tlsext_ticket_expected = 1;
22461f13597dSJung-uk Kim                 return 1;
2247db522d3aSSimon L. B. Nielsen             }
2248*6f9291ceSJung-uk Kim             if (s->tls_session_secret_cb) {
2249*6f9291ceSJung-uk Kim                 /*
2250*6f9291ceSJung-uk Kim                  * Indicate that the ticket couldn't be decrypted rather than
2251*6f9291ceSJung-uk Kim                  * generating the session from ticket now, trigger
2252*6f9291ceSJung-uk Kim                  * abbreviated handshake based on external mechanism to
2253*6f9291ceSJung-uk Kim                  * calculate the master secret later.
2254*6f9291ceSJung-uk Kim                  */
22551f13597dSJung-uk Kim                 return 2;
22561f13597dSJung-uk Kim             }
22571f13597dSJung-uk Kim             r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
2258*6f9291ceSJung-uk Kim             switch (r) {
22591f13597dSJung-uk Kim             case 2:            /* ticket couldn't be decrypted */
22601f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
22611f13597dSJung-uk Kim                 return 2;
22621f13597dSJung-uk Kim             case 3:            /* ticket was decrypted */
22631f13597dSJung-uk Kim                 return r;
22641f13597dSJung-uk Kim             case 4:            /* ticket decrypted but need to renew */
22651f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
22661f13597dSJung-uk Kim                 return 3;
22671f13597dSJung-uk Kim             default:           /* fatal error */
22681f13597dSJung-uk Kim                 return -1;
22691f13597dSJung-uk Kim             }
2270db522d3aSSimon L. B. Nielsen         }
2271db522d3aSSimon L. B. Nielsen         p += size;
2272db522d3aSSimon L. B. Nielsen     }
22731f13597dSJung-uk Kim     return 0;
2274db522d3aSSimon L. B. Nielsen }
2275db522d3aSSimon L. B. Nielsen 
2276*6f9291ceSJung-uk Kim /*-
2277*6f9291ceSJung-uk Kim  * tls_decrypt_ticket attempts to decrypt a session ticket.
22781f13597dSJung-uk Kim  *
22791f13597dSJung-uk Kim  *   etick: points to the body of the session ticket extension.
22801f13597dSJung-uk Kim  *   eticklen: the length of the session tickets extenion.
22811f13597dSJung-uk Kim  *   sess_id: points at the session ID.
22821f13597dSJung-uk Kim  *   sesslen: the length of the session ID.
22831f13597dSJung-uk Kim  *   psess: (output) on return, if a ticket was decrypted, then this is set to
22841f13597dSJung-uk Kim  *       point to the resulting session.
22851f13597dSJung-uk Kim  *
22861f13597dSJung-uk Kim  * Returns:
22871f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
22881f13597dSJung-uk Kim  *    2: the ticket couldn't be decrypted.
22891f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *psess was set.
22901f13597dSJung-uk Kim  *    4: same as 3, but the ticket needs to be renewed.
22911f13597dSJung-uk Kim  */
2292*6f9291ceSJung-uk Kim static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
2293*6f9291ceSJung-uk Kim                               int eticklen, const unsigned char *sess_id,
2294*6f9291ceSJung-uk Kim                               int sesslen, SSL_SESSION **psess)
2295db522d3aSSimon L. B. Nielsen {
2296db522d3aSSimon L. B. Nielsen     SSL_SESSION *sess;
2297db522d3aSSimon L. B. Nielsen     unsigned char *sdec;
2298db522d3aSSimon L. B. Nielsen     const unsigned char *p;
2299db522d3aSSimon L. B. Nielsen     int slen, mlen, renew_ticket = 0;
2300db522d3aSSimon L. B. Nielsen     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
2301db522d3aSSimon L. B. Nielsen     HMAC_CTX hctx;
2302db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX ctx;
23036a599222SSimon L. B. Nielsen     SSL_CTX *tctx = s->initial_ctx;
2304db522d3aSSimon L. B. Nielsen     /* Need at least keyname + iv + some encrypted data */
2305db522d3aSSimon L. B. Nielsen     if (eticklen < 48)
23061f13597dSJung-uk Kim         return 2;
2307db522d3aSSimon L. B. Nielsen     /* Initialize session ticket encryption and HMAC contexts */
2308db522d3aSSimon L. B. Nielsen     HMAC_CTX_init(&hctx);
2309db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_init(&ctx);
2310*6f9291ceSJung-uk Kim     if (tctx->tlsext_ticket_key_cb) {
2311db522d3aSSimon L. B. Nielsen         unsigned char *nctick = (unsigned char *)etick;
23126a599222SSimon L. B. Nielsen         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
2313db522d3aSSimon L. B. Nielsen                                             &ctx, &hctx, 0);
2314db522d3aSSimon L. B. Nielsen         if (rv < 0)
2315db522d3aSSimon L. B. Nielsen             return -1;
2316db522d3aSSimon L. B. Nielsen         if (rv == 0)
23171f13597dSJung-uk Kim             return 2;
2318db522d3aSSimon L. B. Nielsen         if (rv == 2)
2319db522d3aSSimon L. B. Nielsen             renew_ticket = 1;
2320*6f9291ceSJung-uk Kim     } else {
2321db522d3aSSimon L. B. Nielsen         /* Check key name matches */
23226a599222SSimon L. B. Nielsen         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
23231f13597dSJung-uk Kim             return 2;
23246a599222SSimon L. B. Nielsen         HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
2325db522d3aSSimon L. B. Nielsen                      tlsext_tick_md(), NULL);
2326db522d3aSSimon L. B. Nielsen         EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
23276a599222SSimon L. B. Nielsen                            tctx->tlsext_tick_aes_key, etick + 16);
2328db522d3aSSimon L. B. Nielsen     }
2329*6f9291ceSJung-uk Kim     /*
2330*6f9291ceSJung-uk Kim      * Attempt to process session ticket, first conduct sanity and integrity
2331*6f9291ceSJung-uk Kim      * checks on ticket.
2332db522d3aSSimon L. B. Nielsen      */
2333db522d3aSSimon L. B. Nielsen     mlen = HMAC_size(&hctx);
2334*6f9291ceSJung-uk Kim     if (mlen < 0) {
23351f13597dSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
23361f13597dSJung-uk Kim         return -1;
23371f13597dSJung-uk Kim     }
2338db522d3aSSimon L. B. Nielsen     eticklen -= mlen;
2339db522d3aSSimon L. B. Nielsen     /* Check HMAC of encrypted ticket */
2340db522d3aSSimon L. B. Nielsen     HMAC_Update(&hctx, etick, eticklen);
2341db522d3aSSimon L. B. Nielsen     HMAC_Final(&hctx, tick_hmac, NULL);
2342db522d3aSSimon L. B. Nielsen     HMAC_CTX_cleanup(&hctx);
2343*6f9291ceSJung-uk Kim     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
2344fa5fddf1SJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
23451f13597dSJung-uk Kim         return 2;
2346fa5fddf1SJung-uk Kim     }
2347db522d3aSSimon L. B. Nielsen     /* Attempt to decrypt session data */
2348db522d3aSSimon L. B. Nielsen     /* Move p after IV to start of encrypted ticket, update length */
2349db522d3aSSimon L. B. Nielsen     p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
2350db522d3aSSimon L. B. Nielsen     eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
2351db522d3aSSimon L. B. Nielsen     sdec = OPENSSL_malloc(eticklen);
2352*6f9291ceSJung-uk Kim     if (!sdec) {
2353db522d3aSSimon L. B. Nielsen         EVP_CIPHER_CTX_cleanup(&ctx);
2354db522d3aSSimon L. B. Nielsen         return -1;
2355db522d3aSSimon L. B. Nielsen     }
2356db522d3aSSimon L. B. Nielsen     EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
2357*6f9291ceSJung-uk Kim     if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
2358a93cbc2bSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
2359a93cbc2bSJung-uk Kim         OPENSSL_free(sdec);
23601f13597dSJung-uk Kim         return 2;
2361a93cbc2bSJung-uk Kim     }
2362db522d3aSSimon L. B. Nielsen     slen += mlen;
2363db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_cleanup(&ctx);
2364db522d3aSSimon L. B. Nielsen     p = sdec;
2365db522d3aSSimon L. B. Nielsen 
2366db522d3aSSimon L. B. Nielsen     sess = d2i_SSL_SESSION(NULL, &p, slen);
2367db522d3aSSimon L. B. Nielsen     OPENSSL_free(sdec);
2368*6f9291ceSJung-uk Kim     if (sess) {
2369*6f9291ceSJung-uk Kim         /*
2370*6f9291ceSJung-uk Kim          * The session ID, if non-empty, is used by some clients to detect
2371*6f9291ceSJung-uk Kim          * that the ticket has been accepted. So we copy it to the session
2372*6f9291ceSJung-uk Kim          * structure. If it is empty set length to zero as required by
2373*6f9291ceSJung-uk Kim          * standard.
2374db522d3aSSimon L. B. Nielsen          */
2375db522d3aSSimon L. B. Nielsen         if (sesslen)
2376db522d3aSSimon L. B. Nielsen             memcpy(sess->session_id, sess_id, sesslen);
2377db522d3aSSimon L. B. Nielsen         sess->session_id_length = sesslen;
2378db522d3aSSimon L. B. Nielsen         *psess = sess;
23791f13597dSJung-uk Kim         if (renew_ticket)
23801f13597dSJung-uk Kim             return 4;
23811f13597dSJung-uk Kim         else
23821f13597dSJung-uk Kim             return 3;
23831f13597dSJung-uk Kim     }
23841f13597dSJung-uk Kim     ERR_clear_error();
2385*6f9291ceSJung-uk Kim     /*
2386*6f9291ceSJung-uk Kim      * For session parse failure, indicate that we need to send a new ticket.
2387*6f9291ceSJung-uk Kim      */
23881f13597dSJung-uk Kim     return 2;
23891f13597dSJung-uk Kim }
23901f13597dSJung-uk Kim 
23911f13597dSJung-uk Kim /* Tables to translate from NIDs to TLS v1.2 ids */
23921f13597dSJung-uk Kim 
2393*6f9291ceSJung-uk Kim typedef struct {
23941f13597dSJung-uk Kim     int nid;
23951f13597dSJung-uk Kim     int id;
23961f13597dSJung-uk Kim } tls12_lookup;
23971f13597dSJung-uk Kim 
23981f13597dSJung-uk Kim static tls12_lookup tls12_md[] = {
23991f13597dSJung-uk Kim # ifndef OPENSSL_NO_MD5
24001f13597dSJung-uk Kim     {NID_md5, TLSEXT_hash_md5},
24011f13597dSJung-uk Kim # endif
24021f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
24031f13597dSJung-uk Kim     {NID_sha1, TLSEXT_hash_sha1},
24041f13597dSJung-uk Kim # endif
24051f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
24061f13597dSJung-uk Kim     {NID_sha224, TLSEXT_hash_sha224},
24071f13597dSJung-uk Kim     {NID_sha256, TLSEXT_hash_sha256},
24081f13597dSJung-uk Kim # endif
24091f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
24101f13597dSJung-uk Kim     {NID_sha384, TLSEXT_hash_sha384},
24111f13597dSJung-uk Kim     {NID_sha512, TLSEXT_hash_sha512}
24121f13597dSJung-uk Kim # endif
24131f13597dSJung-uk Kim };
24141f13597dSJung-uk Kim 
24151f13597dSJung-uk Kim static tls12_lookup tls12_sig[] = {
24161f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA
24171f13597dSJung-uk Kim     {EVP_PKEY_RSA, TLSEXT_signature_rsa},
24181f13597dSJung-uk Kim # endif
24191f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA
24201f13597dSJung-uk Kim     {EVP_PKEY_DSA, TLSEXT_signature_dsa},
24211f13597dSJung-uk Kim # endif
24221f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
24231f13597dSJung-uk Kim     {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
24241f13597dSJung-uk Kim # endif
24251f13597dSJung-uk Kim };
24261f13597dSJung-uk Kim 
24271f13597dSJung-uk Kim static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
24281f13597dSJung-uk Kim {
24291f13597dSJung-uk Kim     size_t i;
2430*6f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
24311f13597dSJung-uk Kim         if (table[i].nid == nid)
24321f13597dSJung-uk Kim             return table[i].id;
24331f13597dSJung-uk Kim     }
24341f13597dSJung-uk Kim     return -1;
24351f13597dSJung-uk Kim }
2436*6f9291ceSJung-uk Kim 
24371f13597dSJung-uk Kim # if 0
24381f13597dSJung-uk Kim static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
24391f13597dSJung-uk Kim {
24401f13597dSJung-uk Kim     size_t i;
2441*6f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
24421f13597dSJung-uk Kim         if (table[i].id == id)
24431f13597dSJung-uk Kim             return table[i].nid;
24441f13597dSJung-uk Kim     }
24451f13597dSJung-uk Kim     return -1;
24461f13597dSJung-uk Kim }
24471f13597dSJung-uk Kim # endif
24481f13597dSJung-uk Kim 
2449*6f9291ceSJung-uk Kim int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
2450*6f9291ceSJung-uk Kim                          const EVP_MD *md)
24511f13597dSJung-uk Kim {
24521f13597dSJung-uk Kim     int sig_id, md_id;
24531f13597dSJung-uk Kim     if (!md)
24541f13597dSJung-uk Kim         return 0;
24551f13597dSJung-uk Kim     md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
24561f13597dSJung-uk Kim                           sizeof(tls12_md) / sizeof(tls12_lookup));
24571f13597dSJung-uk Kim     if (md_id == -1)
24581f13597dSJung-uk Kim         return 0;
24591f13597dSJung-uk Kim     sig_id = tls12_get_sigid(pk);
24601f13597dSJung-uk Kim     if (sig_id == -1)
24611f13597dSJung-uk Kim         return 0;
24621f13597dSJung-uk Kim     p[0] = (unsigned char)md_id;
24631f13597dSJung-uk Kim     p[1] = (unsigned char)sig_id;
2464db522d3aSSimon L. B. Nielsen     return 1;
2465db522d3aSSimon L. B. Nielsen }
24661f13597dSJung-uk Kim 
24671f13597dSJung-uk Kim int tls12_get_sigid(const EVP_PKEY *pk)
24681f13597dSJung-uk Kim {
24691f13597dSJung-uk Kim     return tls12_find_id(pk->type, tls12_sig,
24701f13597dSJung-uk Kim                          sizeof(tls12_sig) / sizeof(tls12_lookup));
24711f13597dSJung-uk Kim }
24721f13597dSJung-uk Kim 
24731f13597dSJung-uk Kim const EVP_MD *tls12_get_hash(unsigned char hash_alg)
24741f13597dSJung-uk Kim {
2475*6f9291ceSJung-uk Kim     switch (hash_alg) {
24761f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
24771f13597dSJung-uk Kim     case TLSEXT_hash_sha1:
24781f13597dSJung-uk Kim         return EVP_sha1();
24791f13597dSJung-uk Kim # endif
24801f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
24811f13597dSJung-uk Kim     case TLSEXT_hash_sha224:
24821f13597dSJung-uk Kim         return EVP_sha224();
24831f13597dSJung-uk Kim 
24841f13597dSJung-uk Kim     case TLSEXT_hash_sha256:
24851f13597dSJung-uk Kim         return EVP_sha256();
24861f13597dSJung-uk Kim # endif
24871f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
24881f13597dSJung-uk Kim     case TLSEXT_hash_sha384:
24891f13597dSJung-uk Kim         return EVP_sha384();
24901f13597dSJung-uk Kim 
24911f13597dSJung-uk Kim     case TLSEXT_hash_sha512:
24921f13597dSJung-uk Kim         return EVP_sha512();
24931f13597dSJung-uk Kim # endif
24941f13597dSJung-uk Kim     default:
24951f13597dSJung-uk Kim         return NULL;
24961f13597dSJung-uk Kim 
24971f13597dSJung-uk Kim     }
24981f13597dSJung-uk Kim }
24991f13597dSJung-uk Kim 
25001f13597dSJung-uk Kim /* Set preferred digest for each key type */
25011f13597dSJung-uk Kim 
25021f13597dSJung-uk Kim int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
25031f13597dSJung-uk Kim {
25041f13597dSJung-uk Kim     int i, idx;
25051f13597dSJung-uk Kim     const EVP_MD *md;
25061f13597dSJung-uk Kim     CERT *c = s->cert;
25071f13597dSJung-uk Kim     /* Extension ignored for TLS versions below 1.2 */
25081f13597dSJung-uk Kim     if (TLS1_get_version(s) < TLS1_2_VERSION)
25091f13597dSJung-uk Kim         return 1;
25101f13597dSJung-uk Kim     /* Should never happen */
25111f13597dSJung-uk Kim     if (!c)
25121f13597dSJung-uk Kim         return 0;
25131f13597dSJung-uk Kim 
25141f13597dSJung-uk Kim     c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
25151f13597dSJung-uk Kim     c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL;
25161f13597dSJung-uk Kim     c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL;
25171f13597dSJung-uk Kim     c->pkeys[SSL_PKEY_ECC].digest = NULL;
25181f13597dSJung-uk Kim 
2519*6f9291ceSJung-uk Kim     for (i = 0; i < dsize; i += 2) {
25201f13597dSJung-uk Kim         unsigned char hash_alg = data[i], sig_alg = data[i + 1];
25211f13597dSJung-uk Kim 
2522*6f9291ceSJung-uk Kim         switch (sig_alg) {
25231f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA
25241f13597dSJung-uk Kim         case TLSEXT_signature_rsa:
25251f13597dSJung-uk Kim             idx = SSL_PKEY_RSA_SIGN;
25261f13597dSJung-uk Kim             break;
25271f13597dSJung-uk Kim # endif
25281f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA
25291f13597dSJung-uk Kim         case TLSEXT_signature_dsa:
25301f13597dSJung-uk Kim             idx = SSL_PKEY_DSA_SIGN;
25311f13597dSJung-uk Kim             break;
25321f13597dSJung-uk Kim # endif
25331f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
25341f13597dSJung-uk Kim         case TLSEXT_signature_ecdsa:
25351f13597dSJung-uk Kim             idx = SSL_PKEY_ECC;
25361f13597dSJung-uk Kim             break;
25371f13597dSJung-uk Kim # endif
25381f13597dSJung-uk Kim         default:
25391f13597dSJung-uk Kim             continue;
25401f13597dSJung-uk Kim         }
25411f13597dSJung-uk Kim 
2542*6f9291ceSJung-uk Kim         if (c->pkeys[idx].digest == NULL) {
25431f13597dSJung-uk Kim             md = tls12_get_hash(hash_alg);
2544*6f9291ceSJung-uk Kim             if (md) {
25451f13597dSJung-uk Kim                 c->pkeys[idx].digest = md;
25461f13597dSJung-uk Kim                 if (idx == SSL_PKEY_RSA_SIGN)
25471f13597dSJung-uk Kim                     c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
25481f13597dSJung-uk Kim             }
25491f13597dSJung-uk Kim         }
25501f13597dSJung-uk Kim 
25511f13597dSJung-uk Kim     }
25521f13597dSJung-uk Kim 
2553*6f9291ceSJung-uk Kim     /*
2554*6f9291ceSJung-uk Kim      * Set any remaining keys to default values. NOTE: if alg is not
25551f13597dSJung-uk Kim      * supported it stays as NULL.
2556db522d3aSSimon L. B. Nielsen      */
25571f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA
25581f13597dSJung-uk Kim     if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
255909286989SJung-uk Kim         c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
25601f13597dSJung-uk Kim # endif
25611f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA
2562*6f9291ceSJung-uk Kim     if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
25631f13597dSJung-uk Kim         c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
25641f13597dSJung-uk Kim         c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
25651f13597dSJung-uk Kim     }
25661f13597dSJung-uk Kim # endif
25671f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
25681f13597dSJung-uk Kim     if (!c->pkeys[SSL_PKEY_ECC].digest)
256909286989SJung-uk Kim         c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
25701f13597dSJung-uk Kim # endif
25711f13597dSJung-uk Kim     return 1;
25721f13597dSJung-uk Kim }
25731f13597dSJung-uk Kim 
25741f13597dSJung-uk Kim #endif
25751f13597dSJung-uk Kim 
25761f13597dSJung-uk Kim #ifndef OPENSSL_NO_HEARTBEATS
2577*6f9291ceSJung-uk Kim int tls1_process_heartbeat(SSL *s)
25781f13597dSJung-uk Kim {
25791f13597dSJung-uk Kim     unsigned char *p = &s->s3->rrec.data[0], *pl;
25801f13597dSJung-uk Kim     unsigned short hbtype;
25811f13597dSJung-uk Kim     unsigned int payload;
25821f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
25831f13597dSJung-uk Kim 
25841f13597dSJung-uk Kim     if (s->msg_callback)
25851f13597dSJung-uk Kim         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
25861f13597dSJung-uk Kim                         &s->s3->rrec.data[0], s->s3->rrec.length,
25871f13597dSJung-uk Kim                         s, s->msg_callback_arg);
25881f13597dSJung-uk Kim 
258925bfde79SXin LI     /* Read type and payload length first */
259025bfde79SXin LI     if (1 + 2 + 16 > s->s3->rrec.length)
259125bfde79SXin LI         return 0;               /* silently discard */
259225bfde79SXin LI     hbtype = *p++;
259325bfde79SXin LI     n2s(p, payload);
259425bfde79SXin LI     if (1 + 2 + payload + 16 > s->s3->rrec.length)
259525bfde79SXin LI         return 0;               /* silently discard per RFC 6520 sec. 4 */
259625bfde79SXin LI     pl = p;
259725bfde79SXin LI 
2598*6f9291ceSJung-uk Kim     if (hbtype == TLS1_HB_REQUEST) {
25991f13597dSJung-uk Kim         unsigned char *buffer, *bp;
26001f13597dSJung-uk Kim         int r;
26011f13597dSJung-uk Kim 
2602*6f9291ceSJung-uk Kim         /*
2603*6f9291ceSJung-uk Kim          * Allocate memory for the response, size is 1 bytes message type,
2604*6f9291ceSJung-uk Kim          * plus 2 bytes payload length, plus payload, plus padding
26051f13597dSJung-uk Kim          */
26061f13597dSJung-uk Kim         buffer = OPENSSL_malloc(1 + 2 + payload + padding);
26071f13597dSJung-uk Kim         bp = buffer;
26081f13597dSJung-uk Kim 
26091f13597dSJung-uk Kim         /* Enter response type, length and copy payload */
26101f13597dSJung-uk Kim         *bp++ = TLS1_HB_RESPONSE;
26111f13597dSJung-uk Kim         s2n(payload, bp);
26121f13597dSJung-uk Kim         memcpy(bp, pl, payload);
26131f13597dSJung-uk Kim         bp += payload;
26141f13597dSJung-uk Kim         /* Random padding */
26151f13597dSJung-uk Kim         RAND_pseudo_bytes(bp, padding);
26161f13597dSJung-uk Kim 
2617*6f9291ceSJung-uk Kim         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
2618*6f9291ceSJung-uk Kim                              3 + payload + padding);
26191f13597dSJung-uk Kim 
26201f13597dSJung-uk Kim         if (r >= 0 && s->msg_callback)
26211f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
26221f13597dSJung-uk Kim                             buffer, 3 + payload + padding,
26231f13597dSJung-uk Kim                             s, s->msg_callback_arg);
26241f13597dSJung-uk Kim 
26251f13597dSJung-uk Kim         OPENSSL_free(buffer);
26261f13597dSJung-uk Kim 
26271f13597dSJung-uk Kim         if (r < 0)
26281f13597dSJung-uk Kim             return r;
2629*6f9291ceSJung-uk Kim     } else if (hbtype == TLS1_HB_RESPONSE) {
26301f13597dSJung-uk Kim         unsigned int seq;
26311f13597dSJung-uk Kim 
2632*6f9291ceSJung-uk Kim         /*
2633*6f9291ceSJung-uk Kim          * We only send sequence numbers (2 bytes unsigned int), and 16
2634*6f9291ceSJung-uk Kim          * random bytes, so we just try to read the sequence number
2635*6f9291ceSJung-uk Kim          */
26361f13597dSJung-uk Kim         n2s(pl, seq);
26371f13597dSJung-uk Kim 
2638*6f9291ceSJung-uk Kim         if (payload == 18 && seq == s->tlsext_hb_seq) {
26391f13597dSJung-uk Kim             s->tlsext_hb_seq++;
26401f13597dSJung-uk Kim             s->tlsext_hb_pending = 0;
26411f13597dSJung-uk Kim         }
26421f13597dSJung-uk Kim     }
26431f13597dSJung-uk Kim 
2644db522d3aSSimon L. B. Nielsen     return 0;
2645db522d3aSSimon L. B. Nielsen }
2646db522d3aSSimon L. B. Nielsen 
2647*6f9291ceSJung-uk Kim int tls1_heartbeat(SSL *s)
26481f13597dSJung-uk Kim {
26491f13597dSJung-uk Kim     unsigned char *buf, *p;
26501f13597dSJung-uk Kim     int ret;
26511f13597dSJung-uk Kim     unsigned int payload = 18;  /* Sequence number + random bytes */
26521f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
26531f13597dSJung-uk Kim 
26541f13597dSJung-uk Kim     /* Only send if peer supports and accepts HB requests... */
26551f13597dSJung-uk Kim     if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
2656*6f9291ceSJung-uk Kim         s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
26571f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
26581f13597dSJung-uk Kim         return -1;
26591f13597dSJung-uk Kim     }
26601f13597dSJung-uk Kim 
26611f13597dSJung-uk Kim     /* ...and there is none in flight yet... */
2662*6f9291ceSJung-uk Kim     if (s->tlsext_hb_pending) {
26631f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
26641f13597dSJung-uk Kim         return -1;
26651f13597dSJung-uk Kim     }
26661f13597dSJung-uk Kim 
26671f13597dSJung-uk Kim     /* ...and no handshake in progress. */
2668*6f9291ceSJung-uk Kim     if (SSL_in_init(s) || s->in_handshake) {
26691f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
26701f13597dSJung-uk Kim         return -1;
26711f13597dSJung-uk Kim     }
26721f13597dSJung-uk Kim 
2673*6f9291ceSJung-uk Kim     /*
2674*6f9291ceSJung-uk Kim      * Check if padding is too long, payload and padding must not exceed 2^14
2675*6f9291ceSJung-uk Kim      * - 3 = 16381 bytes in total.
26761f13597dSJung-uk Kim      */
26771f13597dSJung-uk Kim     OPENSSL_assert(payload + padding <= 16381);
26781f13597dSJung-uk Kim 
2679*6f9291ceSJung-uk Kim     /*-
2680*6f9291ceSJung-uk Kim      * Create HeartBeat message, we just use a sequence number
26811f13597dSJung-uk Kim      * as payload to distuingish different messages and add
26821f13597dSJung-uk Kim      * some random stuff.
26831f13597dSJung-uk Kim      *  - Message Type, 1 byte
26841f13597dSJung-uk Kim      *  - Payload Length, 2 bytes (unsigned int)
26851f13597dSJung-uk Kim      *  - Payload, the sequence number (2 bytes uint)
26861f13597dSJung-uk Kim      *  - Payload, random bytes (16 bytes uint)
26871f13597dSJung-uk Kim      *  - Padding
26881f13597dSJung-uk Kim      */
26891f13597dSJung-uk Kim     buf = OPENSSL_malloc(1 + 2 + payload + padding);
26901f13597dSJung-uk Kim     p = buf;
26911f13597dSJung-uk Kim     /* Message Type */
26921f13597dSJung-uk Kim     *p++ = TLS1_HB_REQUEST;
26931f13597dSJung-uk Kim     /* Payload length (18 bytes here) */
26941f13597dSJung-uk Kim     s2n(payload, p);
26951f13597dSJung-uk Kim     /* Sequence number */
26961f13597dSJung-uk Kim     s2n(s->tlsext_hb_seq, p);
26971f13597dSJung-uk Kim     /* 16 random bytes */
26981f13597dSJung-uk Kim     RAND_pseudo_bytes(p, 16);
26991f13597dSJung-uk Kim     p += 16;
27001f13597dSJung-uk Kim     /* Random padding */
27011f13597dSJung-uk Kim     RAND_pseudo_bytes(p, padding);
27021f13597dSJung-uk Kim 
27031f13597dSJung-uk Kim     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
2704*6f9291ceSJung-uk Kim     if (ret >= 0) {
27051f13597dSJung-uk Kim         if (s->msg_callback)
27061f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
27071f13597dSJung-uk Kim                             buf, 3 + payload + padding,
27081f13597dSJung-uk Kim                             s, s->msg_callback_arg);
27091f13597dSJung-uk Kim 
27101f13597dSJung-uk Kim         s->tlsext_hb_pending = 1;
27111f13597dSJung-uk Kim     }
27121f13597dSJung-uk Kim 
27131f13597dSJung-uk Kim     OPENSSL_free(buf);
27141f13597dSJung-uk Kim 
27151f13597dSJung-uk Kim     return ret;
27161f13597dSJung-uk Kim }
2717db522d3aSSimon L. B. Nielsen #endif
2718