xref: /freebsd/crypto/openssl/ssl/t1_lib.c (revision dee36b4f92f269b95977ae9c4a37046fb7cc351c)
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 /* ====================================================================
59*dee36b4fSJung-uk Kim  * Copyright (c) 1998-2018 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>
1167bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
1177bded2dbSJung-uk Kim #ifdef OPENSSL_NO_EC2M
1187bded2dbSJung-uk Kim # include <openssl/ec.h>
1197bded2dbSJung-uk Kim #endif
1207bded2dbSJung-uk Kim #endif
121db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h>
1221f13597dSJung-uk Kim #include <openssl/rand.h>
12374664626SKris Kennaway #include "ssl_locl.h"
12474664626SKris Kennaway 
1255471f83eSSimon L. B. Nielsen const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT;
12674664626SKris Kennaway 
127db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
128db522d3aSSimon L. B. Nielsen static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
129db522d3aSSimon L. B. Nielsen                               const unsigned char *sess_id, int sesslen,
130db522d3aSSimon L. B. Nielsen                               SSL_SESSION **psess);
1317bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s);
1327bded2dbSJung-uk Kim int ssl_check_serverhello_tlsext(SSL *s);
133db522d3aSSimon L. B. Nielsen #endif
134db522d3aSSimon L. B. Nielsen 
1356cf8931aSJung-uk Kim #define CHECKLEN(curr, val, limit) \
1366cf8931aSJung-uk Kim     (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))
1376cf8931aSJung-uk Kim 
1383b4e3dcbSSimon L. B. Nielsen SSL3_ENC_METHOD TLSv1_enc_data = {
13974664626SKris Kennaway     tls1_enc,
14074664626SKris Kennaway     tls1_mac,
14174664626SKris Kennaway     tls1_setup_key_block,
14274664626SKris Kennaway     tls1_generate_master_secret,
14374664626SKris Kennaway     tls1_change_cipher_state,
14474664626SKris Kennaway     tls1_final_finish_mac,
14574664626SKris Kennaway     TLS1_FINISH_MAC_LENGTH,
14674664626SKris Kennaway     tls1_cert_verify_mac,
14774664626SKris Kennaway     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
14874664626SKris Kennaway     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
14974664626SKris Kennaway     tls1_alert_code,
1501f13597dSJung-uk Kim     tls1_export_keying_material,
1517bded2dbSJung-uk Kim     0,
1527bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
1537bded2dbSJung-uk Kim     ssl3_set_handshake_header,
1547bded2dbSJung-uk Kim     ssl3_handshake_write
1557bded2dbSJung-uk Kim };
1567bded2dbSJung-uk Kim 
1577bded2dbSJung-uk Kim SSL3_ENC_METHOD TLSv1_1_enc_data = {
1587bded2dbSJung-uk Kim     tls1_enc,
1597bded2dbSJung-uk Kim     tls1_mac,
1607bded2dbSJung-uk Kim     tls1_setup_key_block,
1617bded2dbSJung-uk Kim     tls1_generate_master_secret,
1627bded2dbSJung-uk Kim     tls1_change_cipher_state,
1637bded2dbSJung-uk Kim     tls1_final_finish_mac,
1647bded2dbSJung-uk Kim     TLS1_FINISH_MAC_LENGTH,
1657bded2dbSJung-uk Kim     tls1_cert_verify_mac,
1667bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
1677bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
1687bded2dbSJung-uk Kim     tls1_alert_code,
1697bded2dbSJung-uk Kim     tls1_export_keying_material,
1707bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV,
1717bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
1727bded2dbSJung-uk Kim     ssl3_set_handshake_header,
1737bded2dbSJung-uk Kim     ssl3_handshake_write
1747bded2dbSJung-uk Kim };
1757bded2dbSJung-uk Kim 
1767bded2dbSJung-uk Kim SSL3_ENC_METHOD TLSv1_2_enc_data = {
1777bded2dbSJung-uk Kim     tls1_enc,
1787bded2dbSJung-uk Kim     tls1_mac,
1797bded2dbSJung-uk Kim     tls1_setup_key_block,
1807bded2dbSJung-uk Kim     tls1_generate_master_secret,
1817bded2dbSJung-uk Kim     tls1_change_cipher_state,
1827bded2dbSJung-uk Kim     tls1_final_finish_mac,
1837bded2dbSJung-uk Kim     TLS1_FINISH_MAC_LENGTH,
1847bded2dbSJung-uk Kim     tls1_cert_verify_mac,
1857bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
1867bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
1877bded2dbSJung-uk Kim     tls1_alert_code,
1887bded2dbSJung-uk Kim     tls1_export_keying_material,
1897bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
1907bded2dbSJung-uk Kim         | SSL_ENC_FLAG_TLS1_2_CIPHERS,
1917bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
1927bded2dbSJung-uk Kim     ssl3_set_handshake_header,
1937bded2dbSJung-uk Kim     ssl3_handshake_write
19474664626SKris Kennaway };
19574664626SKris Kennaway 
1963b4e3dcbSSimon L. B. Nielsen long tls1_default_timeout(void)
19774664626SKris Kennaway {
1986f9291ceSJung-uk Kim     /*
1996f9291ceSJung-uk Kim      * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for
2006f9291ceSJung-uk Kim      * http, the cache would over fill
2016f9291ceSJung-uk Kim      */
20274664626SKris Kennaway     return (60 * 60 * 2);
20374664626SKris Kennaway }
20474664626SKris Kennaway 
20574664626SKris Kennaway int tls1_new(SSL *s)
20674664626SKris Kennaway {
2076f9291ceSJung-uk Kim     if (!ssl3_new(s))
2086f9291ceSJung-uk Kim         return (0);
20974664626SKris Kennaway     s->method->ssl_clear(s);
21074664626SKris Kennaway     return (1);
21174664626SKris Kennaway }
21274664626SKris Kennaway 
21374664626SKris Kennaway void tls1_free(SSL *s)
21474664626SKris Kennaway {
2151f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
2166f9291ceSJung-uk Kim     if (s->tlsext_session_ticket) {
2171f13597dSJung-uk Kim         OPENSSL_free(s->tlsext_session_ticket);
2181f13597dSJung-uk Kim     }
2191f13597dSJung-uk Kim #endif                          /* OPENSSL_NO_TLSEXT */
22074664626SKris Kennaway     ssl3_free(s);
22174664626SKris Kennaway }
22274664626SKris Kennaway 
22374664626SKris Kennaway void tls1_clear(SSL *s)
22474664626SKris Kennaway {
22574664626SKris Kennaway     ssl3_clear(s);
2261f13597dSJung-uk Kim     s->version = s->method->version;
22774664626SKris Kennaway }
22874664626SKris Kennaway 
2291f13597dSJung-uk Kim #ifndef OPENSSL_NO_EC
2301f13597dSJung-uk Kim 
2316f9291ceSJung-uk Kim static int nid_list[] = {
2321f13597dSJung-uk Kim     NID_sect163k1,              /* sect163k1 (1) */
2331f13597dSJung-uk Kim     NID_sect163r1,              /* sect163r1 (2) */
2341f13597dSJung-uk Kim     NID_sect163r2,              /* sect163r2 (3) */
2351f13597dSJung-uk Kim     NID_sect193r1,              /* sect193r1 (4) */
2361f13597dSJung-uk Kim     NID_sect193r2,              /* sect193r2 (5) */
2371f13597dSJung-uk Kim     NID_sect233k1,              /* sect233k1 (6) */
2381f13597dSJung-uk Kim     NID_sect233r1,              /* sect233r1 (7) */
2391f13597dSJung-uk Kim     NID_sect239k1,              /* sect239k1 (8) */
2401f13597dSJung-uk Kim     NID_sect283k1,              /* sect283k1 (9) */
2411f13597dSJung-uk Kim     NID_sect283r1,              /* sect283r1 (10) */
2421f13597dSJung-uk Kim     NID_sect409k1,              /* sect409k1 (11) */
2431f13597dSJung-uk Kim     NID_sect409r1,              /* sect409r1 (12) */
2441f13597dSJung-uk Kim     NID_sect571k1,              /* sect571k1 (13) */
2451f13597dSJung-uk Kim     NID_sect571r1,              /* sect571r1 (14) */
2461f13597dSJung-uk Kim     NID_secp160k1,              /* secp160k1 (15) */
2471f13597dSJung-uk Kim     NID_secp160r1,              /* secp160r1 (16) */
2481f13597dSJung-uk Kim     NID_secp160r2,              /* secp160r2 (17) */
2491f13597dSJung-uk Kim     NID_secp192k1,              /* secp192k1 (18) */
2501f13597dSJung-uk Kim     NID_X9_62_prime192v1,       /* secp192r1 (19) */
2511f13597dSJung-uk Kim     NID_secp224k1,              /* secp224k1 (20) */
2521f13597dSJung-uk Kim     NID_secp224r1,              /* secp224r1 (21) */
2531f13597dSJung-uk Kim     NID_secp256k1,              /* secp256k1 (22) */
2541f13597dSJung-uk Kim     NID_X9_62_prime256v1,       /* secp256r1 (23) */
2551f13597dSJung-uk Kim     NID_secp384r1,              /* secp384r1 (24) */
2567bded2dbSJung-uk Kim     NID_secp521r1,              /* secp521r1 (25) */
2577bded2dbSJung-uk Kim     NID_brainpoolP256r1,        /* brainpoolP256r1 (26) */
2587bded2dbSJung-uk Kim     NID_brainpoolP384r1,        /* brainpoolP384r1 (27) */
2597bded2dbSJung-uk Kim     NID_brainpoolP512r1         /* brainpool512r1 (28) */
2601f13597dSJung-uk Kim };
2611f13597dSJung-uk Kim 
2627bded2dbSJung-uk Kim static const unsigned char ecformats_default[] = {
2637bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_uncompressed,
2647bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
2657bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
2661f13597dSJung-uk Kim };
2671f13597dSJung-uk Kim 
2687bded2dbSJung-uk Kim /* The client's default curves / the server's 'auto' curves. */
2697bded2dbSJung-uk Kim static const unsigned char eccurves_auto[] = {
2707bded2dbSJung-uk Kim     /* Prefer P-256 which has the fastest and most secure implementations. */
2717bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
2727bded2dbSJung-uk Kim     /* Other >= 256-bit prime curves. */
2737bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
2747bded2dbSJung-uk Kim     0, 28,                      /* brainpool512r1 (28) */
2757bded2dbSJung-uk Kim     0, 27,                      /* brainpoolP384r1 (27) */
2767bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
2777bded2dbSJung-uk Kim     0, 26,                      /* brainpoolP256r1 (26) */
2787bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
2797bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
2807bded2dbSJung-uk Kim     /* >= 256-bit binary curves. */
2817bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
2827bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
2837bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
2847bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
2857bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
2867bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
2877bded2dbSJung-uk Kim # endif
2887bded2dbSJung-uk Kim };
2897bded2dbSJung-uk Kim 
2907bded2dbSJung-uk Kim static const unsigned char eccurves_all[] = {
2917bded2dbSJung-uk Kim     /* Prefer P-256 which has the fastest and most secure implementations. */
2927bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
2937bded2dbSJung-uk Kim     /* Other >= 256-bit prime curves. */
2947bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
2957bded2dbSJung-uk Kim     0, 28,                      /* brainpool512r1 (28) */
2967bded2dbSJung-uk Kim     0, 27,                      /* brainpoolP384r1 (27) */
2977bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
2987bded2dbSJung-uk Kim     0, 26,                      /* brainpoolP256r1 (26) */
2997bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
3007bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
3017bded2dbSJung-uk Kim     /* >= 256-bit binary curves. */
3027bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
3037bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
3047bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
3057bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
3067bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
3077bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
3087bded2dbSJung-uk Kim # endif
3097bded2dbSJung-uk Kim     /*
3107bded2dbSJung-uk Kim      * Remaining curves disabled by default but still permitted if set
3117bded2dbSJung-uk Kim      * via an explicit callback or parameters.
3127bded2dbSJung-uk Kim      */
3137bded2dbSJung-uk Kim     0, 20,                      /* secp224k1 (20) */
3147bded2dbSJung-uk Kim     0, 21,                      /* secp224r1 (21) */
3157bded2dbSJung-uk Kim     0, 18,                      /* secp192k1 (18) */
3167bded2dbSJung-uk Kim     0, 19,                      /* secp192r1 (19) */
3177bded2dbSJung-uk Kim     0, 15,                      /* secp160k1 (15) */
3187bded2dbSJung-uk Kim     0, 16,                      /* secp160r1 (16) */
3197bded2dbSJung-uk Kim     0, 17,                      /* secp160r2 (17) */
3207bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
3217bded2dbSJung-uk Kim     0, 8,                       /* sect239k1 (8) */
3227bded2dbSJung-uk Kim     0, 6,                       /* sect233k1 (6) */
3237bded2dbSJung-uk Kim     0, 7,                       /* sect233r1 (7) */
3247bded2dbSJung-uk Kim     0, 4,                       /* sect193r1 (4) */
3257bded2dbSJung-uk Kim     0, 5,                       /* sect193r2 (5) */
3267bded2dbSJung-uk Kim     0, 1,                       /* sect163k1 (1) */
3277bded2dbSJung-uk Kim     0, 2,                       /* sect163r1 (2) */
3287bded2dbSJung-uk Kim     0, 3,                       /* sect163r2 (3) */
3297bded2dbSJung-uk Kim # endif
3307bded2dbSJung-uk Kim };
3317bded2dbSJung-uk Kim 
3327bded2dbSJung-uk Kim static const unsigned char suiteb_curves[] = {
3337bded2dbSJung-uk Kim     0, TLSEXT_curve_P_256,
3347bded2dbSJung-uk Kim     0, TLSEXT_curve_P_384
3357bded2dbSJung-uk Kim };
3367bded2dbSJung-uk Kim 
3377bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
3387bded2dbSJung-uk Kim /* Brainpool not allowed in FIPS mode */
3397bded2dbSJung-uk Kim static const unsigned char fips_curves_default[] = {
3407bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3417bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
3427bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
3437bded2dbSJung-uk Kim #  endif
3447bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
3457bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3467bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
3477bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
3487bded2dbSJung-uk Kim #  endif
3497bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
3507bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3517bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
3527bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
3537bded2dbSJung-uk Kim #  endif
3547bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
3557bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
3567bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3577bded2dbSJung-uk Kim     0, 8,                       /* sect239k1 (8) */
3587bded2dbSJung-uk Kim     0, 6,                       /* sect233k1 (6) */
3597bded2dbSJung-uk Kim     0, 7,                       /* sect233r1 (7) */
3607bded2dbSJung-uk Kim #  endif
3617bded2dbSJung-uk Kim     0, 20,                      /* secp224k1 (20) */
3627bded2dbSJung-uk Kim     0, 21,                      /* secp224r1 (21) */
3637bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3647bded2dbSJung-uk Kim     0, 4,                       /* sect193r1 (4) */
3657bded2dbSJung-uk Kim     0, 5,                       /* sect193r2 (5) */
3667bded2dbSJung-uk Kim #  endif
3677bded2dbSJung-uk Kim     0, 18,                      /* secp192k1 (18) */
3687bded2dbSJung-uk Kim     0, 19,                      /* secp192r1 (19) */
3697bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3707bded2dbSJung-uk Kim     0, 1,                       /* sect163k1 (1) */
3717bded2dbSJung-uk Kim     0, 2,                       /* sect163r1 (2) */
3727bded2dbSJung-uk Kim     0, 3,                       /* sect163r2 (3) */
3737bded2dbSJung-uk Kim #  endif
3747bded2dbSJung-uk Kim     0, 15,                      /* secp160k1 (15) */
3757bded2dbSJung-uk Kim     0, 16,                      /* secp160r1 (16) */
3767bded2dbSJung-uk Kim     0, 17,                      /* secp160r2 (17) */
3777bded2dbSJung-uk Kim };
3787bded2dbSJung-uk Kim # endif
3797bded2dbSJung-uk Kim 
3801f13597dSJung-uk Kim int tls1_ec_curve_id2nid(int curve_id)
3811f13597dSJung-uk Kim {
3827bded2dbSJung-uk Kim     /* ECC curves from RFC 4492 and RFC 7027 */
3831f13597dSJung-uk Kim     if ((curve_id < 1) || ((unsigned int)curve_id >
3841f13597dSJung-uk Kim                            sizeof(nid_list) / sizeof(nid_list[0])))
3851f13597dSJung-uk Kim         return 0;
3861f13597dSJung-uk Kim     return nid_list[curve_id - 1];
38774664626SKris Kennaway }
388f579bf8eSKris Kennaway 
3891f13597dSJung-uk Kim int tls1_ec_nid2curve_id(int nid)
390f579bf8eSKris Kennaway {
3917bded2dbSJung-uk Kim     /* ECC curves from RFC 4492 and RFC 7027 */
3926f9291ceSJung-uk Kim     switch (nid) {
3931f13597dSJung-uk Kim     case NID_sect163k1:        /* sect163k1 (1) */
3941f13597dSJung-uk Kim         return 1;
3951f13597dSJung-uk Kim     case NID_sect163r1:        /* sect163r1 (2) */
3961f13597dSJung-uk Kim         return 2;
3971f13597dSJung-uk Kim     case NID_sect163r2:        /* sect163r2 (3) */
3981f13597dSJung-uk Kim         return 3;
3991f13597dSJung-uk Kim     case NID_sect193r1:        /* sect193r1 (4) */
4001f13597dSJung-uk Kim         return 4;
4011f13597dSJung-uk Kim     case NID_sect193r2:        /* sect193r2 (5) */
4021f13597dSJung-uk Kim         return 5;
4031f13597dSJung-uk Kim     case NID_sect233k1:        /* sect233k1 (6) */
4041f13597dSJung-uk Kim         return 6;
4051f13597dSJung-uk Kim     case NID_sect233r1:        /* sect233r1 (7) */
4061f13597dSJung-uk Kim         return 7;
4071f13597dSJung-uk Kim     case NID_sect239k1:        /* sect239k1 (8) */
4081f13597dSJung-uk Kim         return 8;
4091f13597dSJung-uk Kim     case NID_sect283k1:        /* sect283k1 (9) */
4101f13597dSJung-uk Kim         return 9;
4111f13597dSJung-uk Kim     case NID_sect283r1:        /* sect283r1 (10) */
4121f13597dSJung-uk Kim         return 10;
4131f13597dSJung-uk Kim     case NID_sect409k1:        /* sect409k1 (11) */
4141f13597dSJung-uk Kim         return 11;
4151f13597dSJung-uk Kim     case NID_sect409r1:        /* sect409r1 (12) */
4161f13597dSJung-uk Kim         return 12;
4171f13597dSJung-uk Kim     case NID_sect571k1:        /* sect571k1 (13) */
4181f13597dSJung-uk Kim         return 13;
4191f13597dSJung-uk Kim     case NID_sect571r1:        /* sect571r1 (14) */
4201f13597dSJung-uk Kim         return 14;
4211f13597dSJung-uk Kim     case NID_secp160k1:        /* secp160k1 (15) */
4221f13597dSJung-uk Kim         return 15;
4231f13597dSJung-uk Kim     case NID_secp160r1:        /* secp160r1 (16) */
4241f13597dSJung-uk Kim         return 16;
4251f13597dSJung-uk Kim     case NID_secp160r2:        /* secp160r2 (17) */
4261f13597dSJung-uk Kim         return 17;
4271f13597dSJung-uk Kim     case NID_secp192k1:        /* secp192k1 (18) */
4281f13597dSJung-uk Kim         return 18;
4291f13597dSJung-uk Kim     case NID_X9_62_prime192v1: /* secp192r1 (19) */
4301f13597dSJung-uk Kim         return 19;
4311f13597dSJung-uk Kim     case NID_secp224k1:        /* secp224k1 (20) */
4321f13597dSJung-uk Kim         return 20;
4331f13597dSJung-uk Kim     case NID_secp224r1:        /* secp224r1 (21) */
4341f13597dSJung-uk Kim         return 21;
4351f13597dSJung-uk Kim     case NID_secp256k1:        /* secp256k1 (22) */
4361f13597dSJung-uk Kim         return 22;
4371f13597dSJung-uk Kim     case NID_X9_62_prime256v1: /* secp256r1 (23) */
4381f13597dSJung-uk Kim         return 23;
4391f13597dSJung-uk Kim     case NID_secp384r1:        /* secp384r1 (24) */
4401f13597dSJung-uk Kim         return 24;
4411f13597dSJung-uk Kim     case NID_secp521r1:        /* secp521r1 (25) */
4421f13597dSJung-uk Kim         return 25;
4437bded2dbSJung-uk Kim     case NID_brainpoolP256r1:  /* brainpoolP256r1 (26) */
4447bded2dbSJung-uk Kim         return 26;
4457bded2dbSJung-uk Kim     case NID_brainpoolP384r1:  /* brainpoolP384r1 (27) */
4467bded2dbSJung-uk Kim         return 27;
4477bded2dbSJung-uk Kim     case NID_brainpoolP512r1:  /* brainpool512r1 (28) */
4487bded2dbSJung-uk Kim         return 28;
4491f13597dSJung-uk Kim     default:
4501f13597dSJung-uk Kim         return 0;
451f579bf8eSKris Kennaway     }
4521f13597dSJung-uk Kim }
4537bded2dbSJung-uk Kim 
4547bded2dbSJung-uk Kim /*
4557bded2dbSJung-uk Kim  * Get curves list, if "sess" is set return client curves otherwise
4567bded2dbSJung-uk Kim  * preferred list.
4577bded2dbSJung-uk Kim  * Sets |num_curves| to the number of curves in the list, i.e.,
4587bded2dbSJung-uk Kim  * the length of |pcurves| is 2 * num_curves.
4597bded2dbSJung-uk Kim  * Returns 1 on success and 0 if the client curves list has invalid format.
4607bded2dbSJung-uk Kim  * The latter indicates an internal error: we should not be accepting such
4617bded2dbSJung-uk Kim  * lists in the first place.
4627bded2dbSJung-uk Kim  * TODO(emilia): we should really be storing the curves list in explicitly
4637bded2dbSJung-uk Kim  * parsed form instead. (However, this would affect binary compatibility
4647bded2dbSJung-uk Kim  * so cannot happen in the 1.0.x series.)
4657bded2dbSJung-uk Kim  */
4667bded2dbSJung-uk Kim static int tls1_get_curvelist(SSL *s, int sess,
4677bded2dbSJung-uk Kim                               const unsigned char **pcurves,
4687bded2dbSJung-uk Kim                               size_t *num_curves)
4697bded2dbSJung-uk Kim {
4707bded2dbSJung-uk Kim     size_t pcurveslen = 0;
4717bded2dbSJung-uk Kim     if (sess) {
4727bded2dbSJung-uk Kim         *pcurves = s->session->tlsext_ellipticcurvelist;
4737bded2dbSJung-uk Kim         pcurveslen = s->session->tlsext_ellipticcurvelist_length;
4747bded2dbSJung-uk Kim     } else {
4757bded2dbSJung-uk Kim         /* For Suite B mode only include P-256, P-384 */
4767bded2dbSJung-uk Kim         switch (tls1_suiteb(s)) {
4777bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_128_LOS:
4787bded2dbSJung-uk Kim             *pcurves = suiteb_curves;
4797bded2dbSJung-uk Kim             pcurveslen = sizeof(suiteb_curves);
4807bded2dbSJung-uk Kim             break;
4817bded2dbSJung-uk Kim 
4827bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
4837bded2dbSJung-uk Kim             *pcurves = suiteb_curves;
4847bded2dbSJung-uk Kim             pcurveslen = 2;
4857bded2dbSJung-uk Kim             break;
4867bded2dbSJung-uk Kim 
4877bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_192_LOS:
4887bded2dbSJung-uk Kim             *pcurves = suiteb_curves + 2;
4897bded2dbSJung-uk Kim             pcurveslen = 2;
4907bded2dbSJung-uk Kim             break;
4917bded2dbSJung-uk Kim         default:
4927bded2dbSJung-uk Kim             *pcurves = s->tlsext_ellipticcurvelist;
4937bded2dbSJung-uk Kim             pcurveslen = s->tlsext_ellipticcurvelist_length;
4947bded2dbSJung-uk Kim         }
4957bded2dbSJung-uk Kim         if (!*pcurves) {
4967bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
4977bded2dbSJung-uk Kim             if (FIPS_mode()) {
4987bded2dbSJung-uk Kim                 *pcurves = fips_curves_default;
4997bded2dbSJung-uk Kim                 pcurveslen = sizeof(fips_curves_default);
5007bded2dbSJung-uk Kim             } else
5017bded2dbSJung-uk Kim # endif
5027bded2dbSJung-uk Kim             {
50380815a77SJung-uk Kim                 if (!s->server || s->cert->ecdh_tmp_auto) {
5047bded2dbSJung-uk Kim                     *pcurves = eccurves_auto;
5057bded2dbSJung-uk Kim                     pcurveslen = sizeof(eccurves_auto);
5067bded2dbSJung-uk Kim                 } else {
5077bded2dbSJung-uk Kim                     *pcurves = eccurves_all;
5087bded2dbSJung-uk Kim                     pcurveslen = sizeof(eccurves_all);
5097bded2dbSJung-uk Kim                 }
5107bded2dbSJung-uk Kim             }
5117bded2dbSJung-uk Kim         }
5127bded2dbSJung-uk Kim     }
5137bded2dbSJung-uk Kim     /* We do not allow odd length arrays to enter the system. */
5147bded2dbSJung-uk Kim     if (pcurveslen & 1) {
5157bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR);
5167bded2dbSJung-uk Kim         *num_curves = 0;
5177bded2dbSJung-uk Kim         return 0;
5187bded2dbSJung-uk Kim     } else {
5197bded2dbSJung-uk Kim         *num_curves = pcurveslen / 2;
5207bded2dbSJung-uk Kim         return 1;
5217bded2dbSJung-uk Kim     }
5227bded2dbSJung-uk Kim }
5237bded2dbSJung-uk Kim 
5247bded2dbSJung-uk Kim /* Check a curve is one of our preferences */
5257bded2dbSJung-uk Kim int tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
5267bded2dbSJung-uk Kim {
5277bded2dbSJung-uk Kim     const unsigned char *curves;
5287bded2dbSJung-uk Kim     size_t num_curves, i;
5297bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
5307bded2dbSJung-uk Kim     if (len != 3 || p[0] != NAMED_CURVE_TYPE)
5317bded2dbSJung-uk Kim         return 0;
5327bded2dbSJung-uk Kim     /* Check curve matches Suite B preferences */
5337bded2dbSJung-uk Kim     if (suiteb_flags) {
5347bded2dbSJung-uk Kim         unsigned long cid = s->s3->tmp.new_cipher->id;
5357bded2dbSJung-uk Kim         if (p[1])
5367bded2dbSJung-uk Kim             return 0;
5377bded2dbSJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) {
5387bded2dbSJung-uk Kim             if (p[2] != TLSEXT_curve_P_256)
5397bded2dbSJung-uk Kim                 return 0;
5407bded2dbSJung-uk Kim         } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) {
5417bded2dbSJung-uk Kim             if (p[2] != TLSEXT_curve_P_384)
5427bded2dbSJung-uk Kim                 return 0;
5437bded2dbSJung-uk Kim         } else                  /* Should never happen */
5447bded2dbSJung-uk Kim             return 0;
5457bded2dbSJung-uk Kim     }
5467bded2dbSJung-uk Kim     if (!tls1_get_curvelist(s, 0, &curves, &num_curves))
5477bded2dbSJung-uk Kim         return 0;
5487bded2dbSJung-uk Kim     for (i = 0; i < num_curves; i++, curves += 2) {
5497bded2dbSJung-uk Kim         if (p[1] == curves[0] && p[2] == curves[1])
5507bded2dbSJung-uk Kim             return 1;
5517bded2dbSJung-uk Kim     }
5527bded2dbSJung-uk Kim     return 0;
5537bded2dbSJung-uk Kim }
5547bded2dbSJung-uk Kim 
5557bded2dbSJung-uk Kim /*-
5567bded2dbSJung-uk Kim  * Return |nmatch|th shared curve or NID_undef if there is no match.
5577bded2dbSJung-uk Kim  * For nmatch == -1, return number of  matches
5587bded2dbSJung-uk Kim  * For nmatch == -2, return the NID of the curve to use for
5597bded2dbSJung-uk Kim  * an EC tmp key, or NID_undef if there is no match.
5607bded2dbSJung-uk Kim  */
5617bded2dbSJung-uk Kim int tls1_shared_curve(SSL *s, int nmatch)
5627bded2dbSJung-uk Kim {
5637bded2dbSJung-uk Kim     const unsigned char *pref, *supp;
5647bded2dbSJung-uk Kim     size_t num_pref, num_supp, i, j;
5657bded2dbSJung-uk Kim     int k;
5667bded2dbSJung-uk Kim     /* Can't do anything on client side */
5677bded2dbSJung-uk Kim     if (s->server == 0)
5687bded2dbSJung-uk Kim         return -1;
5697bded2dbSJung-uk Kim     if (nmatch == -2) {
5707bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
5717bded2dbSJung-uk Kim             /*
5727bded2dbSJung-uk Kim              * For Suite B ciphersuite determines curve: we already know
5737bded2dbSJung-uk Kim              * these are acceptable due to previous checks.
5747bded2dbSJung-uk Kim              */
5757bded2dbSJung-uk Kim             unsigned long cid = s->s3->tmp.new_cipher->id;
5767bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
5777bded2dbSJung-uk Kim                 return NID_X9_62_prime256v1; /* P-256 */
5787bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
5797bded2dbSJung-uk Kim                 return NID_secp384r1; /* P-384 */
5807bded2dbSJung-uk Kim             /* Should never happen */
5817bded2dbSJung-uk Kim             return NID_undef;
5827bded2dbSJung-uk Kim         }
5837bded2dbSJung-uk Kim         /* If not Suite B just return first preference shared curve */
5847bded2dbSJung-uk Kim         nmatch = 0;
5857bded2dbSJung-uk Kim     }
5867bded2dbSJung-uk Kim     /*
5877bded2dbSJung-uk Kim      * Avoid truncation. tls1_get_curvelist takes an int
5887bded2dbSJung-uk Kim      * but s->options is a long...
5897bded2dbSJung-uk Kim      */
5907bded2dbSJung-uk Kim     if (!tls1_get_curvelist
5917bded2dbSJung-uk Kim         (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp,
5927bded2dbSJung-uk Kim          &num_supp))
5937bded2dbSJung-uk Kim         /* In practice, NID_undef == 0 but let's be precise. */
5947bded2dbSJung-uk Kim         return nmatch == -1 ? 0 : NID_undef;
5957bded2dbSJung-uk Kim     if (!tls1_get_curvelist
5967bded2dbSJung-uk Kim         (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref,
5977bded2dbSJung-uk Kim          &num_pref))
5987bded2dbSJung-uk Kim         return nmatch == -1 ? 0 : NID_undef;
5997bded2dbSJung-uk Kim 
6007bded2dbSJung-uk Kim     /*
6017bded2dbSJung-uk Kim      * If the client didn't send the elliptic_curves extension all of them
6027bded2dbSJung-uk Kim      * are allowed.
6037bded2dbSJung-uk Kim      */
6047bded2dbSJung-uk Kim     if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) {
6057bded2dbSJung-uk Kim         supp = eccurves_all;
6067bded2dbSJung-uk Kim         num_supp = sizeof(eccurves_all) / 2;
6077bded2dbSJung-uk Kim     } else if (num_pref == 0 &&
6087bded2dbSJung-uk Kim         (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) {
6097bded2dbSJung-uk Kim         pref = eccurves_all;
6107bded2dbSJung-uk Kim         num_pref = sizeof(eccurves_all) / 2;
6117bded2dbSJung-uk Kim     }
6127bded2dbSJung-uk Kim 
6137bded2dbSJung-uk Kim     k = 0;
6147bded2dbSJung-uk Kim     for (i = 0; i < num_pref; i++, pref += 2) {
6157bded2dbSJung-uk Kim         const unsigned char *tsupp = supp;
6167bded2dbSJung-uk Kim         for (j = 0; j < num_supp; j++, tsupp += 2) {
6177bded2dbSJung-uk Kim             if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) {
6187bded2dbSJung-uk Kim                 if (nmatch == k) {
6197bded2dbSJung-uk Kim                     int id = (pref[0] << 8) | pref[1];
6207bded2dbSJung-uk Kim                     return tls1_ec_curve_id2nid(id);
6217bded2dbSJung-uk Kim                 }
6227bded2dbSJung-uk Kim                 k++;
6237bded2dbSJung-uk Kim             }
6247bded2dbSJung-uk Kim         }
6257bded2dbSJung-uk Kim     }
6267bded2dbSJung-uk Kim     if (nmatch == -1)
6277bded2dbSJung-uk Kim         return k;
6287bded2dbSJung-uk Kim     /* Out of range (nmatch > k). */
6297bded2dbSJung-uk Kim     return NID_undef;
6307bded2dbSJung-uk Kim }
6317bded2dbSJung-uk Kim 
6327bded2dbSJung-uk Kim int tls1_set_curves(unsigned char **pext, size_t *pextlen,
6337bded2dbSJung-uk Kim                     int *curves, size_t ncurves)
6347bded2dbSJung-uk Kim {
6357bded2dbSJung-uk Kim     unsigned char *clist, *p;
6367bded2dbSJung-uk Kim     size_t i;
6377bded2dbSJung-uk Kim     /*
6387bded2dbSJung-uk Kim      * Bitmap of curves included to detect duplicates: only works while curve
6397bded2dbSJung-uk Kim      * ids < 32
6407bded2dbSJung-uk Kim      */
6417bded2dbSJung-uk Kim     unsigned long dup_list = 0;
6427bded2dbSJung-uk Kim # ifdef OPENSSL_NO_EC2M
6437bded2dbSJung-uk Kim     EC_GROUP *curve;
6447bded2dbSJung-uk Kim # endif
6457bded2dbSJung-uk Kim 
6467bded2dbSJung-uk Kim     clist = OPENSSL_malloc(ncurves * 2);
6477bded2dbSJung-uk Kim     if (!clist)
6487bded2dbSJung-uk Kim         return 0;
6497bded2dbSJung-uk Kim     for (i = 0, p = clist; i < ncurves; i++) {
6507bded2dbSJung-uk Kim         unsigned long idmask;
6517bded2dbSJung-uk Kim         int id;
6527bded2dbSJung-uk Kim         id = tls1_ec_nid2curve_id(curves[i]);
6537bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
6547bded2dbSJung-uk Kim         /* NB: 25 is last curve ID supported by FIPS module */
6557bded2dbSJung-uk Kim         if (FIPS_mode() && id > 25) {
6567bded2dbSJung-uk Kim             OPENSSL_free(clist);
6577bded2dbSJung-uk Kim             return 0;
6587bded2dbSJung-uk Kim         }
6597bded2dbSJung-uk Kim # endif
6607bded2dbSJung-uk Kim # ifdef OPENSSL_NO_EC2M
6617bded2dbSJung-uk Kim         curve = EC_GROUP_new_by_curve_name(curves[i]);
6627bded2dbSJung-uk Kim         if (!curve || EC_METHOD_get_field_type(EC_GROUP_method_of(curve))
6637bded2dbSJung-uk Kim             == NID_X9_62_characteristic_two_field) {
6647bded2dbSJung-uk Kim             if (curve)
6657bded2dbSJung-uk Kim                 EC_GROUP_free(curve);
6667bded2dbSJung-uk Kim             OPENSSL_free(clist);
6677bded2dbSJung-uk Kim             return 0;
6687bded2dbSJung-uk Kim         } else
6697bded2dbSJung-uk Kim             EC_GROUP_free(curve);
6707bded2dbSJung-uk Kim # endif
6717bded2dbSJung-uk Kim         idmask = 1L << id;
6727bded2dbSJung-uk Kim         if (!id || (dup_list & idmask)) {
6737bded2dbSJung-uk Kim             OPENSSL_free(clist);
6747bded2dbSJung-uk Kim             return 0;
6757bded2dbSJung-uk Kim         }
6767bded2dbSJung-uk Kim         dup_list |= idmask;
6777bded2dbSJung-uk Kim         s2n(id, p);
6787bded2dbSJung-uk Kim     }
6797bded2dbSJung-uk Kim     if (*pext)
6807bded2dbSJung-uk Kim         OPENSSL_free(*pext);
6817bded2dbSJung-uk Kim     *pext = clist;
6827bded2dbSJung-uk Kim     *pextlen = ncurves * 2;
6837bded2dbSJung-uk Kim     return 1;
6847bded2dbSJung-uk Kim }
6857bded2dbSJung-uk Kim 
6867bded2dbSJung-uk Kim # define MAX_CURVELIST   28
6877bded2dbSJung-uk Kim 
6887bded2dbSJung-uk Kim typedef struct {
6897bded2dbSJung-uk Kim     size_t nidcnt;
6907bded2dbSJung-uk Kim     int nid_arr[MAX_CURVELIST];
6917bded2dbSJung-uk Kim } nid_cb_st;
6927bded2dbSJung-uk Kim 
6937bded2dbSJung-uk Kim static int nid_cb(const char *elem, int len, void *arg)
6947bded2dbSJung-uk Kim {
6957bded2dbSJung-uk Kim     nid_cb_st *narg = arg;
6967bded2dbSJung-uk Kim     size_t i;
6977bded2dbSJung-uk Kim     int nid;
6987bded2dbSJung-uk Kim     char etmp[20];
6997bded2dbSJung-uk Kim     if (elem == NULL)
7007bded2dbSJung-uk Kim         return 0;
7017bded2dbSJung-uk Kim     if (narg->nidcnt == MAX_CURVELIST)
7027bded2dbSJung-uk Kim         return 0;
7037bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
7047bded2dbSJung-uk Kim         return 0;
7057bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
7067bded2dbSJung-uk Kim     etmp[len] = 0;
7077bded2dbSJung-uk Kim     nid = EC_curve_nist2nid(etmp);
7087bded2dbSJung-uk Kim     if (nid == NID_undef)
7097bded2dbSJung-uk Kim         nid = OBJ_sn2nid(etmp);
7107bded2dbSJung-uk Kim     if (nid == NID_undef)
7117bded2dbSJung-uk Kim         nid = OBJ_ln2nid(etmp);
7127bded2dbSJung-uk Kim     if (nid == NID_undef)
7137bded2dbSJung-uk Kim         return 0;
7147bded2dbSJung-uk Kim     for (i = 0; i < narg->nidcnt; i++)
7157bded2dbSJung-uk Kim         if (narg->nid_arr[i] == nid)
7167bded2dbSJung-uk Kim             return 0;
7177bded2dbSJung-uk Kim     narg->nid_arr[narg->nidcnt++] = nid;
7187bded2dbSJung-uk Kim     return 1;
7197bded2dbSJung-uk Kim }
7207bded2dbSJung-uk Kim 
7217bded2dbSJung-uk Kim /* Set curves based on a colon separate list */
7227bded2dbSJung-uk Kim int tls1_set_curves_list(unsigned char **pext, size_t *pextlen,
7237bded2dbSJung-uk Kim                          const char *str)
7247bded2dbSJung-uk Kim {
7257bded2dbSJung-uk Kim     nid_cb_st ncb;
7267bded2dbSJung-uk Kim     ncb.nidcnt = 0;
7277bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb))
7287bded2dbSJung-uk Kim         return 0;
7297bded2dbSJung-uk Kim     if (pext == NULL)
7307bded2dbSJung-uk Kim         return 1;
7317bded2dbSJung-uk Kim     return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt);
7327bded2dbSJung-uk Kim }
7337bded2dbSJung-uk Kim 
7347bded2dbSJung-uk Kim /* For an EC key set TLS id and required compression based on parameters */
7357bded2dbSJung-uk Kim static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id,
7367bded2dbSJung-uk Kim                           EC_KEY *ec)
7377bded2dbSJung-uk Kim {
7387bded2dbSJung-uk Kim     int is_prime, id;
7397bded2dbSJung-uk Kim     const EC_GROUP *grp;
7407bded2dbSJung-uk Kim     const EC_METHOD *meth;
7417bded2dbSJung-uk Kim     if (!ec)
7427bded2dbSJung-uk Kim         return 0;
7437bded2dbSJung-uk Kim     /* Determine if it is a prime field */
7447bded2dbSJung-uk Kim     grp = EC_KEY_get0_group(ec);
7457bded2dbSJung-uk Kim     if (!grp)
7467bded2dbSJung-uk Kim         return 0;
7477bded2dbSJung-uk Kim     meth = EC_GROUP_method_of(grp);
7487bded2dbSJung-uk Kim     if (!meth)
7497bded2dbSJung-uk Kim         return 0;
7507bded2dbSJung-uk Kim     if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
7517bded2dbSJung-uk Kim         is_prime = 1;
7527bded2dbSJung-uk Kim     else
7537bded2dbSJung-uk Kim         is_prime = 0;
7547bded2dbSJung-uk Kim     /* Determine curve ID */
7557bded2dbSJung-uk Kim     id = EC_GROUP_get_curve_name(grp);
7567bded2dbSJung-uk Kim     id = tls1_ec_nid2curve_id(id);
7577bded2dbSJung-uk Kim     /* If we have an ID set it, otherwise set arbitrary explicit curve */
7587bded2dbSJung-uk Kim     if (id) {
7597bded2dbSJung-uk Kim         curve_id[0] = 0;
7607bded2dbSJung-uk Kim         curve_id[1] = (unsigned char)id;
7617bded2dbSJung-uk Kim     } else {
7627bded2dbSJung-uk Kim         curve_id[0] = 0xff;
7637bded2dbSJung-uk Kim         if (is_prime)
7647bded2dbSJung-uk Kim             curve_id[1] = 0x01;
7657bded2dbSJung-uk Kim         else
7667bded2dbSJung-uk Kim             curve_id[1] = 0x02;
7677bded2dbSJung-uk Kim     }
7687bded2dbSJung-uk Kim     if (comp_id) {
7697bded2dbSJung-uk Kim         if (EC_KEY_get0_public_key(ec) == NULL)
7707bded2dbSJung-uk Kim             return 0;
7717bded2dbSJung-uk Kim         if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
7727bded2dbSJung-uk Kim             if (is_prime)
7737bded2dbSJung-uk Kim                 *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
7747bded2dbSJung-uk Kim             else
7757bded2dbSJung-uk Kim                 *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
7767bded2dbSJung-uk Kim         } else
7777bded2dbSJung-uk Kim             *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
7787bded2dbSJung-uk Kim     }
7797bded2dbSJung-uk Kim     return 1;
7807bded2dbSJung-uk Kim }
7817bded2dbSJung-uk Kim 
7827bded2dbSJung-uk Kim /* Check an EC key is compatible with extensions */
7837bded2dbSJung-uk Kim static int tls1_check_ec_key(SSL *s,
7847bded2dbSJung-uk Kim                              unsigned char *curve_id, unsigned char *comp_id)
7857bded2dbSJung-uk Kim {
7867bded2dbSJung-uk Kim     const unsigned char *pformats, *pcurves;
7877bded2dbSJung-uk Kim     size_t num_formats, num_curves, i;
7887bded2dbSJung-uk Kim     int j;
7897bded2dbSJung-uk Kim     /*
7907bded2dbSJung-uk Kim      * If point formats extension present check it, otherwise everything is
7917bded2dbSJung-uk Kim      * supported (see RFC4492).
7927bded2dbSJung-uk Kim      */
7937bded2dbSJung-uk Kim     if (comp_id && s->session->tlsext_ecpointformatlist) {
7947bded2dbSJung-uk Kim         pformats = s->session->tlsext_ecpointformatlist;
7957bded2dbSJung-uk Kim         num_formats = s->session->tlsext_ecpointformatlist_length;
7967bded2dbSJung-uk Kim         for (i = 0; i < num_formats; i++, pformats++) {
7977bded2dbSJung-uk Kim             if (*comp_id == *pformats)
7987bded2dbSJung-uk Kim                 break;
7997bded2dbSJung-uk Kim         }
8007bded2dbSJung-uk Kim         if (i == num_formats)
8017bded2dbSJung-uk Kim             return 0;
8027bded2dbSJung-uk Kim     }
8037bded2dbSJung-uk Kim     if (!curve_id)
8047bded2dbSJung-uk Kim         return 1;
8057bded2dbSJung-uk Kim     /* Check curve is consistent with client and server preferences */
8067bded2dbSJung-uk Kim     for (j = 0; j <= 1; j++) {
8077bded2dbSJung-uk Kim         if (!tls1_get_curvelist(s, j, &pcurves, &num_curves))
8087bded2dbSJung-uk Kim             return 0;
8097bded2dbSJung-uk Kim         if (j == 1 && num_curves == 0) {
8107bded2dbSJung-uk Kim             /*
8117bded2dbSJung-uk Kim              * If we've not received any curves then skip this check.
8127bded2dbSJung-uk Kim              * RFC 4492 does not require the supported elliptic curves extension
8137bded2dbSJung-uk Kim              * so if it is not sent we can just choose any curve.
8147bded2dbSJung-uk Kim              * It is invalid to send an empty list in the elliptic curves
8157bded2dbSJung-uk Kim              * extension, so num_curves == 0 always means no extension.
8167bded2dbSJung-uk Kim              */
8177bded2dbSJung-uk Kim             break;
8187bded2dbSJung-uk Kim         }
8197bded2dbSJung-uk Kim         for (i = 0; i < num_curves; i++, pcurves += 2) {
8207bded2dbSJung-uk Kim             if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1])
8217bded2dbSJung-uk Kim                 break;
8227bded2dbSJung-uk Kim         }
8237bded2dbSJung-uk Kim         if (i == num_curves)
8247bded2dbSJung-uk Kim             return 0;
8257bded2dbSJung-uk Kim         /* For clients can only check sent curve list */
8267bded2dbSJung-uk Kim         if (!s->server)
8277bded2dbSJung-uk Kim             return 1;
8287bded2dbSJung-uk Kim     }
8297bded2dbSJung-uk Kim     return 1;
8307bded2dbSJung-uk Kim }
8317bded2dbSJung-uk Kim 
8327bded2dbSJung-uk Kim static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
8337bded2dbSJung-uk Kim                                 size_t *num_formats)
8347bded2dbSJung-uk Kim {
8357bded2dbSJung-uk Kim     /*
8367bded2dbSJung-uk Kim      * If we have a custom point format list use it otherwise use default
8377bded2dbSJung-uk Kim      */
8387bded2dbSJung-uk Kim     if (s->tlsext_ecpointformatlist) {
8397bded2dbSJung-uk Kim         *pformats = s->tlsext_ecpointformatlist;
8407bded2dbSJung-uk Kim         *num_formats = s->tlsext_ecpointformatlist_length;
8417bded2dbSJung-uk Kim     } else {
8427bded2dbSJung-uk Kim         *pformats = ecformats_default;
8437bded2dbSJung-uk Kim         /* For Suite B we don't support char2 fields */
8447bded2dbSJung-uk Kim         if (tls1_suiteb(s))
8457bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default) - 1;
8467bded2dbSJung-uk Kim         else
8477bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default);
8487bded2dbSJung-uk Kim     }
8497bded2dbSJung-uk Kim }
8507bded2dbSJung-uk Kim 
8517bded2dbSJung-uk Kim /*
8527bded2dbSJung-uk Kim  * Check cert parameters compatible with extensions: currently just checks EC
8537bded2dbSJung-uk Kim  * certificates have compatible curves and compression.
8547bded2dbSJung-uk Kim  */
8557bded2dbSJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
8567bded2dbSJung-uk Kim {
8577bded2dbSJung-uk Kim     unsigned char comp_id, curve_id[2];
8587bded2dbSJung-uk Kim     EVP_PKEY *pkey;
8597bded2dbSJung-uk Kim     int rv;
8607bded2dbSJung-uk Kim     pkey = X509_get_pubkey(x);
8617bded2dbSJung-uk Kim     if (!pkey)
8627bded2dbSJung-uk Kim         return 0;
8637bded2dbSJung-uk Kim     /* If not EC nothing to do */
8647bded2dbSJung-uk Kim     if (pkey->type != EVP_PKEY_EC) {
8657bded2dbSJung-uk Kim         EVP_PKEY_free(pkey);
8667bded2dbSJung-uk Kim         return 1;
8677bded2dbSJung-uk Kim     }
8687bded2dbSJung-uk Kim     rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec);
8697bded2dbSJung-uk Kim     EVP_PKEY_free(pkey);
8707bded2dbSJung-uk Kim     if (!rv)
8717bded2dbSJung-uk Kim         return 0;
8727bded2dbSJung-uk Kim     /*
8737bded2dbSJung-uk Kim      * Can't check curve_id for client certs as we don't have a supported
8747bded2dbSJung-uk Kim      * curves extension.
8757bded2dbSJung-uk Kim      */
8767bded2dbSJung-uk Kim     rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id);
8777bded2dbSJung-uk Kim     if (!rv)
8787bded2dbSJung-uk Kim         return 0;
8797bded2dbSJung-uk Kim     /*
8807bded2dbSJung-uk Kim      * Special case for suite B. We *MUST* sign using SHA256+P-256 or
8817bded2dbSJung-uk Kim      * SHA384+P-384, adjust digest if necessary.
8827bded2dbSJung-uk Kim      */
8837bded2dbSJung-uk Kim     if (set_ee_md && tls1_suiteb(s)) {
8847bded2dbSJung-uk Kim         int check_md;
8857bded2dbSJung-uk Kim         size_t i;
8867bded2dbSJung-uk Kim         CERT *c = s->cert;
8877bded2dbSJung-uk Kim         if (curve_id[0])
8887bded2dbSJung-uk Kim             return 0;
8897bded2dbSJung-uk Kim         /* Check to see we have necessary signing algorithm */
8907bded2dbSJung-uk Kim         if (curve_id[1] == TLSEXT_curve_P_256)
8917bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA256;
8927bded2dbSJung-uk Kim         else if (curve_id[1] == TLSEXT_curve_P_384)
8937bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA384;
8947bded2dbSJung-uk Kim         else
8957bded2dbSJung-uk Kim             return 0;           /* Should never happen */
8967bded2dbSJung-uk Kim         for (i = 0; i < c->shared_sigalgslen; i++)
8977bded2dbSJung-uk Kim             if (check_md == c->shared_sigalgs[i].signandhash_nid)
8987bded2dbSJung-uk Kim                 break;
8997bded2dbSJung-uk Kim         if (i == c->shared_sigalgslen)
9007bded2dbSJung-uk Kim             return 0;
9017bded2dbSJung-uk Kim         if (set_ee_md == 2) {
9027bded2dbSJung-uk Kim             if (check_md == NID_ecdsa_with_SHA256)
9037bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256();
9047bded2dbSJung-uk Kim             else
9057bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384();
9067bded2dbSJung-uk Kim         }
9077bded2dbSJung-uk Kim     }
9087bded2dbSJung-uk Kim     return rv;
9097bded2dbSJung-uk Kim }
9107bded2dbSJung-uk Kim 
9117bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDH
9127bded2dbSJung-uk Kim /* Check EC temporary key is compatible with client extensions */
9137bded2dbSJung-uk Kim int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
9147bded2dbSJung-uk Kim {
9157bded2dbSJung-uk Kim     unsigned char curve_id[2];
9167bded2dbSJung-uk Kim     EC_KEY *ec = s->cert->ecdh_tmp;
9177bded2dbSJung-uk Kim #  ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
9187bded2dbSJung-uk Kim     /* Allow any curve: not just those peer supports */
9197bded2dbSJung-uk Kim     if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
9207bded2dbSJung-uk Kim         return 1;
9217bded2dbSJung-uk Kim #  endif
9227bded2dbSJung-uk Kim     /*
9237bded2dbSJung-uk Kim      * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other
9247bded2dbSJung-uk Kim      * curves permitted.
9257bded2dbSJung-uk Kim      */
9267bded2dbSJung-uk Kim     if (tls1_suiteb(s)) {
9277bded2dbSJung-uk Kim         /* Curve to check determined by ciphersuite */
9287bded2dbSJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
9297bded2dbSJung-uk Kim             curve_id[1] = TLSEXT_curve_P_256;
9307bded2dbSJung-uk Kim         else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
9317bded2dbSJung-uk Kim             curve_id[1] = TLSEXT_curve_P_384;
9327bded2dbSJung-uk Kim         else
9337bded2dbSJung-uk Kim             return 0;
9347bded2dbSJung-uk Kim         curve_id[0] = 0;
9357bded2dbSJung-uk Kim         /* Check this curve is acceptable */
9367bded2dbSJung-uk Kim         if (!tls1_check_ec_key(s, curve_id, NULL))
9377bded2dbSJung-uk Kim             return 0;
9387bded2dbSJung-uk Kim         /* If auto or setting curve from callback assume OK */
9397bded2dbSJung-uk Kim         if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb)
9407bded2dbSJung-uk Kim             return 1;
9417bded2dbSJung-uk Kim         /* Otherwise check curve is acceptable */
9427bded2dbSJung-uk Kim         else {
9437bded2dbSJung-uk Kim             unsigned char curve_tmp[2];
9447bded2dbSJung-uk Kim             if (!ec)
9457bded2dbSJung-uk Kim                 return 0;
9467bded2dbSJung-uk Kim             if (!tls1_set_ec_id(curve_tmp, NULL, ec))
9477bded2dbSJung-uk Kim                 return 0;
9487bded2dbSJung-uk Kim             if (!curve_tmp[0] || curve_tmp[1] == curve_id[1])
9497bded2dbSJung-uk Kim                 return 1;
9507bded2dbSJung-uk Kim             return 0;
9517bded2dbSJung-uk Kim         }
9527bded2dbSJung-uk Kim 
9537bded2dbSJung-uk Kim     }
9547bded2dbSJung-uk Kim     if (s->cert->ecdh_tmp_auto) {
9557bded2dbSJung-uk Kim         /* Need a shared curve */
9567bded2dbSJung-uk Kim         if (tls1_shared_curve(s, 0))
9577bded2dbSJung-uk Kim             return 1;
9587bded2dbSJung-uk Kim         else
9597bded2dbSJung-uk Kim             return 0;
9607bded2dbSJung-uk Kim     }
9617bded2dbSJung-uk Kim     if (!ec) {
9627bded2dbSJung-uk Kim         if (s->cert->ecdh_tmp_cb)
9637bded2dbSJung-uk Kim             return 1;
9647bded2dbSJung-uk Kim         else
9657bded2dbSJung-uk Kim             return 0;
9667bded2dbSJung-uk Kim     }
9677bded2dbSJung-uk Kim     if (!tls1_set_ec_id(curve_id, NULL, ec))
9687bded2dbSJung-uk Kim         return 0;
9697bded2dbSJung-uk Kim /* Set this to allow use of invalid curves for testing */
9707bded2dbSJung-uk Kim #  if 0
9717bded2dbSJung-uk Kim     return 1;
9727bded2dbSJung-uk Kim #  else
9737bded2dbSJung-uk Kim     return tls1_check_ec_key(s, curve_id, NULL);
9747bded2dbSJung-uk Kim #  endif
9757bded2dbSJung-uk Kim }
9767bded2dbSJung-uk Kim # endif                         /* OPENSSL_NO_ECDH */
9777bded2dbSJung-uk Kim 
9787bded2dbSJung-uk Kim #else
9797bded2dbSJung-uk Kim 
9807bded2dbSJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
9817bded2dbSJung-uk Kim {
9827bded2dbSJung-uk Kim     return 1;
9837bded2dbSJung-uk Kim }
9847bded2dbSJung-uk Kim 
9851f13597dSJung-uk Kim #endif                          /* OPENSSL_NO_EC */
986db522d3aSSimon L. B. Nielsen 
987db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
9881f13597dSJung-uk Kim 
9896f9291ceSJung-uk Kim /*
9906f9291ceSJung-uk Kim  * List of supported signature algorithms and hashes. Should make this
9911f13597dSJung-uk Kim  * customisable at some point, for now include everything we support.
9921f13597dSJung-uk Kim  */
9931f13597dSJung-uk Kim 
9941f13597dSJung-uk Kim # ifdef OPENSSL_NO_RSA
9951f13597dSJung-uk Kim #  define tlsext_sigalg_rsa(md) /* */
9961f13597dSJung-uk Kim # else
9971f13597dSJung-uk Kim #  define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
9981f13597dSJung-uk Kim # endif
9991f13597dSJung-uk Kim 
10001f13597dSJung-uk Kim # ifdef OPENSSL_NO_DSA
10011f13597dSJung-uk Kim #  define tlsext_sigalg_dsa(md) /* */
10021f13597dSJung-uk Kim # else
10031f13597dSJung-uk Kim #  define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
10041f13597dSJung-uk Kim # endif
10051f13597dSJung-uk Kim 
10061f13597dSJung-uk Kim # ifdef OPENSSL_NO_ECDSA
10076f9291ceSJung-uk Kim #  define tlsext_sigalg_ecdsa(md)
10086f9291ceSJung-uk Kim                                 /* */
10091f13597dSJung-uk Kim # else
10101f13597dSJung-uk Kim #  define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
10111f13597dSJung-uk Kim # endif
10121f13597dSJung-uk Kim 
10131f13597dSJung-uk Kim # define tlsext_sigalg(md) \
10141f13597dSJung-uk Kim                 tlsext_sigalg_rsa(md) \
10151f13597dSJung-uk Kim                 tlsext_sigalg_dsa(md) \
10161f13597dSJung-uk Kim                 tlsext_sigalg_ecdsa(md)
10171f13597dSJung-uk Kim 
10181f13597dSJung-uk Kim static unsigned char tls12_sigalgs[] = {
10191f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
10201f13597dSJung-uk Kim     tlsext_sigalg(TLSEXT_hash_sha512)
10211f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha384)
10221f13597dSJung-uk Kim # endif
10231f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
10241f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha256)
10251f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha224)
10261f13597dSJung-uk Kim # endif
10271f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
10281f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha1)
10291f13597dSJung-uk Kim # endif
10301f13597dSJung-uk Kim };
10311f13597dSJung-uk Kim 
10327bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
10337bded2dbSJung-uk Kim static unsigned char suiteb_sigalgs[] = {
10347bded2dbSJung-uk Kim     tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
10357bded2dbSJung-uk Kim         tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
10367bded2dbSJung-uk Kim };
10377bded2dbSJung-uk Kim # endif
1038ed7112f0SJung-uk Kim size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs)
10391f13597dSJung-uk Kim {
10407bded2dbSJung-uk Kim     /*
10417bded2dbSJung-uk Kim      * If Suite B mode use Suite B sigalgs only, ignore any other
10427bded2dbSJung-uk Kim      * preferences.
10437bded2dbSJung-uk Kim      */
10447bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
10457bded2dbSJung-uk Kim     switch (tls1_suiteb(s)) {
10467bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
10477bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
10487bded2dbSJung-uk Kim         return sizeof(suiteb_sigalgs);
10497bded2dbSJung-uk Kim 
10507bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
10517bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
10527bded2dbSJung-uk Kim         return 2;
10537bded2dbSJung-uk Kim 
10547bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
10557bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs + 2;
10567bded2dbSJung-uk Kim         return 2;
10577bded2dbSJung-uk Kim     }
10587bded2dbSJung-uk Kim # endif
10597bded2dbSJung-uk Kim     /* If server use client authentication sigalgs if not NULL */
1060ed7112f0SJung-uk Kim     if (s->server == sent && s->cert->client_sigalgs) {
10617bded2dbSJung-uk Kim         *psigs = s->cert->client_sigalgs;
10627bded2dbSJung-uk Kim         return s->cert->client_sigalgslen;
10637bded2dbSJung-uk Kim     } else if (s->cert->conf_sigalgs) {
10647bded2dbSJung-uk Kim         *psigs = s->cert->conf_sigalgs;
10657bded2dbSJung-uk Kim         return s->cert->conf_sigalgslen;
10667bded2dbSJung-uk Kim     } else {
10677bded2dbSJung-uk Kim         *psigs = tls12_sigalgs;
10687bded2dbSJung-uk Kim         return sizeof(tls12_sigalgs);
10697bded2dbSJung-uk Kim     }
10707bded2dbSJung-uk Kim }
10717bded2dbSJung-uk Kim 
10727bded2dbSJung-uk Kim /*
10737bded2dbSJung-uk Kim  * Check signature algorithm is consistent with sent supported signature
10747bded2dbSJung-uk Kim  * algorithms and if so return relevant digest.
10757bded2dbSJung-uk Kim  */
10767bded2dbSJung-uk Kim int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
10777bded2dbSJung-uk Kim                             const unsigned char *sig, EVP_PKEY *pkey)
10787bded2dbSJung-uk Kim {
10797bded2dbSJung-uk Kim     const unsigned char *sent_sigs;
10807bded2dbSJung-uk Kim     size_t sent_sigslen, i;
10817bded2dbSJung-uk Kim     int sigalg = tls12_get_sigid(pkey);
10827bded2dbSJung-uk Kim     /* Should never happen */
10837bded2dbSJung-uk Kim     if (sigalg == -1)
10847bded2dbSJung-uk Kim         return -1;
10857bded2dbSJung-uk Kim     /* Check key type is consistent with signature */
10867bded2dbSJung-uk Kim     if (sigalg != (int)sig[1]) {
10877bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
10887bded2dbSJung-uk Kim         return 0;
10897bded2dbSJung-uk Kim     }
10907bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
10917bded2dbSJung-uk Kim     if (pkey->type == EVP_PKEY_EC) {
10927bded2dbSJung-uk Kim         unsigned char curve_id[2], comp_id;
10937bded2dbSJung-uk Kim         /* Check compression and curve matches extensions */
10947bded2dbSJung-uk Kim         if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec))
10957bded2dbSJung-uk Kim             return 0;
10967bded2dbSJung-uk Kim         if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
10977bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
10987bded2dbSJung-uk Kim             return 0;
10997bded2dbSJung-uk Kim         }
11007bded2dbSJung-uk Kim         /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
11017bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
11027bded2dbSJung-uk Kim             if (curve_id[0])
11037bded2dbSJung-uk Kim                 return 0;
11047bded2dbSJung-uk Kim             if (curve_id[1] == TLSEXT_curve_P_256) {
11057bded2dbSJung-uk Kim                 if (sig[0] != TLSEXT_hash_sha256) {
11067bded2dbSJung-uk Kim                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
11077bded2dbSJung-uk Kim                            SSL_R_ILLEGAL_SUITEB_DIGEST);
11087bded2dbSJung-uk Kim                     return 0;
11097bded2dbSJung-uk Kim                 }
11107bded2dbSJung-uk Kim             } else if (curve_id[1] == TLSEXT_curve_P_384) {
11117bded2dbSJung-uk Kim                 if (sig[0] != TLSEXT_hash_sha384) {
11127bded2dbSJung-uk Kim                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
11137bded2dbSJung-uk Kim                            SSL_R_ILLEGAL_SUITEB_DIGEST);
11147bded2dbSJung-uk Kim                     return 0;
11157bded2dbSJung-uk Kim                 }
11167bded2dbSJung-uk Kim             } else
11177bded2dbSJung-uk Kim                 return 0;
11187bded2dbSJung-uk Kim         }
11197bded2dbSJung-uk Kim     } else if (tls1_suiteb(s))
11207bded2dbSJung-uk Kim         return 0;
11217bded2dbSJung-uk Kim # endif
11227bded2dbSJung-uk Kim 
11237bded2dbSJung-uk Kim     /* Check signature matches a type we sent */
1124ed7112f0SJung-uk Kim     sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
11257bded2dbSJung-uk Kim     for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
11267bded2dbSJung-uk Kim         if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1])
11277bded2dbSJung-uk Kim             break;
11287bded2dbSJung-uk Kim     }
11297bded2dbSJung-uk Kim     /* Allow fallback to SHA1 if not strict mode */
11307bded2dbSJung-uk Kim     if (i == sent_sigslen
11317bded2dbSJung-uk Kim         && (sig[0] != TLSEXT_hash_sha1
11327bded2dbSJung-uk Kim             || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
11337bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
11347bded2dbSJung-uk Kim         return 0;
11357bded2dbSJung-uk Kim     }
11367bded2dbSJung-uk Kim     *pmd = tls12_get_hash(sig[0]);
11377bded2dbSJung-uk Kim     if (*pmd == NULL) {
11387bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
11397bded2dbSJung-uk Kim         return 0;
11407bded2dbSJung-uk Kim     }
11417bded2dbSJung-uk Kim     /*
11427bded2dbSJung-uk Kim      * Store the digest used so applications can retrieve it if they wish.
11437bded2dbSJung-uk Kim      */
11447bded2dbSJung-uk Kim     if (s->session && s->session->sess_cert)
11457bded2dbSJung-uk Kim         s->session->sess_cert->peer_key->digest = *pmd;
11467bded2dbSJung-uk Kim     return 1;
11477bded2dbSJung-uk Kim }
11487bded2dbSJung-uk Kim 
11497bded2dbSJung-uk Kim /*
11507bded2dbSJung-uk Kim  * Get a mask of disabled algorithms: an algorithm is disabled if it isn't
11517bded2dbSJung-uk Kim  * supported or doesn't appear in supported signature algorithms. Unlike
11527bded2dbSJung-uk Kim  * ssl_cipher_get_disabled this applies to a specific session and not global
11537bded2dbSJung-uk Kim  * settings.
11547bded2dbSJung-uk Kim  */
11557bded2dbSJung-uk Kim void ssl_set_client_disabled(SSL *s)
11567bded2dbSJung-uk Kim {
11577bded2dbSJung-uk Kim     CERT *c = s->cert;
11587bded2dbSJung-uk Kim     const unsigned char *sigalgs;
11597bded2dbSJung-uk Kim     size_t i, sigalgslen;
11607bded2dbSJung-uk Kim     int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
11617bded2dbSJung-uk Kim     c->mask_a = 0;
11627bded2dbSJung-uk Kim     c->mask_k = 0;
11637bded2dbSJung-uk Kim     /* Don't allow TLS 1.2 only ciphers if we don't suppport them */
11647bded2dbSJung-uk Kim     if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s))
11657bded2dbSJung-uk Kim         c->mask_ssl = SSL_TLSV1_2;
11667bded2dbSJung-uk Kim     else
11677bded2dbSJung-uk Kim         c->mask_ssl = 0;
11687bded2dbSJung-uk Kim     /*
11697bded2dbSJung-uk Kim      * Now go through all signature algorithms seeing if we support any for
11707bded2dbSJung-uk Kim      * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2.
11717bded2dbSJung-uk Kim      */
1172ed7112f0SJung-uk Kim     sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
11737bded2dbSJung-uk Kim     for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
11747bded2dbSJung-uk Kim         switch (sigalgs[1]) {
11757bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA
11767bded2dbSJung-uk Kim         case TLSEXT_signature_rsa:
11777bded2dbSJung-uk Kim             have_rsa = 1;
11787bded2dbSJung-uk Kim             break;
11797bded2dbSJung-uk Kim # endif
11807bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA
11817bded2dbSJung-uk Kim         case TLSEXT_signature_dsa:
11827bded2dbSJung-uk Kim             have_dsa = 1;
11837bded2dbSJung-uk Kim             break;
11847bded2dbSJung-uk Kim # endif
11857bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
11867bded2dbSJung-uk Kim         case TLSEXT_signature_ecdsa:
11877bded2dbSJung-uk Kim             have_ecdsa = 1;
11887bded2dbSJung-uk Kim             break;
11897bded2dbSJung-uk Kim # endif
11907bded2dbSJung-uk Kim         }
11917bded2dbSJung-uk Kim     }
11927bded2dbSJung-uk Kim     /*
11937bded2dbSJung-uk Kim      * Disable auth and static DH if we don't include any appropriate
11947bded2dbSJung-uk Kim      * signature algorithms.
11957bded2dbSJung-uk Kim      */
11967bded2dbSJung-uk Kim     if (!have_rsa) {
11977bded2dbSJung-uk Kim         c->mask_a |= SSL_aRSA;
11987bded2dbSJung-uk Kim         c->mask_k |= SSL_kDHr | SSL_kECDHr;
11997bded2dbSJung-uk Kim     }
12007bded2dbSJung-uk Kim     if (!have_dsa) {
12017bded2dbSJung-uk Kim         c->mask_a |= SSL_aDSS;
12027bded2dbSJung-uk Kim         c->mask_k |= SSL_kDHd;
12037bded2dbSJung-uk Kim     }
12047bded2dbSJung-uk Kim     if (!have_ecdsa) {
12057bded2dbSJung-uk Kim         c->mask_a |= SSL_aECDSA;
12067bded2dbSJung-uk Kim         c->mask_k |= SSL_kECDHe;
12077bded2dbSJung-uk Kim     }
12087bded2dbSJung-uk Kim # ifndef OPENSSL_NO_KRB5
12097bded2dbSJung-uk Kim     if (!kssl_tgt_is_available(s->kssl_ctx)) {
12107bded2dbSJung-uk Kim         c->mask_a |= SSL_aKRB5;
12117bded2dbSJung-uk Kim         c->mask_k |= SSL_kKRB5;
12127bded2dbSJung-uk Kim     }
12137bded2dbSJung-uk Kim # endif
12147bded2dbSJung-uk Kim # ifndef OPENSSL_NO_PSK
12157bded2dbSJung-uk Kim     /* with PSK there must be client callback set */
12167bded2dbSJung-uk Kim     if (!s->psk_client_callback) {
12177bded2dbSJung-uk Kim         c->mask_a |= SSL_aPSK;
12187bded2dbSJung-uk Kim         c->mask_k |= SSL_kPSK;
12197bded2dbSJung-uk Kim     }
12207bded2dbSJung-uk Kim # endif                         /* OPENSSL_NO_PSK */
12217bded2dbSJung-uk Kim # ifndef OPENSSL_NO_SRP
12227bded2dbSJung-uk Kim     if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
12237bded2dbSJung-uk Kim         c->mask_a |= SSL_aSRP;
12247bded2dbSJung-uk Kim         c->mask_k |= SSL_kSRP;
12257bded2dbSJung-uk Kim     }
12267bded2dbSJung-uk Kim # endif
12277bded2dbSJung-uk Kim     c->valid = 1;
12281f13597dSJung-uk Kim }
12291f13597dSJung-uk Kim 
12306f9291ceSJung-uk Kim unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
12317bded2dbSJung-uk Kim                                           unsigned char *limit, int *al)
1232db522d3aSSimon L. B. Nielsen {
1233db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
1234a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
1235a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
12367bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
12377bded2dbSJung-uk Kim     /* See if we support any ECC ciphersuites */
12387bded2dbSJung-uk Kim     int using_ecc = 0;
12397bded2dbSJung-uk Kim     if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
12407bded2dbSJung-uk Kim         int i;
12417bded2dbSJung-uk Kim         unsigned long alg_k, alg_a;
12427bded2dbSJung-uk Kim         STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
12437bded2dbSJung-uk Kim 
12447bded2dbSJung-uk Kim         for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
12457bded2dbSJung-uk Kim             SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
12467bded2dbSJung-uk Kim 
12477bded2dbSJung-uk Kim             alg_k = c->algorithm_mkey;
12487bded2dbSJung-uk Kim             alg_a = c->algorithm_auth;
12497bded2dbSJung-uk Kim             if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)
12507bded2dbSJung-uk Kim                  || (alg_a & SSL_aECDSA))) {
12517bded2dbSJung-uk Kim                 using_ecc = 1;
12527bded2dbSJung-uk Kim                 break;
12537bded2dbSJung-uk Kim             }
12547bded2dbSJung-uk Kim         }
12557bded2dbSJung-uk Kim     }
12567bded2dbSJung-uk Kim # endif
1257db522d3aSSimon L. B. Nielsen 
12586a599222SSimon L. B. Nielsen     /* don't add extensions for SSLv3 unless doing secure renegotiation */
12596f9291ceSJung-uk Kim     if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding)
1260a93cbc2bSJung-uk Kim         return orig;
12616a599222SSimon L. B. Nielsen 
1262db522d3aSSimon L. B. Nielsen     ret += 2;
1263db522d3aSSimon L. B. Nielsen 
12646f9291ceSJung-uk Kim     if (ret >= limit)
12656f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
1266db522d3aSSimon L. B. Nielsen 
12676f9291ceSJung-uk Kim     if (s->tlsext_hostname != NULL) {
1268db522d3aSSimon L. B. Nielsen         /* Add TLS extension servername to the Client Hello message */
12696cf8931aSJung-uk Kim         size_t size_str;
1270db522d3aSSimon L. B. Nielsen 
12716f9291ceSJung-uk Kim         /*-
12726f9291ceSJung-uk Kim          * check for enough space.
12736f9291ceSJung-uk Kim          * 4 for the servername type and entension length
12746f9291ceSJung-uk Kim          * 2 for servernamelist length
12756f9291ceSJung-uk Kim          * 1 for the hostname type
12766f9291ceSJung-uk Kim          * 2 for hostname length
12776f9291ceSJung-uk Kim          * + hostname length
1278db522d3aSSimon L. B. Nielsen          */
12796cf8931aSJung-uk Kim         size_str = strlen(s->tlsext_hostname);
12806cf8931aSJung-uk Kim         if (CHECKLEN(ret, 9 + size_str, limit))
1281db522d3aSSimon L. B. Nielsen             return NULL;
1282db522d3aSSimon L. B. Nielsen 
1283db522d3aSSimon L. B. Nielsen         /* extension type and length */
1284db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_server_name, ret);
1285db522d3aSSimon L. B. Nielsen         s2n(size_str + 5, ret);
1286db522d3aSSimon L. B. Nielsen 
1287db522d3aSSimon L. B. Nielsen         /* length of servername list */
1288db522d3aSSimon L. B. Nielsen         s2n(size_str + 3, ret);
1289db522d3aSSimon L. B. Nielsen 
1290db522d3aSSimon L. B. Nielsen         /* hostname type, length and hostname */
1291db522d3aSSimon L. B. Nielsen         *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name;
1292db522d3aSSimon L. B. Nielsen         s2n(size_str, ret);
1293db522d3aSSimon L. B. Nielsen         memcpy(ret, s->tlsext_hostname, size_str);
1294db522d3aSSimon L. B. Nielsen         ret += size_str;
1295db522d3aSSimon L. B. Nielsen     }
1296db522d3aSSimon L. B. Nielsen 
12976a599222SSimon L. B. Nielsen     /* Add RI if renegotiating */
12986f9291ceSJung-uk Kim     if (s->renegotiate) {
12996a599222SSimon L. B. Nielsen         int el;
13006a599222SSimon L. B. Nielsen 
13016f9291ceSJung-uk Kim         if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
13026a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13036a599222SSimon L. B. Nielsen             return NULL;
13046a599222SSimon L. B. Nielsen         }
13056a599222SSimon L. B. Nielsen 
13066f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
13076f9291ceSJung-uk Kim             return NULL;
13086a599222SSimon L. B. Nielsen 
13096a599222SSimon L. B. Nielsen         s2n(TLSEXT_TYPE_renegotiate, ret);
13106a599222SSimon L. B. Nielsen         s2n(el, ret);
13116a599222SSimon L. B. Nielsen 
13126f9291ceSJung-uk Kim         if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
13136a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13146a599222SSimon L. B. Nielsen             return NULL;
13156a599222SSimon L. B. Nielsen         }
13166a599222SSimon L. B. Nielsen 
13176a599222SSimon L. B. Nielsen         ret += el;
13186a599222SSimon L. B. Nielsen     }
13191f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP
13201f13597dSJung-uk Kim     /* Add SRP username if there is one */
13216f9291ceSJung-uk Kim     if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
13226f9291ceSJung-uk Kim                                      * Client Hello message */
13231f13597dSJung-uk Kim 
13246cf8931aSJung-uk Kim         size_t login_len = strlen(s->srp_ctx.login);
13256f9291ceSJung-uk Kim         if (login_len > 255 || login_len == 0) {
13261f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13271f13597dSJung-uk Kim             return NULL;
13281f13597dSJung-uk Kim         }
13291f13597dSJung-uk Kim 
13306f9291ceSJung-uk Kim         /*-
13316f9291ceSJung-uk Kim          * check for enough space.
13326f9291ceSJung-uk Kim          * 4 for the srp type type and entension length
13336f9291ceSJung-uk Kim          * 1 for the srp user identity
13346f9291ceSJung-uk Kim          * + srp user identity length
13351f13597dSJung-uk Kim          */
13366cf8931aSJung-uk Kim         if (CHECKLEN(ret, 5 + login_len, limit))
13376f9291ceSJung-uk Kim             return NULL;
13381f13597dSJung-uk Kim 
13391f13597dSJung-uk Kim         /* fill in the extension */
13401f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_srp, ret);
13411f13597dSJung-uk Kim         s2n(login_len + 1, ret);
13421f13597dSJung-uk Kim         (*ret++) = (unsigned char)login_len;
13431f13597dSJung-uk Kim         memcpy(ret, s->srp_ctx.login, login_len);
13441f13597dSJung-uk Kim         ret += login_len;
13451f13597dSJung-uk Kim     }
13461f13597dSJung-uk Kim # endif
13471f13597dSJung-uk Kim 
13481f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
13497bded2dbSJung-uk Kim     if (using_ecc) {
13506f9291ceSJung-uk Kim         /*
13516f9291ceSJung-uk Kim          * Add TLS extension ECPointFormats to the ClientHello message
13526f9291ceSJung-uk Kim          */
13537bded2dbSJung-uk Kim         const unsigned char *pcurves, *pformats;
13547bded2dbSJung-uk Kim         size_t num_curves, num_formats, curves_list_len;
13557bded2dbSJung-uk Kim 
13567bded2dbSJung-uk Kim         tls1_get_formatlist(s, &pformats, &num_formats);
13571f13597dSJung-uk Kim 
13587bded2dbSJung-uk Kim         if (num_formats > 255) {
13591f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13601f13597dSJung-uk Kim             return NULL;
13611f13597dSJung-uk Kim         }
13626cf8931aSJung-uk Kim         /*-
13636cf8931aSJung-uk Kim          * check for enough space.
13646cf8931aSJung-uk Kim          * 4 bytes for the ec point formats type and extension length
13656cf8931aSJung-uk Kim          * 1 byte for the length of the formats
13666cf8931aSJung-uk Kim          * + formats length
13676cf8931aSJung-uk Kim          */
13686cf8931aSJung-uk Kim         if (CHECKLEN(ret, 5 + num_formats, limit))
13696cf8931aSJung-uk Kim             return NULL;
13701f13597dSJung-uk Kim 
13711f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
13727bded2dbSJung-uk Kim         /* The point format list has 1-byte length. */
13737bded2dbSJung-uk Kim         s2n(num_formats + 1, ret);
13747bded2dbSJung-uk Kim         *(ret++) = (unsigned char)num_formats;
13757bded2dbSJung-uk Kim         memcpy(ret, pformats, num_formats);
13767bded2dbSJung-uk Kim         ret += num_formats;
13777bded2dbSJung-uk Kim 
13786f9291ceSJung-uk Kim         /*
13796f9291ceSJung-uk Kim          * Add TLS extension EllipticCurves to the ClientHello message
13806f9291ceSJung-uk Kim          */
13817bded2dbSJung-uk Kim         pcurves = s->tlsext_ellipticcurvelist;
13827bded2dbSJung-uk Kim         if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
13837bded2dbSJung-uk Kim             return NULL;
13841f13597dSJung-uk Kim 
13857bded2dbSJung-uk Kim         if (num_curves > 65532 / 2) {
13861f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13871f13597dSJung-uk Kim             return NULL;
13881f13597dSJung-uk Kim         }
13897bded2dbSJung-uk Kim         curves_list_len = 2 * num_curves;
13906cf8931aSJung-uk Kim         /*-
13916cf8931aSJung-uk Kim          * check for enough space.
13926cf8931aSJung-uk Kim          * 4 bytes for the ec curves type and extension length
13936cf8931aSJung-uk Kim          * 2 bytes for the curve list length
13946cf8931aSJung-uk Kim          * + curve list length
13956cf8931aSJung-uk Kim          */
13966cf8931aSJung-uk Kim         if (CHECKLEN(ret, 6 + curves_list_len, limit))
13976cf8931aSJung-uk Kim             return NULL;
13986cf8931aSJung-uk Kim 
13991f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_elliptic_curves, ret);
14007bded2dbSJung-uk Kim         s2n(curves_list_len + 2, ret);
14017bded2dbSJung-uk Kim         s2n(curves_list_len, ret);
14027bded2dbSJung-uk Kim         memcpy(ret, pcurves, curves_list_len);
14037bded2dbSJung-uk Kim         ret += curves_list_len;
14041f13597dSJung-uk Kim     }
14051f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
14066a599222SSimon L. B. Nielsen 
14076f9291ceSJung-uk Kim     if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
14086cf8931aSJung-uk Kim         size_t ticklen;
14096a599222SSimon L. B. Nielsen         if (!s->new_session && s->session && s->session->tlsext_tick)
1410db522d3aSSimon L. B. Nielsen             ticklen = s->session->tlsext_ticklen;
14111f13597dSJung-uk Kim         else if (s->session && s->tlsext_session_ticket &&
14126f9291ceSJung-uk Kim                  s->tlsext_session_ticket->data) {
14131f13597dSJung-uk Kim             ticklen = s->tlsext_session_ticket->length;
14141f13597dSJung-uk Kim             s->session->tlsext_tick = OPENSSL_malloc(ticklen);
14151f13597dSJung-uk Kim             if (!s->session->tlsext_tick)
14161f13597dSJung-uk Kim                 return NULL;
14171f13597dSJung-uk Kim             memcpy(s->session->tlsext_tick,
14186f9291ceSJung-uk Kim                    s->tlsext_session_ticket->data, ticklen);
14191f13597dSJung-uk Kim             s->session->tlsext_ticklen = ticklen;
14206f9291ceSJung-uk Kim         } else
1421db522d3aSSimon L. B. Nielsen             ticklen = 0;
14221f13597dSJung-uk Kim         if (ticklen == 0 && s->tlsext_session_ticket &&
14231f13597dSJung-uk Kim             s->tlsext_session_ticket->data == NULL)
14241f13597dSJung-uk Kim             goto skip_ext;
14256f9291ceSJung-uk Kim         /*
14266f9291ceSJung-uk Kim          * Check for enough room 2 for extension type, 2 for len rest for
14276f9291ceSJung-uk Kim          * ticket
1428db522d3aSSimon L. B. Nielsen          */
14296cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4 + ticklen, limit))
14306f9291ceSJung-uk Kim             return NULL;
1431db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
1432db522d3aSSimon L. B. Nielsen         s2n(ticklen, ret);
14336cf8931aSJung-uk Kim         if (ticklen > 0) {
1434db522d3aSSimon L. B. Nielsen             memcpy(ret, s->session->tlsext_tick, ticklen);
1435db522d3aSSimon L. B. Nielsen             ret += ticklen;
1436db522d3aSSimon L. B. Nielsen         }
1437db522d3aSSimon L. B. Nielsen     }
14381f13597dSJung-uk Kim  skip_ext:
14391f13597dSJung-uk Kim 
1440aeb5019cSJung-uk Kim     if (SSL_CLIENT_USE_SIGALGS(s)) {
14417bded2dbSJung-uk Kim         size_t salglen;
14427bded2dbSJung-uk Kim         const unsigned char *salg;
1443ed7112f0SJung-uk Kim         salglen = tls12_get_psigalgs(s, 1, &salg);
14446cf8931aSJung-uk Kim 
14456cf8931aSJung-uk Kim         /*-
14466cf8931aSJung-uk Kim          * check for enough space.
14476cf8931aSJung-uk Kim          * 4 bytes for the sigalgs type and extension length
14486cf8931aSJung-uk Kim          * 2 bytes for the sigalg list length
14496cf8931aSJung-uk Kim          * + sigalg list length
14506cf8931aSJung-uk Kim          */
14516cf8931aSJung-uk Kim         if (CHECKLEN(ret, salglen + 6, limit))
14521f13597dSJung-uk Kim             return NULL;
14531f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_signature_algorithms, ret);
14547bded2dbSJung-uk Kim         s2n(salglen + 2, ret);
14557bded2dbSJung-uk Kim         s2n(salglen, ret);
14567bded2dbSJung-uk Kim         memcpy(ret, salg, salglen);
14577bded2dbSJung-uk Kim         ret += salglen;
14581f13597dSJung-uk Kim     }
14591f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
14607bded2dbSJung-uk Kim     if (s->s3->client_opaque_prf_input != NULL) {
14611f13597dSJung-uk Kim         size_t col = s->s3->client_opaque_prf_input_len;
14621f13597dSJung-uk Kim 
14631f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - col < 0))
14641f13597dSJung-uk Kim             return NULL;
14651f13597dSJung-uk Kim         if (col > 0xFFFD)       /* can't happen */
14661f13597dSJung-uk Kim             return NULL;
14671f13597dSJung-uk Kim 
14681f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
14691f13597dSJung-uk Kim         s2n(col + 2, ret);
14701f13597dSJung-uk Kim         s2n(col, ret);
14711f13597dSJung-uk Kim         memcpy(ret, s->s3->client_opaque_prf_input, col);
14721f13597dSJung-uk Kim         ret += col;
14731f13597dSJung-uk Kim     }
14741f13597dSJung-uk Kim # endif
1475db522d3aSSimon L. B. Nielsen 
14767bded2dbSJung-uk Kim     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
1477db522d3aSSimon L. B. Nielsen         int i;
14786cf8931aSJung-uk Kim         size_t extlen, idlen;
14796cf8931aSJung-uk Kim         int lentmp;
1480db522d3aSSimon L. B. Nielsen         OCSP_RESPID *id;
1481db522d3aSSimon L. B. Nielsen 
1482db522d3aSSimon L. B. Nielsen         idlen = 0;
14836f9291ceSJung-uk Kim         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
1484db522d3aSSimon L. B. Nielsen             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
14856cf8931aSJung-uk Kim             lentmp = i2d_OCSP_RESPID(id, NULL);
14866cf8931aSJung-uk Kim             if (lentmp <= 0)
1487db522d3aSSimon L. B. Nielsen                 return NULL;
14886cf8931aSJung-uk Kim             idlen += (size_t)lentmp + 2;
1489db522d3aSSimon L. B. Nielsen         }
1490db522d3aSSimon L. B. Nielsen 
14916f9291ceSJung-uk Kim         if (s->tlsext_ocsp_exts) {
14926cf8931aSJung-uk Kim             lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
14936cf8931aSJung-uk Kim             if (lentmp < 0)
1494db522d3aSSimon L. B. Nielsen                 return NULL;
14956cf8931aSJung-uk Kim             extlen = (size_t)lentmp;
14966f9291ceSJung-uk Kim         } else
1497db522d3aSSimon L. B. Nielsen             extlen = 0;
1498db522d3aSSimon L. B. Nielsen 
1499db522d3aSSimon L. B. Nielsen         if (extlen + idlen > 0xFFF0)
1500db522d3aSSimon L. B. Nielsen             return NULL;
15016cf8931aSJung-uk Kim         /*
15026cf8931aSJung-uk Kim          * 2 bytes for status request type
15036cf8931aSJung-uk Kim          * 2 bytes for status request len
15046cf8931aSJung-uk Kim          * 1 byte for OCSP request type
15056cf8931aSJung-uk Kim          * 2 bytes for length of ids
15066cf8931aSJung-uk Kim          * 2 bytes for length of extensions
15076cf8931aSJung-uk Kim          * + length of ids
15086cf8931aSJung-uk Kim          * + length of extensions
15096cf8931aSJung-uk Kim          */
15106cf8931aSJung-uk Kim         if (CHECKLEN(ret, 9 + idlen + extlen, limit))
15116cf8931aSJung-uk Kim             return NULL;
15126cf8931aSJung-uk Kim 
15136cf8931aSJung-uk Kim         s2n(TLSEXT_TYPE_status_request, ret);
1514db522d3aSSimon L. B. Nielsen         s2n(extlen + idlen + 5, ret);
1515db522d3aSSimon L. B. Nielsen         *(ret++) = TLSEXT_STATUSTYPE_ocsp;
1516db522d3aSSimon L. B. Nielsen         s2n(idlen, ret);
15176f9291ceSJung-uk Kim         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
1518db522d3aSSimon L. B. Nielsen             /* save position of id len */
1519db522d3aSSimon L. B. Nielsen             unsigned char *q = ret;
1520db522d3aSSimon L. B. Nielsen             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
1521db522d3aSSimon L. B. Nielsen             /* skip over id len */
1522db522d3aSSimon L. B. Nielsen             ret += 2;
15236cf8931aSJung-uk Kim             lentmp = i2d_OCSP_RESPID(id, &ret);
1524db522d3aSSimon L. B. Nielsen             /* write id len */
15256cf8931aSJung-uk Kim             s2n(lentmp, q);
1526db522d3aSSimon L. B. Nielsen         }
1527db522d3aSSimon L. B. Nielsen         s2n(extlen, ret);
1528db522d3aSSimon L. B. Nielsen         if (extlen > 0)
1529db522d3aSSimon L. B. Nielsen             i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
1530db522d3aSSimon L. B. Nielsen     }
15311f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
15321f13597dSJung-uk Kim     /* Add Heartbeat extension */
15336cf8931aSJung-uk Kim 
15346cf8931aSJung-uk Kim     /*-
15356cf8931aSJung-uk Kim      * check for enough space.
15366cf8931aSJung-uk Kim      * 4 bytes for the heartbeat ext type and extension length
15376cf8931aSJung-uk Kim      * 1 byte for the mode
15386cf8931aSJung-uk Kim      */
15396cf8931aSJung-uk Kim     if (CHECKLEN(ret, 5, limit))
154094ad176cSJung-uk Kim         return NULL;
15416cf8931aSJung-uk Kim 
15421f13597dSJung-uk Kim     s2n(TLSEXT_TYPE_heartbeat, ret);
15431f13597dSJung-uk Kim     s2n(1, ret);
15446f9291ceSJung-uk Kim     /*-
15456f9291ceSJung-uk Kim      * Set mode:
15461f13597dSJung-uk Kim      * 1: peer may send requests
15471f13597dSJung-uk Kim      * 2: peer not allowed to send requests
15481f13597dSJung-uk Kim      */
15491f13597dSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
15501f13597dSJung-uk Kim         *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
15511f13597dSJung-uk Kim     else
15521f13597dSJung-uk Kim         *(ret++) = SSL_TLSEXT_HB_ENABLED;
15531f13597dSJung-uk Kim # endif
15541f13597dSJung-uk Kim 
15551f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
15566f9291ceSJung-uk Kim     if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
15576f9291ceSJung-uk Kim         /*
15586f9291ceSJung-uk Kim          * The client advertises an emtpy extension to indicate its support
15596f9291ceSJung-uk Kim          * for Next Protocol Negotiation
15606f9291ceSJung-uk Kim          */
15616cf8931aSJung-uk Kim 
15626cf8931aSJung-uk Kim         /*-
15636cf8931aSJung-uk Kim          * check for enough space.
15646cf8931aSJung-uk Kim          * 4 bytes for the NPN ext type and extension length
15656cf8931aSJung-uk Kim          */
15666cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4, limit))
15671f13597dSJung-uk Kim             return NULL;
15681f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_next_proto_neg, ret);
15691f13597dSJung-uk Kim         s2n(0, ret);
15701f13597dSJung-uk Kim     }
15711f13597dSJung-uk Kim # endif
15721f13597dSJung-uk Kim 
15737bded2dbSJung-uk Kim     if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
15746cf8931aSJung-uk Kim         /*-
15756cf8931aSJung-uk Kim          * check for enough space.
15766cf8931aSJung-uk Kim          * 4 bytes for the ALPN type and extension length
15776cf8931aSJung-uk Kim          * 2 bytes for the ALPN protocol list length
15786cf8931aSJung-uk Kim          * + ALPN protocol list length
15796cf8931aSJung-uk Kim          */
15806cf8931aSJung-uk Kim         if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
15817bded2dbSJung-uk Kim             return NULL;
15827bded2dbSJung-uk Kim         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
15837bded2dbSJung-uk Kim         s2n(2 + s->alpn_client_proto_list_len, ret);
15847bded2dbSJung-uk Kim         s2n(s->alpn_client_proto_list_len, ret);
15857bded2dbSJung-uk Kim         memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
15867bded2dbSJung-uk Kim         ret += s->alpn_client_proto_list_len;
1587b8721c16SJung-uk Kim         s->cert->alpn_sent = 1;
15887bded2dbSJung-uk Kim     }
158909286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
15906f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
15911f13597dSJung-uk Kim         int el;
15921f13597dSJung-uk Kim 
15931f13597dSJung-uk Kim         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
15941f13597dSJung-uk Kim 
15956cf8931aSJung-uk Kim         /*-
15966cf8931aSJung-uk Kim          * check for enough space.
15976cf8931aSJung-uk Kim          * 4 bytes for the SRTP type and extension length
15986cf8931aSJung-uk Kim          * + SRTP profiles length
15996cf8931aSJung-uk Kim          */
16006cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4 + el, limit))
16016f9291ceSJung-uk Kim             return NULL;
16021f13597dSJung-uk Kim 
16031f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
16041f13597dSJung-uk Kim         s2n(el, ret);
16051f13597dSJung-uk Kim 
16066f9291ceSJung-uk Kim         if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
16071f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16081f13597dSJung-uk Kim             return NULL;
16091f13597dSJung-uk Kim         }
16101f13597dSJung-uk Kim         ret += el;
16111f13597dSJung-uk Kim     }
161209286989SJung-uk Kim # endif
16137bded2dbSJung-uk Kim     custom_ext_init(&s->cert->cli_ext);
16147bded2dbSJung-uk Kim     /* Add custom TLS Extensions to ClientHello */
16157bded2dbSJung-uk Kim     if (!custom_ext_add(s, 0, &ret, limit, al))
16167bded2dbSJung-uk Kim         return NULL;
16177bded2dbSJung-uk Kim 
16186f9291ceSJung-uk Kim     /*
16196f9291ceSJung-uk Kim      * Add padding to workaround bugs in F5 terminators. See
16206f9291ceSJung-uk Kim      * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
16216f9291ceSJung-uk Kim      * code works out the length of all existing extensions it MUST always
16226f9291ceSJung-uk Kim      * appear last.
1623560ede85SJung-uk Kim      */
16246f9291ceSJung-uk Kim     if (s->options & SSL_OP_TLSEXT_PADDING) {
1625560ede85SJung-uk Kim         int hlen = ret - (unsigned char *)s->init_buf->data;
16266f9291ceSJung-uk Kim         /*
16276f9291ceSJung-uk Kim          * The code in s23_clnt.c to build ClientHello messages includes the
16286f9291ceSJung-uk Kim          * 5-byte record header in the buffer, while the code in s3_clnt.c
16296f9291ceSJung-uk Kim          * does not.
163094ad176cSJung-uk Kim          */
1631560ede85SJung-uk Kim         if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
1632560ede85SJung-uk Kim             hlen -= 5;
16336f9291ceSJung-uk Kim         if (hlen > 0xff && hlen < 0x200) {
1634560ede85SJung-uk Kim             hlen = 0x200 - hlen;
1635560ede85SJung-uk Kim             if (hlen >= 4)
1636560ede85SJung-uk Kim                 hlen -= 4;
1637560ede85SJung-uk Kim             else
1638560ede85SJung-uk Kim                 hlen = 0;
1639560ede85SJung-uk Kim 
16406cf8931aSJung-uk Kim             /*-
16416cf8931aSJung-uk Kim              * check for enough space. Strictly speaking we know we've already
16426cf8931aSJung-uk Kim              * got enough space because to get here the message size is < 0x200,
16436cf8931aSJung-uk Kim              * but we know that we've allocated far more than that in the buffer
16446cf8931aSJung-uk Kim              * - but for consistency and robustness we're going to check anyway.
16456cf8931aSJung-uk Kim              *
16466cf8931aSJung-uk Kim              * 4 bytes for the padding type and extension length
16476cf8931aSJung-uk Kim              * + padding length
16486cf8931aSJung-uk Kim              */
16496cf8931aSJung-uk Kim             if (CHECKLEN(ret, 4 + hlen, limit))
16506cf8931aSJung-uk Kim                 return NULL;
1651560ede85SJung-uk Kim             s2n(TLSEXT_TYPE_padding, ret);
1652560ede85SJung-uk Kim             s2n(hlen, ret);
1653560ede85SJung-uk Kim             memset(ret, 0, hlen);
1654560ede85SJung-uk Kim             ret += hlen;
1655560ede85SJung-uk Kim         }
1656560ede85SJung-uk Kim     }
1657560ede85SJung-uk Kim 
1658a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
1659a93cbc2bSJung-uk Kim         return orig;
1660db522d3aSSimon L. B. Nielsen 
1661a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
1662db522d3aSSimon L. B. Nielsen     return ret;
1663db522d3aSSimon L. B. Nielsen }
1664db522d3aSSimon L. B. Nielsen 
16656f9291ceSJung-uk Kim unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
16667bded2dbSJung-uk Kim                                           unsigned char *limit, int *al)
1667db522d3aSSimon L. B. Nielsen {
1668db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
1669a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
1670a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
16711f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
16721f13597dSJung-uk Kim     int next_proto_neg_seen;
16731f13597dSJung-uk Kim # endif
16747bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
16757bded2dbSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
16767bded2dbSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
16777bded2dbSJung-uk Kim     int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
16787bded2dbSJung-uk Kim         || (alg_a & SSL_aECDSA);
16797bded2dbSJung-uk Kim     using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
16807bded2dbSJung-uk Kim # endif
16816f9291ceSJung-uk Kim     /*
16826f9291ceSJung-uk Kim      * don't add extensions for SSLv3, unless doing secure renegotiation
16836f9291ceSJung-uk Kim      */
16846a599222SSimon L. B. Nielsen     if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
1685a93cbc2bSJung-uk Kim         return orig;
16866a599222SSimon L. B. Nielsen 
1687db522d3aSSimon L. B. Nielsen     ret += 2;
16886f9291ceSJung-uk Kim     if (ret >= limit)
16896f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
1690db522d3aSSimon L. B. Nielsen 
16916f9291ceSJung-uk Kim     if (!s->hit && s->servername_done == 1
16926f9291ceSJung-uk Kim         && s->session->tlsext_hostname != NULL) {
16936f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
16946f9291ceSJung-uk Kim             return NULL;
1695db522d3aSSimon L. B. Nielsen 
1696db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_server_name, ret);
1697db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1698db522d3aSSimon L. B. Nielsen     }
1699db522d3aSSimon L. B. Nielsen 
17006f9291ceSJung-uk Kim     if (s->s3->send_connection_binding) {
17016a599222SSimon L. B. Nielsen         int el;
17026a599222SSimon L. B. Nielsen 
17036f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
17046a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
17056a599222SSimon L. B. Nielsen             return NULL;
17066a599222SSimon L. B. Nielsen         }
17076a599222SSimon L. B. Nielsen 
17086cf8931aSJung-uk Kim         /*-
17096cf8931aSJung-uk Kim          * check for enough space.
17106cf8931aSJung-uk Kim          * 4 bytes for the reneg type and extension length
17116cf8931aSJung-uk Kim          * + reneg data length
17126cf8931aSJung-uk Kim          */
17136cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4 + el, limit))
17146f9291ceSJung-uk Kim             return NULL;
17156a599222SSimon L. B. Nielsen 
17166a599222SSimon L. B. Nielsen         s2n(TLSEXT_TYPE_renegotiate, ret);
17176a599222SSimon L. B. Nielsen         s2n(el, ret);
17186a599222SSimon L. B. Nielsen 
17196f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
17206a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
17216a599222SSimon L. B. Nielsen             return NULL;
17226a599222SSimon L. B. Nielsen         }
17236a599222SSimon L. B. Nielsen 
17246a599222SSimon L. B. Nielsen         ret += el;
17256a599222SSimon L. B. Nielsen     }
17261f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
17277bded2dbSJung-uk Kim     if (using_ecc) {
17287bded2dbSJung-uk Kim         const unsigned char *plist;
17297bded2dbSJung-uk Kim         size_t plistlen;
17306f9291ceSJung-uk Kim         /*
17316f9291ceSJung-uk Kim          * Add TLS extension ECPointFormats to the ServerHello message
17326f9291ceSJung-uk Kim          */
17331f13597dSJung-uk Kim 
17347bded2dbSJung-uk Kim         tls1_get_formatlist(s, &plist, &plistlen);
17357bded2dbSJung-uk Kim 
17367bded2dbSJung-uk Kim         if (plistlen > 255) {
17371f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
17381f13597dSJung-uk Kim             return NULL;
17391f13597dSJung-uk Kim         }
17401f13597dSJung-uk Kim 
17416cf8931aSJung-uk Kim         /*-
17426cf8931aSJung-uk Kim          * check for enough space.
17436cf8931aSJung-uk Kim          * 4 bytes for the ec points format type and extension length
17446cf8931aSJung-uk Kim          * 1 byte for the points format list length
17456cf8931aSJung-uk Kim          * + length of points format list
17466cf8931aSJung-uk Kim          */
17476cf8931aSJung-uk Kim         if (CHECKLEN(ret, 5 + plistlen, limit))
17486cf8931aSJung-uk Kim             return NULL;
17496cf8931aSJung-uk Kim 
17501f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
17517bded2dbSJung-uk Kim         s2n(plistlen + 1, ret);
17527bded2dbSJung-uk Kim         *(ret++) = (unsigned char)plistlen;
17537bded2dbSJung-uk Kim         memcpy(ret, plist, plistlen);
17547bded2dbSJung-uk Kim         ret += plistlen;
17551f13597dSJung-uk Kim 
17561f13597dSJung-uk Kim     }
17576f9291ceSJung-uk Kim     /*
17586f9291ceSJung-uk Kim      * Currently the server should not respond with a SupportedCurves
17596f9291ceSJung-uk Kim      * extension
17606f9291ceSJung-uk Kim      */
17611f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
17621f13597dSJung-uk Kim 
17636f9291ceSJung-uk Kim     if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
17646cf8931aSJung-uk Kim         /*-
17656cf8931aSJung-uk Kim          * check for enough space.
17666cf8931aSJung-uk Kim          * 4 bytes for the Ticket type and extension length
17676cf8931aSJung-uk Kim          */
17686cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4, limit))
17696f9291ceSJung-uk Kim             return NULL;
1770db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
1771db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1772ed7112f0SJung-uk Kim     } else {
1773ed7112f0SJung-uk Kim         /* if we don't add the above TLSEXT, we can't add a session ticket later */
1774ed7112f0SJung-uk Kim         s->tlsext_ticket_expected = 0;
1775db522d3aSSimon L. B. Nielsen     }
1776db522d3aSSimon L. B. Nielsen 
17776f9291ceSJung-uk Kim     if (s->tlsext_status_expected) {
17786cf8931aSJung-uk Kim         /*-
17796cf8931aSJung-uk Kim          * check for enough space.
17806cf8931aSJung-uk Kim          * 4 bytes for the Status request type and extension length
17816cf8931aSJung-uk Kim          */
17826cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4, limit))
17836f9291ceSJung-uk Kim             return NULL;
1784db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_status_request, ret);
1785db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1786db522d3aSSimon L. B. Nielsen     }
17871f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
17887bded2dbSJung-uk Kim     if (s->s3->server_opaque_prf_input != NULL) {
17891f13597dSJung-uk Kim         size_t sol = s->s3->server_opaque_prf_input_len;
17901f13597dSJung-uk Kim 
17911f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - sol) < 0)
17921f13597dSJung-uk Kim             return NULL;
17931f13597dSJung-uk Kim         if (sol > 0xFFFD)       /* can't happen */
17941f13597dSJung-uk Kim             return NULL;
17951f13597dSJung-uk Kim 
17961f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
17971f13597dSJung-uk Kim         s2n(sol + 2, ret);
17981f13597dSJung-uk Kim         s2n(sol, ret);
17991f13597dSJung-uk Kim         memcpy(ret, s->s3->server_opaque_prf_input, sol);
18001f13597dSJung-uk Kim         ret += sol;
18011f13597dSJung-uk Kim     }
18021f13597dSJung-uk Kim # endif
18031f13597dSJung-uk Kim 
180409286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
18056f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && s->srtp_profile) {
18061f13597dSJung-uk Kim         int el;
18071f13597dSJung-uk Kim 
18081f13597dSJung-uk Kim         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
18091f13597dSJung-uk Kim 
18106cf8931aSJung-uk Kim         /*-
18116cf8931aSJung-uk Kim          * check for enough space.
18126cf8931aSJung-uk Kim          * 4 bytes for the SRTP profiles type and extension length
18136cf8931aSJung-uk Kim          * + length of the SRTP profiles list
18146cf8931aSJung-uk Kim          */
18156cf8931aSJung-uk Kim         if (CHECKLEN(ret, 4 + el, limit))
18166f9291ceSJung-uk Kim             return NULL;
18171f13597dSJung-uk Kim 
18181f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
18191f13597dSJung-uk Kim         s2n(el, ret);
18201f13597dSJung-uk Kim 
18216f9291ceSJung-uk Kim         if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
18221f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
18231f13597dSJung-uk Kim             return NULL;
18241f13597dSJung-uk Kim         }
18251f13597dSJung-uk Kim         ret += el;
18261f13597dSJung-uk Kim     }
182709286989SJung-uk Kim # endif
18281f13597dSJung-uk Kim 
18296f9291ceSJung-uk Kim     if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
18306f9291ceSJung-uk Kim          || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
18316f9291ceSJung-uk Kim         && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
18326f9291ceSJung-uk Kim         const unsigned char cryptopro_ext[36] = {
18331f13597dSJung-uk Kim             0xfd, 0xe8,         /* 65000 */
18341f13597dSJung-uk Kim             0x00, 0x20,         /* 32 bytes length */
18351f13597dSJung-uk Kim             0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
18361f13597dSJung-uk Kim             0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
18371f13597dSJung-uk Kim             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
18386f9291ceSJung-uk Kim             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
18396f9291ceSJung-uk Kim         };
18406cf8931aSJung-uk Kim 
18416cf8931aSJung-uk Kim         /* check for enough space. */
18426cf8931aSJung-uk Kim         if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
18436f9291ceSJung-uk Kim             return NULL;
18446cf8931aSJung-uk Kim         memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
18456cf8931aSJung-uk Kim         ret += sizeof(cryptopro_ext);
18461f13597dSJung-uk Kim 
18471f13597dSJung-uk Kim     }
18481f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
18491f13597dSJung-uk Kim     /* Add Heartbeat extension if we've received one */
18506f9291ceSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
18516cf8931aSJung-uk Kim         /*-
18526cf8931aSJung-uk Kim          * check for enough space.
18536cf8931aSJung-uk Kim          * 4 bytes for the Heartbeat type and extension length
18546cf8931aSJung-uk Kim          * 1 byte for the mode
18556cf8931aSJung-uk Kim          */
18566cf8931aSJung-uk Kim         if (CHECKLEN(ret, 5, limit))
185794ad176cSJung-uk Kim             return NULL;
18581f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_heartbeat, ret);
18591f13597dSJung-uk Kim         s2n(1, ret);
18606f9291ceSJung-uk Kim         /*-
18616f9291ceSJung-uk Kim          * Set mode:
18621f13597dSJung-uk Kim          * 1: peer may send requests
18631f13597dSJung-uk Kim          * 2: peer not allowed to send requests
18641f13597dSJung-uk Kim          */
18651f13597dSJung-uk Kim         if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
18661f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
18671f13597dSJung-uk Kim         else
18681f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_ENABLED;
18691f13597dSJung-uk Kim 
18701f13597dSJung-uk Kim     }
18711f13597dSJung-uk Kim # endif
18721f13597dSJung-uk Kim 
18731f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
18741f13597dSJung-uk Kim     next_proto_neg_seen = s->s3->next_proto_neg_seen;
18751f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
18766f9291ceSJung-uk Kim     if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
18771f13597dSJung-uk Kim         const unsigned char *npa;
18781f13597dSJung-uk Kim         unsigned int npalen;
18791f13597dSJung-uk Kim         int r;
18801f13597dSJung-uk Kim 
18816f9291ceSJung-uk Kim         r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
18826f9291ceSJung-uk Kim                                               s->
18836f9291ceSJung-uk Kim                                               ctx->next_protos_advertised_cb_arg);
18846f9291ceSJung-uk Kim         if (r == SSL_TLSEXT_ERR_OK) {
18856cf8931aSJung-uk Kim             /*-
18866cf8931aSJung-uk Kim              * check for enough space.
18876cf8931aSJung-uk Kim              * 4 bytes for the NPN type and extension length
18886cf8931aSJung-uk Kim              * + length of protocols list
18896cf8931aSJung-uk Kim              */
18906cf8931aSJung-uk Kim             if (CHECKLEN(ret, 4 + npalen, limit))
18916f9291ceSJung-uk Kim                 return NULL;
18921f13597dSJung-uk Kim             s2n(TLSEXT_TYPE_next_proto_neg, ret);
18931f13597dSJung-uk Kim             s2n(npalen, ret);
18941f13597dSJung-uk Kim             memcpy(ret, npa, npalen);
18951f13597dSJung-uk Kim             ret += npalen;
18961f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
18971f13597dSJung-uk Kim         }
18981f13597dSJung-uk Kim     }
18991f13597dSJung-uk Kim # endif
19007bded2dbSJung-uk Kim     if (!custom_ext_add(s, 1, &ret, limit, al))
19017bded2dbSJung-uk Kim         return NULL;
19027bded2dbSJung-uk Kim 
19037bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
19047bded2dbSJung-uk Kim         const unsigned char *selected = s->s3->alpn_selected;
19056cf8931aSJung-uk Kim         size_t len = s->s3->alpn_selected_len;
19067bded2dbSJung-uk Kim 
19076cf8931aSJung-uk Kim         /*-
19086cf8931aSJung-uk Kim          * check for enough space.
19096cf8931aSJung-uk Kim          * 4 bytes for the ALPN type and extension length
19106cf8931aSJung-uk Kim          * 2 bytes for ALPN data length
19116cf8931aSJung-uk Kim          * 1 byte for selected protocol length
19126cf8931aSJung-uk Kim          * + length of the selected protocol
19136cf8931aSJung-uk Kim          */
19146cf8931aSJung-uk Kim         if (CHECKLEN(ret, 7 + len, limit))
19157bded2dbSJung-uk Kim             return NULL;
19167bded2dbSJung-uk Kim         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
19177bded2dbSJung-uk Kim         s2n(3 + len, ret);
19187bded2dbSJung-uk Kim         s2n(1 + len, ret);
1919c4ad4dffSJung-uk Kim         *ret++ = (unsigned char)len;
19207bded2dbSJung-uk Kim         memcpy(ret, selected, len);
19217bded2dbSJung-uk Kim         ret += len;
19227bded2dbSJung-uk Kim     }
19231f13597dSJung-uk Kim 
1924a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
1925a93cbc2bSJung-uk Kim         return orig;
1926db522d3aSSimon L. B. Nielsen 
1927a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
1928db522d3aSSimon L. B. Nielsen     return ret;
1929db522d3aSSimon L. B. Nielsen }
1930db522d3aSSimon L. B. Nielsen 
1931de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
19326f9291ceSJung-uk Kim /*-
19336f9291ceSJung-uk Kim  * ssl_check_for_safari attempts to fingerprint Safari using OS X
1934de78d5d8SJung-uk Kim  * SecureTransport using the TLS extension block in |d|, of length |n|.
1935de78d5d8SJung-uk Kim  * Safari, since 10.6, sends exactly these extensions, in this order:
1936de78d5d8SJung-uk Kim  *   SNI,
1937de78d5d8SJung-uk Kim  *   elliptic_curves
1938de78d5d8SJung-uk Kim  *   ec_point_formats
1939de78d5d8SJung-uk Kim  *
1940de78d5d8SJung-uk Kim  * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
1941de78d5d8SJung-uk Kim  * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
1942de78d5d8SJung-uk Kim  * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
1943de78d5d8SJung-uk Kim  * 10.8..10.8.3 (which don't work).
1944de78d5d8SJung-uk Kim  */
19456f9291ceSJung-uk Kim static void ssl_check_for_safari(SSL *s, const unsigned char *data,
194680815a77SJung-uk Kim                                  const unsigned char *limit)
19476f9291ceSJung-uk Kim {
1948de78d5d8SJung-uk Kim     unsigned short type, size;
1949de78d5d8SJung-uk Kim     static const unsigned char kSafariExtensionsBlock[] = {
1950de78d5d8SJung-uk Kim         0x00, 0x0a,             /* elliptic_curves extension */
1951de78d5d8SJung-uk Kim         0x00, 0x08,             /* 8 bytes */
1952de78d5d8SJung-uk Kim         0x00, 0x06,             /* 6 bytes of curve ids */
1953de78d5d8SJung-uk Kim         0x00, 0x17,             /* P-256 */
1954de78d5d8SJung-uk Kim         0x00, 0x18,             /* P-384 */
1955de78d5d8SJung-uk Kim         0x00, 0x19,             /* P-521 */
1956de78d5d8SJung-uk Kim 
1957de78d5d8SJung-uk Kim         0x00, 0x0b,             /* ec_point_formats */
1958de78d5d8SJung-uk Kim         0x00, 0x02,             /* 2 bytes */
1959de78d5d8SJung-uk Kim         0x01,                   /* 1 point format */
1960de78d5d8SJung-uk Kim         0x00,                   /* uncompressed */
1961de78d5d8SJung-uk Kim     };
1962de78d5d8SJung-uk Kim 
1963de78d5d8SJung-uk Kim     /* The following is only present in TLS 1.2 */
1964de78d5d8SJung-uk Kim     static const unsigned char kSafariTLS12ExtensionsBlock[] = {
1965de78d5d8SJung-uk Kim         0x00, 0x0d,             /* signature_algorithms */
1966de78d5d8SJung-uk Kim         0x00, 0x0c,             /* 12 bytes */
1967de78d5d8SJung-uk Kim         0x00, 0x0a,             /* 10 bytes */
1968de78d5d8SJung-uk Kim         0x05, 0x01,             /* SHA-384/RSA */
1969de78d5d8SJung-uk Kim         0x04, 0x01,             /* SHA-256/RSA */
1970de78d5d8SJung-uk Kim         0x02, 0x01,             /* SHA-1/RSA */
1971de78d5d8SJung-uk Kim         0x04, 0x03,             /* SHA-256/ECDSA */
1972de78d5d8SJung-uk Kim         0x02, 0x03,             /* SHA-1/ECDSA */
1973de78d5d8SJung-uk Kim     };
1974de78d5d8SJung-uk Kim 
1975aeb5019cSJung-uk Kim     if (limit - data <= 2)
1976de78d5d8SJung-uk Kim         return;
1977de78d5d8SJung-uk Kim     data += 2;
1978de78d5d8SJung-uk Kim 
1979aeb5019cSJung-uk Kim     if (limit - data < 4)
1980de78d5d8SJung-uk Kim         return;
1981de78d5d8SJung-uk Kim     n2s(data, type);
1982de78d5d8SJung-uk Kim     n2s(data, size);
1983de78d5d8SJung-uk Kim 
1984de78d5d8SJung-uk Kim     if (type != TLSEXT_TYPE_server_name)
1985de78d5d8SJung-uk Kim         return;
1986de78d5d8SJung-uk Kim 
1987aeb5019cSJung-uk Kim     if (limit - data < size)
1988de78d5d8SJung-uk Kim         return;
1989de78d5d8SJung-uk Kim     data += size;
1990de78d5d8SJung-uk Kim 
19916f9291ceSJung-uk Kim     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
1992de78d5d8SJung-uk Kim         const size_t len1 = sizeof(kSafariExtensionsBlock);
1993de78d5d8SJung-uk Kim         const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
1994de78d5d8SJung-uk Kim 
1995aeb5019cSJung-uk Kim         if (limit - data != (int)(len1 + len2))
1996de78d5d8SJung-uk Kim             return;
1997de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
1998de78d5d8SJung-uk Kim             return;
1999de78d5d8SJung-uk Kim         if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
2000de78d5d8SJung-uk Kim             return;
20016f9291ceSJung-uk Kim     } else {
2002de78d5d8SJung-uk Kim         const size_t len = sizeof(kSafariExtensionsBlock);
2003de78d5d8SJung-uk Kim 
2004aeb5019cSJung-uk Kim         if (limit - data != (int)(len))
2005de78d5d8SJung-uk Kim             return;
2006de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len) != 0)
2007de78d5d8SJung-uk Kim             return;
2008de78d5d8SJung-uk Kim     }
2009de78d5d8SJung-uk Kim 
2010de78d5d8SJung-uk Kim     s->s3->is_probably_safari = 1;
2011de78d5d8SJung-uk Kim }
2012de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
2013de78d5d8SJung-uk Kim 
20147bded2dbSJung-uk Kim /*
2015b8721c16SJung-uk Kim  * tls1_alpn_handle_client_hello is called to save the ALPN extension in a
20167bded2dbSJung-uk Kim  * ClientHello.  data: the contents of the extension, not including the type
20177bded2dbSJung-uk Kim  * and length.  data_len: the number of bytes in |data| al: a pointer to the
20187bded2dbSJung-uk Kim  * alert value to send in the event of a non-zero return.  returns: 0 on
20197bded2dbSJung-uk Kim  * success.
20207bded2dbSJung-uk Kim  */
20217bded2dbSJung-uk Kim static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
20227bded2dbSJung-uk Kim                                          unsigned data_len, int *al)
20237bded2dbSJung-uk Kim {
20247bded2dbSJung-uk Kim     unsigned i;
20257bded2dbSJung-uk Kim     unsigned proto_len;
20267bded2dbSJung-uk Kim 
20277bded2dbSJung-uk Kim     if (data_len < 2)
20287bded2dbSJung-uk Kim         goto parse_error;
20297bded2dbSJung-uk Kim 
20307bded2dbSJung-uk Kim     /*
20317bded2dbSJung-uk Kim      * data should contain a uint16 length followed by a series of 8-bit,
20327bded2dbSJung-uk Kim      * length-prefixed strings.
20337bded2dbSJung-uk Kim      */
20347bded2dbSJung-uk Kim     i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]);
20357bded2dbSJung-uk Kim     data_len -= 2;
20367bded2dbSJung-uk Kim     data += 2;
20377bded2dbSJung-uk Kim     if (data_len != i)
20387bded2dbSJung-uk Kim         goto parse_error;
20397bded2dbSJung-uk Kim 
20407bded2dbSJung-uk Kim     if (data_len < 2)
20417bded2dbSJung-uk Kim         goto parse_error;
20427bded2dbSJung-uk Kim 
20437bded2dbSJung-uk Kim     for (i = 0; i < data_len;) {
20447bded2dbSJung-uk Kim         proto_len = data[i];
20457bded2dbSJung-uk Kim         i++;
20467bded2dbSJung-uk Kim 
20477bded2dbSJung-uk Kim         if (proto_len == 0)
20487bded2dbSJung-uk Kim             goto parse_error;
20497bded2dbSJung-uk Kim 
20507bded2dbSJung-uk Kim         if (i + proto_len < i || i + proto_len > data_len)
20517bded2dbSJung-uk Kim             goto parse_error;
20527bded2dbSJung-uk Kim 
20537bded2dbSJung-uk Kim         i += proto_len;
20547bded2dbSJung-uk Kim     }
20557bded2dbSJung-uk Kim 
2056b8721c16SJung-uk Kim     if (s->cert->alpn_proposed != NULL)
2057b8721c16SJung-uk Kim         OPENSSL_free(s->cert->alpn_proposed);
2058b8721c16SJung-uk Kim     s->cert->alpn_proposed = OPENSSL_malloc(data_len);
2059b8721c16SJung-uk Kim     if (s->cert->alpn_proposed == NULL) {
20607bded2dbSJung-uk Kim         *al = SSL_AD_INTERNAL_ERROR;
20617bded2dbSJung-uk Kim         return -1;
20627bded2dbSJung-uk Kim     }
2063b8721c16SJung-uk Kim     memcpy(s->cert->alpn_proposed, data, data_len);
2064b8721c16SJung-uk Kim     s->cert->alpn_proposed_len = data_len;
20657bded2dbSJung-uk Kim     return 0;
20667bded2dbSJung-uk Kim 
20677bded2dbSJung-uk Kim  parse_error:
20687bded2dbSJung-uk Kim     *al = SSL_AD_DECODE_ERROR;
20697bded2dbSJung-uk Kim     return -1;
20707bded2dbSJung-uk Kim }
20717bded2dbSJung-uk Kim 
2072b8721c16SJung-uk Kim /*
2073b8721c16SJung-uk Kim  * Process the ALPN extension in a ClientHello.
2074b8721c16SJung-uk Kim  * al: a pointer to the alert value to send in the event of a failure.
20756cf8931aSJung-uk Kim  * returns 1 on success, 0 on failure: al set only on failure
2076b8721c16SJung-uk Kim  */
20776cf8931aSJung-uk Kim static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
2078b8721c16SJung-uk Kim {
2079b8721c16SJung-uk Kim     const unsigned char *selected = NULL;
2080b8721c16SJung-uk Kim     unsigned char selected_len = 0;
2081b8721c16SJung-uk Kim 
2082b8721c16SJung-uk Kim     if (s->ctx->alpn_select_cb != NULL && s->cert->alpn_proposed != NULL) {
2083b8721c16SJung-uk Kim         int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
2084b8721c16SJung-uk Kim                                        s->cert->alpn_proposed,
2085b8721c16SJung-uk Kim                                        s->cert->alpn_proposed_len,
2086b8721c16SJung-uk Kim                                        s->ctx->alpn_select_cb_arg);
2087b8721c16SJung-uk Kim 
2088b8721c16SJung-uk Kim         if (r == SSL_TLSEXT_ERR_OK) {
2089b8721c16SJung-uk Kim             OPENSSL_free(s->s3->alpn_selected);
2090b8721c16SJung-uk Kim             s->s3->alpn_selected = OPENSSL_malloc(selected_len);
2091b8721c16SJung-uk Kim             if (s->s3->alpn_selected == NULL) {
2092b8721c16SJung-uk Kim                 *al = SSL_AD_INTERNAL_ERROR;
2093b8721c16SJung-uk Kim                 return 0;
2094b8721c16SJung-uk Kim             }
2095b8721c16SJung-uk Kim             memcpy(s->s3->alpn_selected, selected, selected_len);
2096b8721c16SJung-uk Kim             s->s3->alpn_selected_len = selected_len;
2097b8721c16SJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
2098b8721c16SJung-uk Kim             /* ALPN takes precedence over NPN. */
2099b8721c16SJung-uk Kim             s->s3->next_proto_neg_seen = 0;
2100b8721c16SJung-uk Kim # endif
2101b8721c16SJung-uk Kim         }
2102b8721c16SJung-uk Kim     }
2103b8721c16SJung-uk Kim 
2104b8721c16SJung-uk Kim     return 1;
2105b8721c16SJung-uk Kim }
2106b8721c16SJung-uk Kim 
21077bded2dbSJung-uk Kim static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
210880815a77SJung-uk Kim                                        unsigned char *limit, int *al)
2109db522d3aSSimon L. B. Nielsen {
2110db522d3aSSimon L. B. Nielsen     unsigned short type;
2111db522d3aSSimon L. B. Nielsen     unsigned short size;
2112db522d3aSSimon L. B. Nielsen     unsigned short len;
2113db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
21146a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
21156a599222SSimon L. B. Nielsen 
2116db522d3aSSimon L. B. Nielsen     s->servername_done = 0;
2117db522d3aSSimon L. B. Nielsen     s->tlsext_status_type = -1;
21181f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
21191f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
21201f13597dSJung-uk Kim # endif
21211f13597dSJung-uk Kim 
21227bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
21237bded2dbSJung-uk Kim         OPENSSL_free(s->s3->alpn_selected);
21247bded2dbSJung-uk Kim         s->s3->alpn_selected = NULL;
21257bded2dbSJung-uk Kim     }
2126b8721c16SJung-uk Kim     s->s3->alpn_selected_len = 0;
2127b8721c16SJung-uk Kim     if (s->cert->alpn_proposed) {
2128b8721c16SJung-uk Kim         OPENSSL_free(s->cert->alpn_proposed);
2129b8721c16SJung-uk Kim         s->cert->alpn_proposed = NULL;
2130b8721c16SJung-uk Kim     }
2131b8721c16SJung-uk Kim     s->cert->alpn_proposed_len = 0;
21321f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
21331f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
21341f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
21351f13597dSJung-uk Kim # endif
2136db522d3aSSimon L. B. Nielsen 
2137de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
2138de78d5d8SJung-uk Kim     if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
213980815a77SJung-uk Kim         ssl_check_for_safari(s, data, limit);
2140de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
2141de78d5d8SJung-uk Kim 
21427bded2dbSJung-uk Kim     /* Clear any signature algorithms extension received */
21437bded2dbSJung-uk Kim     if (s->cert->peer_sigalgs) {
21447bded2dbSJung-uk Kim         OPENSSL_free(s->cert->peer_sigalgs);
21457bded2dbSJung-uk Kim         s->cert->peer_sigalgs = NULL;
21467bded2dbSJung-uk Kim     }
2147751d2991SJung-uk Kim # ifndef OPENSSL_NO_SRP
21486f9291ceSJung-uk Kim     if (s->srp_ctx.login != NULL) {
2149751d2991SJung-uk Kim         OPENSSL_free(s->srp_ctx.login);
2150751d2991SJung-uk Kim         s->srp_ctx.login = NULL;
2151751d2991SJung-uk Kim     }
2152751d2991SJung-uk Kim # endif
2153751d2991SJung-uk Kim 
2154751d2991SJung-uk Kim     s->srtp_profile = NULL;
2155751d2991SJung-uk Kim 
215680815a77SJung-uk Kim     if (data == limit)
21576a599222SSimon L. B. Nielsen         goto ri_check;
2158d47910c6SJung-uk Kim 
2159aeb5019cSJung-uk Kim     if (limit - data < 2)
2160d47910c6SJung-uk Kim         goto err;
2161d47910c6SJung-uk Kim 
2162db522d3aSSimon L. B. Nielsen     n2s(data, len);
2163db522d3aSSimon L. B. Nielsen 
2164aeb5019cSJung-uk Kim     if (limit - data != len)
2165ed6b93beSJung-uk Kim         goto err;
2166db522d3aSSimon L. B. Nielsen 
2167aeb5019cSJung-uk Kim     while (limit - data >= 4) {
2168db522d3aSSimon L. B. Nielsen         n2s(data, type);
2169db522d3aSSimon L. B. Nielsen         n2s(data, size);
2170db522d3aSSimon L. B. Nielsen 
2171aeb5019cSJung-uk Kim         if (limit - data < size)
2172ed6b93beSJung-uk Kim             goto err;
21731f13597dSJung-uk Kim # if 0
21741f13597dSJung-uk Kim         fprintf(stderr, "Received extension type %d size %d\n", type, size);
21751f13597dSJung-uk Kim # endif
2176db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
21776f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
21786f9291ceSJung-uk Kim /*-
21796f9291ceSJung-uk Kim  * The servername extension is treated as follows:
21806f9291ceSJung-uk Kim  *
21816f9291ceSJung-uk Kim  * - Only the hostname type is supported with a maximum length of 255.
21826f9291ceSJung-uk Kim  * - The servername is rejected if too long or if it contains zeros,
21836f9291ceSJung-uk Kim  *   in which case an fatal alert is generated.
21846f9291ceSJung-uk Kim  * - The servername field is maintained together with the session cache.
21856f9291ceSJung-uk Kim  * - When a session is resumed, the servername call back invoked in order
21866f9291ceSJung-uk Kim  *   to allow the application to position itself to the right context.
21876f9291ceSJung-uk Kim  * - The servername is acknowledged if it is new for a session or when
21886f9291ceSJung-uk Kim  *   it is identical to a previously used for the same session.
21896f9291ceSJung-uk Kim  *   Applications can control the behaviour.  They can at any time
21906f9291ceSJung-uk Kim  *   set a 'desirable' servername for a new SSL object. This can be the
21916f9291ceSJung-uk Kim  *   case for example with HTTPS when a Host: header field is received and
21926f9291ceSJung-uk Kim  *   a renegotiation is requested. In this case, a possible servername
21936f9291ceSJung-uk Kim  *   presented in the new client hello is only acknowledged if it matches
21946f9291ceSJung-uk Kim  *   the value of the Host: field.
21956f9291ceSJung-uk Kim  * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
21966f9291ceSJung-uk Kim  *   if they provide for changing an explicit servername context for the
21976f9291ceSJung-uk Kim  *   session, i.e. when the session has been established with a servername
21986f9291ceSJung-uk Kim  *   extension.
21996f9291ceSJung-uk Kim  * - On session reconnect, the servername extension may be absent.
22006f9291ceSJung-uk Kim  *
2201db522d3aSSimon L. B. Nielsen  */
2202db522d3aSSimon L. B. Nielsen 
22036f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
2204db522d3aSSimon L. B. Nielsen             unsigned char *sdata;
2205db522d3aSSimon L. B. Nielsen             int servname_type;
2206db522d3aSSimon L. B. Nielsen             int dsize;
2207db522d3aSSimon L. B. Nielsen 
2208ed6b93beSJung-uk Kim             if (size < 2)
2209ed6b93beSJung-uk Kim                 goto err;
2210db522d3aSSimon L. B. Nielsen             n2s(data, dsize);
2211db522d3aSSimon L. B. Nielsen             size -= 2;
2212ed6b93beSJung-uk Kim             if (dsize > size)
2213ed6b93beSJung-uk Kim                 goto err;
2214db522d3aSSimon L. B. Nielsen 
2215db522d3aSSimon L. B. Nielsen             sdata = data;
22166f9291ceSJung-uk Kim             while (dsize > 3) {
2217db522d3aSSimon L. B. Nielsen                 servname_type = *(sdata++);
2218db522d3aSSimon L. B. Nielsen                 n2s(sdata, len);
2219db522d3aSSimon L. B. Nielsen                 dsize -= 3;
2220db522d3aSSimon L. B. Nielsen 
2221ed6b93beSJung-uk Kim                 if (len > dsize)
2222ed6b93beSJung-uk Kim                     goto err;
2223ed6b93beSJung-uk Kim 
2224db522d3aSSimon L. B. Nielsen                 if (s->servername_done == 0)
22256f9291ceSJung-uk Kim                     switch (servname_type) {
2226db522d3aSSimon L. B. Nielsen                     case TLSEXT_NAMETYPE_host_name:
22276f9291ceSJung-uk Kim                         if (!s->hit) {
2228ed6b93beSJung-uk Kim                             if (s->session->tlsext_hostname)
2229ed6b93beSJung-uk Kim                                 goto err;
2230ed6b93beSJung-uk Kim 
22316f9291ceSJung-uk Kim                             if (len > TLSEXT_MAXLEN_host_name) {
2232db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2233db522d3aSSimon L. B. Nielsen                                 return 0;
2234db522d3aSSimon L. B. Nielsen                             }
22356f9291ceSJung-uk Kim                             if ((s->session->tlsext_hostname =
22366f9291ceSJung-uk Kim                                  OPENSSL_malloc(len + 1)) == NULL) {
2237a3ddd25aSSimon L. B. Nielsen                                 *al = TLS1_AD_INTERNAL_ERROR;
2238a3ddd25aSSimon L. B. Nielsen                                 return 0;
2239a3ddd25aSSimon L. B. Nielsen                             }
2240db522d3aSSimon L. B. Nielsen                             memcpy(s->session->tlsext_hostname, sdata, len);
2241db522d3aSSimon L. B. Nielsen                             s->session->tlsext_hostname[len] = '\0';
2242db522d3aSSimon L. B. Nielsen                             if (strlen(s->session->tlsext_hostname) != len) {
2243db522d3aSSimon L. B. Nielsen                                 OPENSSL_free(s->session->tlsext_hostname);
2244db522d3aSSimon L. B. Nielsen                                 s->session->tlsext_hostname = NULL;
2245db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2246db522d3aSSimon L. B. Nielsen                                 return 0;
2247db522d3aSSimon L. B. Nielsen                             }
2248db522d3aSSimon L. B. Nielsen                             s->servername_done = 1;
2249db522d3aSSimon L. B. Nielsen 
22506f9291ceSJung-uk Kim                         } else
2251a3ddd25aSSimon L. B. Nielsen                             s->servername_done = s->session->tlsext_hostname
2252a3ddd25aSSimon L. B. Nielsen                                 && strlen(s->session->tlsext_hostname) == len
22536f9291ceSJung-uk Kim                                 && strncmp(s->session->tlsext_hostname,
22546f9291ceSJung-uk Kim                                            (char *)sdata, len) == 0;
2255db522d3aSSimon L. B. Nielsen 
2256db522d3aSSimon L. B. Nielsen                         break;
2257db522d3aSSimon L. B. Nielsen 
2258db522d3aSSimon L. B. Nielsen                     default:
2259db522d3aSSimon L. B. Nielsen                         break;
2260db522d3aSSimon L. B. Nielsen                     }
2261db522d3aSSimon L. B. Nielsen 
2262db522d3aSSimon L. B. Nielsen                 dsize -= len;
2263db522d3aSSimon L. B. Nielsen             }
2264ed6b93beSJung-uk Kim             if (dsize != 0)
2265ed6b93beSJung-uk Kim                 goto err;
2266db522d3aSSimon L. B. Nielsen 
2267db522d3aSSimon L. B. Nielsen         }
22681f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP
22696f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_srp) {
2270ed6b93beSJung-uk Kim             if (size == 0 || ((len = data[0])) != (size - 1))
2271ed6b93beSJung-uk Kim                 goto err;
2272ed6b93beSJung-uk Kim             if (s->srp_ctx.login != NULL)
2273ed6b93beSJung-uk Kim                 goto err;
22741f13597dSJung-uk Kim             if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
22751f13597dSJung-uk Kim                 return -1;
22761f13597dSJung-uk Kim             memcpy(s->srp_ctx.login, &data[1], len);
22771f13597dSJung-uk Kim             s->srp_ctx.login[len] = '\0';
22781f13597dSJung-uk Kim 
2279ed6b93beSJung-uk Kim             if (strlen(s->srp_ctx.login) != len)
2280ed6b93beSJung-uk Kim                 goto err;
22811f13597dSJung-uk Kim         }
22821f13597dSJung-uk Kim # endif
22831f13597dSJung-uk Kim 
22841f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
22856f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
22861f13597dSJung-uk Kim             unsigned char *sdata = data;
2287*dee36b4fSJung-uk Kim             int ecpointformatlist_length;
22881f13597dSJung-uk Kim 
2289*dee36b4fSJung-uk Kim             if (size == 0)
2290*dee36b4fSJung-uk Kim                 goto err;
2291*dee36b4fSJung-uk Kim 
2292*dee36b4fSJung-uk Kim             ecpointformatlist_length = *(sdata++);
22937bded2dbSJung-uk Kim             if (ecpointformatlist_length != size - 1 ||
22947bded2dbSJung-uk Kim                 ecpointformatlist_length < 1)
2295ed6b93beSJung-uk Kim                 goto err;
22966f9291ceSJung-uk Kim             if (!s->hit) {
22976f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist) {
22981f13597dSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
22991f13597dSJung-uk Kim                     s->session->tlsext_ecpointformatlist = NULL;
23001f13597dSJung-uk Kim                 }
23011f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
23026f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
23036f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
23041f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
23051f13597dSJung-uk Kim                     return 0;
23061f13597dSJung-uk Kim                 }
23076f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
23086f9291ceSJung-uk Kim                     ecpointformatlist_length;
23096f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
23106f9291ceSJung-uk Kim                        ecpointformatlist_length);
23111f13597dSJung-uk Kim             }
23121f13597dSJung-uk Kim #  if 0
23136f9291ceSJung-uk Kim             fprintf(stderr,
23146f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ",
23156f9291ceSJung-uk Kim                     s->session->tlsext_ecpointformatlist_length);
23161f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
23171f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
23181f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
23191f13597dSJung-uk Kim             fprintf(stderr, "\n");
23201f13597dSJung-uk Kim #  endif
23216f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_elliptic_curves) {
23221f13597dSJung-uk Kim             unsigned char *sdata = data;
23231f13597dSJung-uk Kim             int ellipticcurvelist_length = (*(sdata++) << 8);
23241f13597dSJung-uk Kim             ellipticcurvelist_length += (*(sdata++));
23251f13597dSJung-uk Kim 
232609286989SJung-uk Kim             if (ellipticcurvelist_length != size - 2 ||
2327751d2991SJung-uk Kim                 ellipticcurvelist_length < 1 ||
2328751d2991SJung-uk Kim                 /* Each NamedCurve is 2 bytes. */
2329ed6b93beSJung-uk Kim                 ellipticcurvelist_length & 1)
2330ed6b93beSJung-uk Kim                     goto err;
2331ed6b93beSJung-uk Kim 
23326f9291ceSJung-uk Kim             if (!s->hit) {
2333ed6b93beSJung-uk Kim                 if (s->session->tlsext_ellipticcurvelist)
2334ed6b93beSJung-uk Kim                     goto err;
2335ed6b93beSJung-uk Kim 
23361f13597dSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length = 0;
23376f9291ceSJung-uk Kim                 if ((s->session->tlsext_ellipticcurvelist =
23386f9291ceSJung-uk Kim                      OPENSSL_malloc(ellipticcurvelist_length)) == NULL) {
23391f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
23401f13597dSJung-uk Kim                     return 0;
23411f13597dSJung-uk Kim                 }
23426f9291ceSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length =
23436f9291ceSJung-uk Kim                     ellipticcurvelist_length;
23446f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ellipticcurvelist, sdata,
23456f9291ceSJung-uk Kim                        ellipticcurvelist_length);
23461f13597dSJung-uk Kim             }
23471f13597dSJung-uk Kim #  if 0
23486f9291ceSJung-uk Kim             fprintf(stderr,
23496f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ",
23506f9291ceSJung-uk Kim                     s->session->tlsext_ellipticcurvelist_length);
23511f13597dSJung-uk Kim             sdata = s->session->tlsext_ellipticcurvelist;
23521f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
23531f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
23541f13597dSJung-uk Kim             fprintf(stderr, "\n");
23551f13597dSJung-uk Kim #  endif
23561f13597dSJung-uk Kim         }
23571f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
23581f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
23597bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input) {
23601f13597dSJung-uk Kim             unsigned char *sdata = data;
23611f13597dSJung-uk Kim 
23626f9291ceSJung-uk Kim             if (size < 2) {
23631f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
23641f13597dSJung-uk Kim                 return 0;
23651f13597dSJung-uk Kim             }
23661f13597dSJung-uk Kim             n2s(sdata, s->s3->client_opaque_prf_input_len);
23676f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input_len != size - 2) {
23681f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
23691f13597dSJung-uk Kim                 return 0;
23701f13597dSJung-uk Kim             }
23711f13597dSJung-uk Kim 
23726f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
23736f9291ceSJung-uk Kim                 /* shouldn't really happen */
23741f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
23756f9291ceSJung-uk Kim             }
23766f9291ceSJung-uk Kim 
23776f9291ceSJung-uk Kim             /* dummy byte just to get non-NULL */
23781f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input_len == 0)
23796f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
23801f13597dSJung-uk Kim             else
23816f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
23826f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
23836f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
23841f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
23851f13597dSJung-uk Kim                 return 0;
23861f13597dSJung-uk Kim             }
23871f13597dSJung-uk Kim         }
23881f13597dSJung-uk Kim # endif
23896f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
23901f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
23916f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
23926f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
23931f13597dSJung-uk Kim             {
23941f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
23951f13597dSJung-uk Kim                 return 0;
23961f13597dSJung-uk Kim             }
23976f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_renegotiate) {
23986a599222SSimon L. B. Nielsen             if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
23996a599222SSimon L. B. Nielsen                 return 0;
24006a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
24016f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_signature_algorithms) {
24021f13597dSJung-uk Kim             int dsize;
24037bded2dbSJung-uk Kim             if (s->cert->peer_sigalgs || size < 2)
2404ed6b93beSJung-uk Kim                 goto err;
24051f13597dSJung-uk Kim             n2s(data, dsize);
24061f13597dSJung-uk Kim             size -= 2;
24077bded2dbSJung-uk Kim             if (dsize != size || dsize & 1 || !dsize)
2408ed6b93beSJung-uk Kim                 goto err;
24097bded2dbSJung-uk Kim             if (!tls1_save_sigalgs(s, data, dsize))
2410ed6b93beSJung-uk Kim                 goto err;
24117bded2dbSJung-uk Kim         } else if (type == TLSEXT_TYPE_status_request) {
2412db522d3aSSimon L. B. Nielsen 
2413ed6b93beSJung-uk Kim             if (size < 5)
2414ed6b93beSJung-uk Kim                 goto err;
2415db522d3aSSimon L. B. Nielsen 
2416db522d3aSSimon L. B. Nielsen             s->tlsext_status_type = *data++;
2417db522d3aSSimon L. B. Nielsen             size--;
24186f9291ceSJung-uk Kim             if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
2419db522d3aSSimon L. B. Nielsen                 const unsigned char *sdata;
2420db522d3aSSimon L. B. Nielsen                 int dsize;
2421db522d3aSSimon L. B. Nielsen                 /* Read in responder_id_list */
2422db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
2423db522d3aSSimon L. B. Nielsen                 size -= 2;
2424ed6b93beSJung-uk Kim                 if (dsize > size)
2425ed6b93beSJung-uk Kim                     goto err;
2426aeb5019cSJung-uk Kim 
2427aeb5019cSJung-uk Kim                 /*
2428aeb5019cSJung-uk Kim                  * We remove any OCSP_RESPIDs from a previous handshake
2429aeb5019cSJung-uk Kim                  * to prevent unbounded memory growth - CVE-2016-6304
2430aeb5019cSJung-uk Kim                  */
2431aeb5019cSJung-uk Kim                 sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
2432aeb5019cSJung-uk Kim                                         OCSP_RESPID_free);
2433aeb5019cSJung-uk Kim                 if (dsize > 0) {
2434aeb5019cSJung-uk Kim                     s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
2435aeb5019cSJung-uk Kim                     if (s->tlsext_ocsp_ids == NULL) {
2436aeb5019cSJung-uk Kim                         *al = SSL_AD_INTERNAL_ERROR;
2437aeb5019cSJung-uk Kim                         return 0;
2438aeb5019cSJung-uk Kim                     }
2439aeb5019cSJung-uk Kim                 } else {
2440aeb5019cSJung-uk Kim                     s->tlsext_ocsp_ids = NULL;
2441aeb5019cSJung-uk Kim                 }
2442aeb5019cSJung-uk Kim 
24436f9291ceSJung-uk Kim                 while (dsize > 0) {
2444db522d3aSSimon L. B. Nielsen                     OCSP_RESPID *id;
2445db522d3aSSimon L. B. Nielsen                     int idsize;
2446ed6b93beSJung-uk Kim                     if (dsize < 4)
2447ed6b93beSJung-uk Kim                         goto err;
2448db522d3aSSimon L. B. Nielsen                     n2s(data, idsize);
2449db522d3aSSimon L. B. Nielsen                     dsize -= 2 + idsize;
24500a704568SSimon L. B. Nielsen                     size -= 2 + idsize;
2451ed6b93beSJung-uk Kim                     if (dsize < 0)
2452ed6b93beSJung-uk Kim                         goto err;
2453db522d3aSSimon L. B. Nielsen                     sdata = data;
2454db522d3aSSimon L. B. Nielsen                     data += idsize;
24556f9291ceSJung-uk Kim                     id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
2456ed6b93beSJung-uk Kim                     if (!id)
2457ed6b93beSJung-uk Kim                         goto err;
24586f9291ceSJung-uk Kim                     if (data != sdata) {
2459db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2460ed6b93beSJung-uk Kim                         goto err;
2461db522d3aSSimon L. B. Nielsen                     }
24626f9291ceSJung-uk Kim                     if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
2463db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2464db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_INTERNAL_ERROR;
2465db522d3aSSimon L. B. Nielsen                         return 0;
2466db522d3aSSimon L. B. Nielsen                     }
2467db522d3aSSimon L. B. Nielsen                 }
2468db522d3aSSimon L. B. Nielsen 
2469db522d3aSSimon L. B. Nielsen                 /* Read in request_extensions */
2470ed6b93beSJung-uk Kim                 if (size < 2)
2471ed6b93beSJung-uk Kim                     goto err;
2472db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
2473db522d3aSSimon L. B. Nielsen                 size -= 2;
2474ed6b93beSJung-uk Kim                 if (dsize != size)
2475ed6b93beSJung-uk Kim                     goto err;
2476db522d3aSSimon L. B. Nielsen                 sdata = data;
24776f9291ceSJung-uk Kim                 if (dsize > 0) {
24786f9291ceSJung-uk Kim                     if (s->tlsext_ocsp_exts) {
247912de4ed2SJung-uk Kim                         sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
248012de4ed2SJung-uk Kim                                                    X509_EXTENSION_free);
248112de4ed2SJung-uk Kim                     }
248212de4ed2SJung-uk Kim 
2483db522d3aSSimon L. B. Nielsen                     s->tlsext_ocsp_exts =
24846f9291ceSJung-uk Kim                         d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
2485ed6b93beSJung-uk Kim                     if (!s->tlsext_ocsp_exts || (data + dsize != sdata))
2486ed6b93beSJung-uk Kim                         goto err;
2487db522d3aSSimon L. B. Nielsen                 }
2488db522d3aSSimon L. B. Nielsen             }
24896f9291ceSJung-uk Kim             /*
24906f9291ceSJung-uk Kim              * We don't know what to do with any other type * so ignore it.
2491db522d3aSSimon L. B. Nielsen              */
2492db522d3aSSimon L. B. Nielsen             else
2493db522d3aSSimon L. B. Nielsen                 s->tlsext_status_type = -1;
2494db522d3aSSimon L. B. Nielsen         }
24951f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
24966f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
24976f9291ceSJung-uk Kim             switch (data[0]) {
24981f13597dSJung-uk Kim             case 0x01:         /* Client allows us to send HB requests */
24991f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
25001f13597dSJung-uk Kim                 break;
25011f13597dSJung-uk Kim             case 0x02:         /* Client doesn't accept HB requests */
25021f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
25031f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
25041f13597dSJung-uk Kim                 break;
25056f9291ceSJung-uk Kim             default:
25066f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
25071f13597dSJung-uk Kim                 return 0;
25081f13597dSJung-uk Kim             }
25091f13597dSJung-uk Kim         }
25101f13597dSJung-uk Kim # endif
25111f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
25121f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
2513b8721c16SJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
25146f9291ceSJung-uk Kim             /*-
25156f9291ceSJung-uk Kim              * We shouldn't accept this extension on a
25161f13597dSJung-uk Kim              * renegotiation.
25171f13597dSJung-uk Kim              *
25181f13597dSJung-uk Kim              * s->new_session will be set on renegotiation, but we
25191f13597dSJung-uk Kim              * probably shouldn't rely that it couldn't be set on
25201f13597dSJung-uk Kim              * the initial renegotation too in certain cases (when
25211f13597dSJung-uk Kim              * there's some other reason to disallow resuming an
25221f13597dSJung-uk Kim              * earlier session -- the current code won't be doing
25231f13597dSJung-uk Kim              * anything like that, but this might change).
25246f9291ceSJung-uk Kim              *
25251f13597dSJung-uk Kim              * A valid sign that there's been a previous handshake
25261f13597dSJung-uk Kim              * in this connection is if s->s3->tmp.finish_md_len >
25271f13597dSJung-uk Kim              * 0.  (We are talking about a check that will happen
25281f13597dSJung-uk Kim              * in the Hello protocol round, well before a new
25296f9291ceSJung-uk Kim              * Finished message could have been computed.)
25306f9291ceSJung-uk Kim              */
25311f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
25321f13597dSJung-uk Kim         }
25331f13597dSJung-uk Kim # endif
25346a599222SSimon L. B. Nielsen 
25357bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
2536b8721c16SJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
25377bded2dbSJung-uk Kim             if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
25387bded2dbSJung-uk Kim                 return 0;
25397bded2dbSJung-uk Kim         }
25407bded2dbSJung-uk Kim 
2541db522d3aSSimon L. B. Nielsen         /* session ticket processed earlier */
254209286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
2543fa5fddf1SJung-uk Kim         else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
25446f9291ceSJung-uk Kim                  && type == TLSEXT_TYPE_use_srtp) {
25456f9291ceSJung-uk Kim             if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al))
25461f13597dSJung-uk Kim                 return 0;
25471f13597dSJung-uk Kim         }
254809286989SJung-uk Kim # endif
2549db522d3aSSimon L. B. Nielsen 
2550db522d3aSSimon L. B. Nielsen         data += size;
2551db522d3aSSimon L. B. Nielsen     }
25521f13597dSJung-uk Kim 
2553ed6b93beSJung-uk Kim     /* Spurious data on the end */
255480815a77SJung-uk Kim     if (data != limit)
2555ed6b93beSJung-uk Kim         goto err;
2556ed6b93beSJung-uk Kim 
2557db522d3aSSimon L. B. Nielsen     *p = data;
25586a599222SSimon L. B. Nielsen 
25596a599222SSimon L. B. Nielsen  ri_check:
25606a599222SSimon L. B. Nielsen 
25616a599222SSimon L. B. Nielsen     /* Need RI if renegotiating */
25626a599222SSimon L. B. Nielsen 
25631f13597dSJung-uk Kim     if (!renegotiate_seen && s->renegotiate &&
25646f9291ceSJung-uk Kim         !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
25656a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
25667bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
25676a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
25686a599222SSimon L. B. Nielsen         return 0;
25696a599222SSimon L. B. Nielsen     }
25706a599222SSimon L. B. Nielsen 
2571db522d3aSSimon L. B. Nielsen     return 1;
2572ed6b93beSJung-uk Kim err:
2573ed6b93beSJung-uk Kim     *al = SSL_AD_DECODE_ERROR;
2574ed6b93beSJung-uk Kim     return 0;
2575db522d3aSSimon L. B. Nielsen }
2576db522d3aSSimon L. B. Nielsen 
25777bded2dbSJung-uk Kim /*
25787bded2dbSJung-uk Kim  * Parse any custom extensions found.  "data" is the start of the extension data
25797bded2dbSJung-uk Kim  * and "limit" is the end of the record. TODO: add strict syntax checking.
25807bded2dbSJung-uk Kim  */
25817bded2dbSJung-uk Kim 
25827bded2dbSJung-uk Kim static int ssl_scan_clienthello_custom_tlsext(SSL *s,
25837bded2dbSJung-uk Kim                                               const unsigned char *data,
25847bded2dbSJung-uk Kim                                               const unsigned char *limit,
25857bded2dbSJung-uk Kim                                               int *al)
25867bded2dbSJung-uk Kim {
25877bded2dbSJung-uk Kim     unsigned short type, size, len;
25887bded2dbSJung-uk Kim     /* If resumed session or no custom extensions nothing to do */
25897bded2dbSJung-uk Kim     if (s->hit || s->cert->srv_ext.meths_count == 0)
25907bded2dbSJung-uk Kim         return 1;
25917bded2dbSJung-uk Kim 
2592aeb5019cSJung-uk Kim     if (limit - data <= 2)
25937bded2dbSJung-uk Kim         return 1;
25947bded2dbSJung-uk Kim     n2s(data, len);
25957bded2dbSJung-uk Kim 
2596aeb5019cSJung-uk Kim     if (limit - data < len)
25977bded2dbSJung-uk Kim         return 1;
25987bded2dbSJung-uk Kim 
2599aeb5019cSJung-uk Kim     while (limit - data >= 4) {
26007bded2dbSJung-uk Kim         n2s(data, type);
26017bded2dbSJung-uk Kim         n2s(data, size);
26027bded2dbSJung-uk Kim 
2603aeb5019cSJung-uk Kim         if (limit - data < size)
26047bded2dbSJung-uk Kim             return 1;
26057bded2dbSJung-uk Kim         if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0)
26067bded2dbSJung-uk Kim             return 0;
26077bded2dbSJung-uk Kim 
26087bded2dbSJung-uk Kim         data += size;
26097bded2dbSJung-uk Kim     }
26107bded2dbSJung-uk Kim 
26117bded2dbSJung-uk Kim     return 1;
26127bded2dbSJung-uk Kim }
26137bded2dbSJung-uk Kim 
261480815a77SJung-uk Kim int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
261580815a77SJung-uk Kim                                  unsigned char *limit)
26167bded2dbSJung-uk Kim {
26177bded2dbSJung-uk Kim     int al = -1;
26187bded2dbSJung-uk Kim     unsigned char *ptmp = *p;
26197bded2dbSJung-uk Kim     /*
26207bded2dbSJung-uk Kim      * Internally supported extensions are parsed first so SNI can be handled
26217bded2dbSJung-uk Kim      * before custom extensions. An application processing SNI will typically
26227bded2dbSJung-uk Kim      * switch the parent context using SSL_set_SSL_CTX and custom extensions
26237bded2dbSJung-uk Kim      * need to be handled by the new SSL_CTX structure.
26247bded2dbSJung-uk Kim      */
262580815a77SJung-uk Kim     if (ssl_scan_clienthello_tlsext(s, p, limit, &al) <= 0) {
26267bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
26277bded2dbSJung-uk Kim         return 0;
26287bded2dbSJung-uk Kim     }
26297bded2dbSJung-uk Kim 
26307bded2dbSJung-uk Kim     if (ssl_check_clienthello_tlsext_early(s) <= 0) {
26317bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT);
26327bded2dbSJung-uk Kim         return 0;
26337bded2dbSJung-uk Kim     }
26347bded2dbSJung-uk Kim 
26357bded2dbSJung-uk Kim     custom_ext_init(&s->cert->srv_ext);
263680815a77SJung-uk Kim     if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) {
26377bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
26387bded2dbSJung-uk Kim         return 0;
26397bded2dbSJung-uk Kim     }
26407bded2dbSJung-uk Kim 
26417bded2dbSJung-uk Kim     return 1;
26427bded2dbSJung-uk Kim }
26437bded2dbSJung-uk Kim 
26441f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
26456f9291ceSJung-uk Kim /*
26466f9291ceSJung-uk Kim  * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
26476f9291ceSJung-uk Kim  * elements of zero length are allowed and the set of elements must exactly
26486f9291ceSJung-uk Kim  * fill the length of the block.
26496f9291ceSJung-uk Kim  */
26501f13597dSJung-uk Kim static char ssl_next_proto_validate(unsigned char *d, unsigned len)
26511f13597dSJung-uk Kim {
26521f13597dSJung-uk Kim     unsigned int off = 0;
26531f13597dSJung-uk Kim 
26546f9291ceSJung-uk Kim     while (off < len) {
26551f13597dSJung-uk Kim         if (d[off] == 0)
26561f13597dSJung-uk Kim             return 0;
26571f13597dSJung-uk Kim         off += d[off];
26581f13597dSJung-uk Kim         off++;
26591f13597dSJung-uk Kim     }
26601f13597dSJung-uk Kim 
26611f13597dSJung-uk Kim     return off == len;
26621f13597dSJung-uk Kim }
26631f13597dSJung-uk Kim # endif
26641f13597dSJung-uk Kim 
26657bded2dbSJung-uk Kim static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
26667bded2dbSJung-uk Kim                                        unsigned char *d, int n, int *al)
2667db522d3aSSimon L. B. Nielsen {
2668a3ddd25aSSimon L. B. Nielsen     unsigned short length;
2669db522d3aSSimon L. B. Nielsen     unsigned short type;
2670db522d3aSSimon L. B. Nielsen     unsigned short size;
2671db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
2672db522d3aSSimon L. B. Nielsen     int tlsext_servername = 0;
26736a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
2674db522d3aSSimon L. B. Nielsen 
26751f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
26761f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
26771f13597dSJung-uk Kim # endif
2678751d2991SJung-uk Kim     s->tlsext_ticket_expected = 0;
26791f13597dSJung-uk Kim 
26807bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
26817bded2dbSJung-uk Kim         OPENSSL_free(s->s3->alpn_selected);
26827bded2dbSJung-uk Kim         s->s3->alpn_selected = NULL;
26837bded2dbSJung-uk Kim     }
26841f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
26851f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
26861f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
26871f13597dSJung-uk Kim # endif
26881f13597dSJung-uk Kim 
2689aeb5019cSJung-uk Kim     if ((d + n) - data <= 2)
26906a599222SSimon L. B. Nielsen         goto ri_check;
2691db522d3aSSimon L. B. Nielsen 
2692a3ddd25aSSimon L. B. Nielsen     n2s(data, length);
2693aeb5019cSJung-uk Kim     if ((d + n) - data != length) {
2694a3ddd25aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
2695a3ddd25aSSimon L. B. Nielsen         return 0;
2696a3ddd25aSSimon L. B. Nielsen     }
2697db522d3aSSimon L. B. Nielsen 
2698aeb5019cSJung-uk Kim     while ((d + n) - data >= 4) {
2699db522d3aSSimon L. B. Nielsen         n2s(data, type);
2700db522d3aSSimon L. B. Nielsen         n2s(data, size);
2701db522d3aSSimon L. B. Nielsen 
2702aeb5019cSJung-uk Kim         if ((d + n) - data < size)
27036a599222SSimon L. B. Nielsen             goto ri_check;
2704db522d3aSSimon L. B. Nielsen 
2705db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
27066f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
2707db522d3aSSimon L. B. Nielsen 
27086f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
27096f9291ceSJung-uk Kim             if (s->tlsext_hostname == NULL || size > 0) {
2710db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2711db522d3aSSimon L. B. Nielsen                 return 0;
2712db522d3aSSimon L. B. Nielsen             }
2713db522d3aSSimon L. B. Nielsen             tlsext_servername = 1;
2714db522d3aSSimon L. B. Nielsen         }
27151f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
27166f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
27171f13597dSJung-uk Kim             unsigned char *sdata = data;
2718*dee36b4fSJung-uk Kim             int ecpointformatlist_length;
27191f13597dSJung-uk Kim 
2720*dee36b4fSJung-uk Kim             if (size == 0) {
2721*dee36b4fSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
2722*dee36b4fSJung-uk Kim                 return 0;
2723*dee36b4fSJung-uk Kim             }
2724*dee36b4fSJung-uk Kim 
2725*dee36b4fSJung-uk Kim             ecpointformatlist_length = *(sdata++);
27267bded2dbSJung-uk Kim             if (ecpointformatlist_length != size - 1) {
27271f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
27281f13597dSJung-uk Kim                 return 0;
27291f13597dSJung-uk Kim             }
27306f9291ceSJung-uk Kim             if (!s->hit) {
27311f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
27326f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist != NULL)
27336f9291ceSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
27346f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
27356f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
27361f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
27371f13597dSJung-uk Kim                     return 0;
27381f13597dSJung-uk Kim                 }
27396f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
27406f9291ceSJung-uk Kim                     ecpointformatlist_length;
27416f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
27426f9291ceSJung-uk Kim                        ecpointformatlist_length);
2743a93cbc2bSJung-uk Kim             }
27441f13597dSJung-uk Kim #  if 0
27456f9291ceSJung-uk Kim             fprintf(stderr,
27466f9291ceSJung-uk Kim                     "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
27471f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
27481f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
27491f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
27501f13597dSJung-uk Kim             fprintf(stderr, "\n");
27511f13597dSJung-uk Kim #  endif
27521f13597dSJung-uk Kim         }
27531f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
27541f13597dSJung-uk Kim 
27556f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
27561f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
27576f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
27586f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
27591f13597dSJung-uk Kim             {
27601f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
27611f13597dSJung-uk Kim                 return 0;
27621f13597dSJung-uk Kim             }
2763db522d3aSSimon L. B. Nielsen             if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
27646f9291ceSJung-uk Kim                 || (size > 0)) {
2765db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2766db522d3aSSimon L. B. Nielsen                 return 0;
2767db522d3aSSimon L. B. Nielsen             }
2768db522d3aSSimon L. B. Nielsen             s->tlsext_ticket_expected = 1;
2769db522d3aSSimon L. B. Nielsen         }
27701f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
27717bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input) {
27721f13597dSJung-uk Kim             unsigned char *sdata = data;
27731f13597dSJung-uk Kim 
27746f9291ceSJung-uk Kim             if (size < 2) {
27751f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
27761f13597dSJung-uk Kim                 return 0;
27771f13597dSJung-uk Kim             }
27781f13597dSJung-uk Kim             n2s(sdata, s->s3->server_opaque_prf_input_len);
27796f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len != size - 2) {
27801f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
27811f13597dSJung-uk Kim                 return 0;
27821f13597dSJung-uk Kim             }
27831f13597dSJung-uk Kim 
27846f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input != NULL) {
27856f9291ceSJung-uk Kim                 /* shouldn't really happen */
27861f13597dSJung-uk Kim                 OPENSSL_free(s->s3->server_opaque_prf_input);
27876f9291ceSJung-uk Kim             }
27886f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len == 0) {
27896f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
27906f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
27916f9291ceSJung-uk Kim             } else {
27926f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input =
27936f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
27946f9291ceSJung-uk Kim             }
27951f13597dSJung-uk Kim 
27966f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input == NULL) {
27971f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
27981f13597dSJung-uk Kim                 return 0;
27991f13597dSJung-uk Kim             }
28001f13597dSJung-uk Kim         }
28011f13597dSJung-uk Kim # endif
28027bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_status_request) {
28036f9291ceSJung-uk Kim             /*
28046f9291ceSJung-uk Kim              * MUST be empty and only sent if we've requested a status
28056f9291ceSJung-uk Kim              * request message.
2806db522d3aSSimon L. B. Nielsen              */
28076f9291ceSJung-uk Kim             if ((s->tlsext_status_type == -1) || (size > 0)) {
2808db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2809db522d3aSSimon L. B. Nielsen                 return 0;
2810db522d3aSSimon L. B. Nielsen             }
2811db522d3aSSimon L. B. Nielsen             /* Set flag to expect CertificateStatus message */
2812db522d3aSSimon L. B. Nielsen             s->tlsext_status_expected = 1;
2813db522d3aSSimon L. B. Nielsen         }
28141f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
28151f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
28166f9291ceSJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
28171f13597dSJung-uk Kim             unsigned char *selected;
28181f13597dSJung-uk Kim             unsigned char selected_len;
28191f13597dSJung-uk Kim 
28201f13597dSJung-uk Kim             /* We must have requested it. */
28216f9291ceSJung-uk Kim             if (s->ctx->next_proto_select_cb == NULL) {
28221f13597dSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
28231f13597dSJung-uk Kim                 return 0;
28241f13597dSJung-uk Kim             }
28251f13597dSJung-uk Kim             /* The data must be valid */
28266f9291ceSJung-uk Kim             if (!ssl_next_proto_validate(data, size)) {
28271f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
28281f13597dSJung-uk Kim                 return 0;
28291f13597dSJung-uk Kim             }
28306f9291ceSJung-uk Kim             if (s->
28316f9291ceSJung-uk Kim                 ctx->next_proto_select_cb(s, &selected, &selected_len, data,
28326f9291ceSJung-uk Kim                                           size,
28336f9291ceSJung-uk Kim                                           s->ctx->next_proto_select_cb_arg) !=
28346f9291ceSJung-uk Kim                 SSL_TLSEXT_ERR_OK) {
28351f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
28361f13597dSJung-uk Kim                 return 0;
28371f13597dSJung-uk Kim             }
2838aeb5019cSJung-uk Kim             /*
2839aeb5019cSJung-uk Kim              * Could be non-NULL if server has sent multiple NPN extensions in
2840aeb5019cSJung-uk Kim              * a single Serverhello
2841aeb5019cSJung-uk Kim              */
2842aeb5019cSJung-uk Kim             OPENSSL_free(s->next_proto_negotiated);
28431f13597dSJung-uk Kim             s->next_proto_negotiated = OPENSSL_malloc(selected_len);
28446f9291ceSJung-uk Kim             if (!s->next_proto_negotiated) {
28451f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
28461f13597dSJung-uk Kim                 return 0;
28471f13597dSJung-uk Kim             }
28481f13597dSJung-uk Kim             memcpy(s->next_proto_negotiated, selected, selected_len);
28491f13597dSJung-uk Kim             s->next_proto_negotiated_len = selected_len;
28501f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
28511f13597dSJung-uk Kim         }
28521f13597dSJung-uk Kim # endif
28537bded2dbSJung-uk Kim 
28547bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
28557bded2dbSJung-uk Kim             unsigned len;
28567bded2dbSJung-uk Kim 
28577bded2dbSJung-uk Kim             /* We must have requested it. */
2858b8721c16SJung-uk Kim             if (!s->cert->alpn_sent) {
28597bded2dbSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
28607bded2dbSJung-uk Kim                 return 0;
28617bded2dbSJung-uk Kim             }
28627bded2dbSJung-uk Kim             if (size < 4) {
28637bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
28647bded2dbSJung-uk Kim                 return 0;
28657bded2dbSJung-uk Kim             }
28667bded2dbSJung-uk Kim             /*-
28677bded2dbSJung-uk Kim              * The extension data consists of:
28687bded2dbSJung-uk Kim              *   uint16 list_length
28697bded2dbSJung-uk Kim              *   uint8 proto_length;
28707bded2dbSJung-uk Kim              *   uint8 proto[proto_length];
28717bded2dbSJung-uk Kim              */
28727bded2dbSJung-uk Kim             len = data[0];
28737bded2dbSJung-uk Kim             len <<= 8;
28747bded2dbSJung-uk Kim             len |= data[1];
28757bded2dbSJung-uk Kim             if (len != (unsigned)size - 2) {
28767bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
28777bded2dbSJung-uk Kim                 return 0;
28787bded2dbSJung-uk Kim             }
28797bded2dbSJung-uk Kim             len = data[2];
28807bded2dbSJung-uk Kim             if (len != (unsigned)size - 3) {
28817bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
28827bded2dbSJung-uk Kim                 return 0;
28837bded2dbSJung-uk Kim             }
28847bded2dbSJung-uk Kim             if (s->s3->alpn_selected)
28857bded2dbSJung-uk Kim                 OPENSSL_free(s->s3->alpn_selected);
28867bded2dbSJung-uk Kim             s->s3->alpn_selected = OPENSSL_malloc(len);
28877bded2dbSJung-uk Kim             if (!s->s3->alpn_selected) {
28887bded2dbSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
28897bded2dbSJung-uk Kim                 return 0;
28907bded2dbSJung-uk Kim             }
28917bded2dbSJung-uk Kim             memcpy(s->s3->alpn_selected, data + 3, len);
28927bded2dbSJung-uk Kim             s->s3->alpn_selected_len = len;
28937bded2dbSJung-uk Kim         }
28947bded2dbSJung-uk Kim 
28956f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_renegotiate) {
28966a599222SSimon L. B. Nielsen             if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
28976a599222SSimon L. B. Nielsen                 return 0;
28986a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
28996a599222SSimon L. B. Nielsen         }
29001f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
29016f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
29026f9291ceSJung-uk Kim             switch (data[0]) {
29031f13597dSJung-uk Kim             case 0x01:         /* Server allows us to send HB requests */
29041f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
29051f13597dSJung-uk Kim                 break;
29061f13597dSJung-uk Kim             case 0x02:         /* Server doesn't accept HB requests */
29071f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
29081f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
29091f13597dSJung-uk Kim                 break;
29106f9291ceSJung-uk Kim             default:
29116f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
29121f13597dSJung-uk Kim                 return 0;
29131f13597dSJung-uk Kim             }
29141f13597dSJung-uk Kim         }
29151f13597dSJung-uk Kim # endif
291609286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
29176f9291ceSJung-uk Kim         else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
29186f9291ceSJung-uk Kim             if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al))
29191f13597dSJung-uk Kim                 return 0;
29201f13597dSJung-uk Kim         }
292109286989SJung-uk Kim # endif
29227bded2dbSJung-uk Kim         /*
29237bded2dbSJung-uk Kim          * If this extension type was not otherwise handled, but matches a
29247bded2dbSJung-uk Kim          * custom_cli_ext_record, then send it to the c callback
29257bded2dbSJung-uk Kim          */
29267bded2dbSJung-uk Kim         else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
29277bded2dbSJung-uk Kim             return 0;
29281f13597dSJung-uk Kim 
2929db522d3aSSimon L. B. Nielsen         data += size;
2930db522d3aSSimon L. B. Nielsen     }
2931db522d3aSSimon L. B. Nielsen 
29326f9291ceSJung-uk Kim     if (data != d + n) {
2933db522d3aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
2934db522d3aSSimon L. B. Nielsen         return 0;
2935db522d3aSSimon L. B. Nielsen     }
2936db522d3aSSimon L. B. Nielsen 
29376f9291ceSJung-uk Kim     if (!s->hit && tlsext_servername == 1) {
29386f9291ceSJung-uk Kim         if (s->tlsext_hostname) {
29396f9291ceSJung-uk Kim             if (s->session->tlsext_hostname == NULL) {
2940db522d3aSSimon L. B. Nielsen                 s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
29416f9291ceSJung-uk Kim                 if (!s->session->tlsext_hostname) {
2942db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_UNRECOGNIZED_NAME;
2943db522d3aSSimon L. B. Nielsen                     return 0;
2944db522d3aSSimon L. B. Nielsen                 }
29456f9291ceSJung-uk Kim             } else {
2946db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
2947db522d3aSSimon L. B. Nielsen                 return 0;
2948db522d3aSSimon L. B. Nielsen             }
2949db522d3aSSimon L. B. Nielsen         }
2950db522d3aSSimon L. B. Nielsen     }
2951db522d3aSSimon L. B. Nielsen 
2952db522d3aSSimon L. B. Nielsen     *p = data;
29536a599222SSimon L. B. Nielsen 
29546a599222SSimon L. B. Nielsen  ri_check:
29556a599222SSimon L. B. Nielsen 
29566f9291ceSJung-uk Kim     /*
29576f9291ceSJung-uk Kim      * Determine if we need to see RI. Strictly speaking if we want to avoid
29586f9291ceSJung-uk Kim      * an attack we should *always* see RI even on initial server hello
29596f9291ceSJung-uk Kim      * because the client doesn't see any renegotiation during an attack.
29606f9291ceSJung-uk Kim      * However this would mean we could not connect to any server which
29616f9291ceSJung-uk Kim      * doesn't support RI so for the immediate future tolerate RI absence on
29626f9291ceSJung-uk Kim      * initial connect only.
29636a599222SSimon L. B. Nielsen      */
29646f9291ceSJung-uk Kim     if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
29656f9291ceSJung-uk Kim         && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
29666a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
29677bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
29686a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
29696a599222SSimon L. B. Nielsen         return 0;
29706a599222SSimon L. B. Nielsen     }
29716a599222SSimon L. B. Nielsen 
2972db522d3aSSimon L. B. Nielsen     return 1;
2973db522d3aSSimon L. B. Nielsen }
2974db522d3aSSimon L. B. Nielsen 
29751f13597dSJung-uk Kim int ssl_prepare_clienthello_tlsext(SSL *s)
29761f13597dSJung-uk Kim {
29771f13597dSJung-uk Kim 
29781f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
29791f13597dSJung-uk Kim     {
29801f13597dSJung-uk Kim         int r = 1;
29811f13597dSJung-uk Kim 
29826f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
29836f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
29846f9291ceSJung-uk Kim                                                          s->
29856f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
29861f13597dSJung-uk Kim             if (!r)
29871f13597dSJung-uk Kim                 return -1;
29881f13597dSJung-uk Kim         }
29891f13597dSJung-uk Kim 
29906f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
29916f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
29926f9291ceSJung-uk Kim                 /* shouldn't really happen */
29931f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
29946f9291ceSJung-uk Kim             }
29951f13597dSJung-uk Kim 
29966f9291ceSJung-uk Kim             if (s->tlsext_opaque_prf_input_len == 0) {
29976f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
29986f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
29996f9291ceSJung-uk Kim             } else {
30006f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
30016f9291ceSJung-uk Kim                     BUF_memdup(s->tlsext_opaque_prf_input,
30026f9291ceSJung-uk Kim                                s->tlsext_opaque_prf_input_len);
30036f9291ceSJung-uk Kim             }
30046f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
30056f9291ceSJung-uk Kim                 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
30066f9291ceSJung-uk Kim                        ERR_R_MALLOC_FAILURE);
30071f13597dSJung-uk Kim                 return -1;
30081f13597dSJung-uk Kim             }
30096f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len =
30106f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
30111f13597dSJung-uk Kim         }
30121f13597dSJung-uk Kim 
30131f13597dSJung-uk Kim         if (r == 2)
30146f9291ceSJung-uk Kim             /*
30156f9291ceSJung-uk Kim              * at callback's request, insist on receiving an appropriate
30166f9291ceSJung-uk Kim              * server opaque PRF input
30176f9291ceSJung-uk Kim              */
30186f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len =
30196f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
30201f13597dSJung-uk Kim     }
30211f13597dSJung-uk Kim # endif
30221f13597dSJung-uk Kim 
3023b8721c16SJung-uk Kim     s->cert->alpn_sent = 0;
30241f13597dSJung-uk Kim     return 1;
30251f13597dSJung-uk Kim }
30261f13597dSJung-uk Kim 
30271f13597dSJung-uk Kim int ssl_prepare_serverhello_tlsext(SSL *s)
30281f13597dSJung-uk Kim {
30291f13597dSJung-uk Kim     return 1;
30301f13597dSJung-uk Kim }
30311f13597dSJung-uk Kim 
30327bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s)
3033db522d3aSSimon L. B. Nielsen {
3034db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
3035db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
3036db522d3aSSimon L. B. Nielsen 
30371f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
30386f9291ceSJung-uk Kim     /*
30396f9291ceSJung-uk Kim      * The handling of the ECPointFormats extension is done elsewhere, namely
30406f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
30411f13597dSJung-uk Kim      */
30426f9291ceSJung-uk Kim     /*
30436f9291ceSJung-uk Kim      * The handling of the EllipticCurves extension is done elsewhere, namely
30446f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
30451f13597dSJung-uk Kim      */
30461f13597dSJung-uk Kim # endif
30471f13597dSJung-uk Kim 
3048db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
30496f9291ceSJung-uk Kim         ret =
30506f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
30516f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
30526f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
30536f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
30546f9291ceSJung-uk Kim         ret =
30556f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
30566f9291ceSJung-uk Kim                                                        s->
30576f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
3058db522d3aSSimon L. B. Nielsen 
30591f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
30601f13597dSJung-uk Kim     {
30616f9291ceSJung-uk Kim         /*
30626f9291ceSJung-uk Kim          * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we
30636f9291ceSJung-uk Kim          * might be sending an alert in response to the client hello, so this
30646f9291ceSJung-uk Kim          * has to happen here in ssl_check_clienthello_tlsext_early().
30656f9291ceSJung-uk Kim          */
30661f13597dSJung-uk Kim 
30671f13597dSJung-uk Kim         int r = 1;
30681f13597dSJung-uk Kim 
30696f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
30706f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
30716f9291ceSJung-uk Kim                                                          s->
30726f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
30736f9291ceSJung-uk Kim             if (!r) {
30741f13597dSJung-uk Kim                 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
30751f13597dSJung-uk Kim                 al = SSL_AD_INTERNAL_ERROR;
30761f13597dSJung-uk Kim                 goto err;
30771f13597dSJung-uk Kim             }
30781f13597dSJung-uk Kim         }
30791f13597dSJung-uk Kim 
30806f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input != NULL) {
30816f9291ceSJung-uk Kim             /* shouldn't really happen */
30821f13597dSJung-uk Kim             OPENSSL_free(s->s3->server_opaque_prf_input);
30836f9291ceSJung-uk Kim         }
30841f13597dSJung-uk Kim         s->s3->server_opaque_prf_input = NULL;
30851f13597dSJung-uk Kim 
30866f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
30871f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL &&
30886f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input_len ==
30896f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len) {
30906f9291ceSJung-uk Kim                 /*
30916f9291ceSJung-uk Kim                  * can only use this extension if we have a server opaque PRF
30926f9291ceSJung-uk Kim                  * input of the same length as the client opaque PRF input!
30936f9291ceSJung-uk Kim                  */
30941f13597dSJung-uk Kim 
30956f9291ceSJung-uk Kim                 if (s->tlsext_opaque_prf_input_len == 0) {
30966f9291ceSJung-uk Kim                     /* dummy byte just to get non-NULL */
30976f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
30986f9291ceSJung-uk Kim                 } else {
30996f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input =
31006f9291ceSJung-uk Kim                         BUF_memdup(s->tlsext_opaque_prf_input,
31016f9291ceSJung-uk Kim                                    s->tlsext_opaque_prf_input_len);
31026f9291ceSJung-uk Kim                 }
31036f9291ceSJung-uk Kim                 if (s->s3->server_opaque_prf_input == NULL) {
31041f13597dSJung-uk Kim                     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
31051f13597dSJung-uk Kim                     al = SSL_AD_INTERNAL_ERROR;
31061f13597dSJung-uk Kim                     goto err;
31071f13597dSJung-uk Kim                 }
31086f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input_len =
31096f9291ceSJung-uk Kim                     s->tlsext_opaque_prf_input_len;
31101f13597dSJung-uk Kim             }
31111f13597dSJung-uk Kim         }
31121f13597dSJung-uk Kim 
31136f9291ceSJung-uk Kim         if (r == 2 && s->s3->server_opaque_prf_input == NULL) {
31146f9291ceSJung-uk Kim             /*
31156f9291ceSJung-uk Kim              * The callback wants to enforce use of the extension, but we
31166f9291ceSJung-uk Kim              * can't do that with the client opaque PRF input; abort the
31176f9291ceSJung-uk Kim              * handshake.
31181f13597dSJung-uk Kim              */
31191f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
31201f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
31211f13597dSJung-uk Kim         }
31221f13597dSJung-uk Kim     }
31231f13597dSJung-uk Kim 
3124db522d3aSSimon L. B. Nielsen  err:
312509286989SJung-uk Kim # endif
31266f9291ceSJung-uk Kim     switch (ret) {
3127db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
3128db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
3129db522d3aSSimon L. B. Nielsen         return -1;
3130db522d3aSSimon L. B. Nielsen 
3131db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
3132db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
3133db522d3aSSimon L. B. Nielsen         return 1;
3134db522d3aSSimon L. B. Nielsen 
3135db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
3136db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
3137db522d3aSSimon L. B. Nielsen     default:
3138db522d3aSSimon L. B. Nielsen         return 1;
3139db522d3aSSimon L. B. Nielsen     }
3140db522d3aSSimon L. B. Nielsen }
3141db522d3aSSimon L. B. Nielsen 
31427bded2dbSJung-uk Kim int tls1_set_server_sigalgs(SSL *s)
31437bded2dbSJung-uk Kim {
31447bded2dbSJung-uk Kim     int al;
31457bded2dbSJung-uk Kim     size_t i;
31467bded2dbSJung-uk Kim     /* Clear any shared sigtnature algorithms */
31477bded2dbSJung-uk Kim     if (s->cert->shared_sigalgs) {
31487bded2dbSJung-uk Kim         OPENSSL_free(s->cert->shared_sigalgs);
31497bded2dbSJung-uk Kim         s->cert->shared_sigalgs = NULL;
31507bded2dbSJung-uk Kim         s->cert->shared_sigalgslen = 0;
31517bded2dbSJung-uk Kim     }
31527bded2dbSJung-uk Kim     /* Clear certificate digests and validity flags */
31537bded2dbSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
31547bded2dbSJung-uk Kim         s->cert->pkeys[i].digest = NULL;
31557bded2dbSJung-uk Kim         s->cert->pkeys[i].valid_flags = 0;
31567bded2dbSJung-uk Kim     }
31577bded2dbSJung-uk Kim 
31587bded2dbSJung-uk Kim     /* If sigalgs received process it. */
31597bded2dbSJung-uk Kim     if (s->cert->peer_sigalgs) {
31607bded2dbSJung-uk Kim         if (!tls1_process_sigalgs(s)) {
31617bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
31627bded2dbSJung-uk Kim             al = SSL_AD_INTERNAL_ERROR;
31637bded2dbSJung-uk Kim             goto err;
31647bded2dbSJung-uk Kim         }
31657bded2dbSJung-uk Kim         /* Fatal error is no shared signature algorithms */
31667bded2dbSJung-uk Kim         if (!s->cert->shared_sigalgs) {
31677bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
31687bded2dbSJung-uk Kim                    SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
31697bded2dbSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
31707bded2dbSJung-uk Kim             goto err;
31717bded2dbSJung-uk Kim         }
31727bded2dbSJung-uk Kim     } else
31737bded2dbSJung-uk Kim         ssl_cert_set_default_md(s->cert);
31747bded2dbSJung-uk Kim     return 1;
31757bded2dbSJung-uk Kim  err:
31767bded2dbSJung-uk Kim     ssl3_send_alert(s, SSL3_AL_FATAL, al);
31777bded2dbSJung-uk Kim     return 0;
31787bded2dbSJung-uk Kim }
31797bded2dbSJung-uk Kim 
31806cf8931aSJung-uk Kim /*
31816cf8931aSJung-uk Kim  * Upon success, returns 1.
31826cf8931aSJung-uk Kim  * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
31836cf8931aSJung-uk Kim  */
31846cf8931aSJung-uk Kim int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
318509286989SJung-uk Kim {
318609286989SJung-uk Kim 
31876f9291ceSJung-uk Kim     /*
31886f9291ceSJung-uk Kim      * If status request then ask callback what to do. Note: this must be
31897bded2dbSJung-uk Kim      * called after servername callbacks in case the certificate has changed,
31907bded2dbSJung-uk Kim      * and must be called after the cipher has been chosen because this may
31917bded2dbSJung-uk Kim      * influence which certificate is sent
319209286989SJung-uk Kim      */
31936f9291ceSJung-uk Kim     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
31946cf8931aSJung-uk Kim         int ret;
319509286989SJung-uk Kim         CERT_PKEY *certpkey;
319609286989SJung-uk Kim         certpkey = ssl_get_server_send_pkey(s);
319709286989SJung-uk Kim         /* If no certificate can't return certificate status */
31986cf8931aSJung-uk Kim         if (certpkey != NULL) {
31996f9291ceSJung-uk Kim             /*
32006f9291ceSJung-uk Kim              * Set current certificate to one we will use so SSL_get_certificate
32016f9291ceSJung-uk Kim              * et al can pick it up.
320209286989SJung-uk Kim              */
320309286989SJung-uk Kim             s->cert->key = certpkey;
32046cf8931aSJung-uk Kim             ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
32056cf8931aSJung-uk Kim             switch (ret) {
320609286989SJung-uk Kim                 /* We don't want to send a status request response */
320709286989SJung-uk Kim             case SSL_TLSEXT_ERR_NOACK:
320809286989SJung-uk Kim                 s->tlsext_status_expected = 0;
320909286989SJung-uk Kim                 break;
321009286989SJung-uk Kim                 /* status request response should be sent */
321109286989SJung-uk Kim             case SSL_TLSEXT_ERR_OK:
321209286989SJung-uk Kim                 if (s->tlsext_ocsp_resp)
321309286989SJung-uk Kim                     s->tlsext_status_expected = 1;
321409286989SJung-uk Kim                 break;
321509286989SJung-uk Kim                 /* something bad happened */
321609286989SJung-uk Kim             case SSL_TLSEXT_ERR_ALERT_FATAL:
321709286989SJung-uk Kim             default:
32186cf8931aSJung-uk Kim                 *al = SSL_AD_INTERNAL_ERROR;
32196cf8931aSJung-uk Kim                 return 0;
322009286989SJung-uk Kim             }
322109286989SJung-uk Kim         }
32226cf8931aSJung-uk Kim     }
32236cf8931aSJung-uk Kim 
32246cf8931aSJung-uk Kim     if (!tls1_alpn_handle_client_hello_late(s, al)) {
32256cf8931aSJung-uk Kim         return 0;
32266cf8931aSJung-uk Kim     }
32276cf8931aSJung-uk Kim 
32286cf8931aSJung-uk Kim     return 1;
32296cf8931aSJung-uk Kim }
323009286989SJung-uk Kim 
3231db522d3aSSimon L. B. Nielsen int ssl_check_serverhello_tlsext(SSL *s)
3232db522d3aSSimon L. B. Nielsen {
3233db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
3234db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
3235db522d3aSSimon L. B. Nielsen 
32361f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
32376f9291ceSJung-uk Kim     /*
32386f9291ceSJung-uk Kim      * If we are client and using an elliptic curve cryptography cipher
32396f9291ceSJung-uk Kim      * suite, then if server returns an EC point formats lists extension it
32406f9291ceSJung-uk Kim      * must contain uncompressed.
32411f13597dSJung-uk Kim      */
32421f13597dSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
32431f13597dSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
32446f9291ceSJung-uk Kim     if ((s->tlsext_ecpointformatlist != NULL)
32456f9291ceSJung-uk Kim         && (s->tlsext_ecpointformatlist_length > 0)
32466f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist != NULL)
32476f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist_length > 0)
32486f9291ceSJung-uk Kim         && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
32496f9291ceSJung-uk Kim             || (alg_a & SSL_aECDSA))) {
32501f13597dSJung-uk Kim         /* we are using an ECC cipher */
32511f13597dSJung-uk Kim         size_t i;
32521f13597dSJung-uk Kim         unsigned char *list;
32531f13597dSJung-uk Kim         int found_uncompressed = 0;
32541f13597dSJung-uk Kim         list = s->session->tlsext_ecpointformatlist;
32556f9291ceSJung-uk Kim         for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
32566f9291ceSJung-uk Kim             if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
32571f13597dSJung-uk Kim                 found_uncompressed = 1;
32581f13597dSJung-uk Kim                 break;
32591f13597dSJung-uk Kim             }
32601f13597dSJung-uk Kim         }
32616f9291ceSJung-uk Kim         if (!found_uncompressed) {
32626f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
32636f9291ceSJung-uk Kim                    SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
32641f13597dSJung-uk Kim             return -1;
32651f13597dSJung-uk Kim         }
32661f13597dSJung-uk Kim     }
32671f13597dSJung-uk Kim     ret = SSL_TLSEXT_ERR_OK;
32681f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
32691f13597dSJung-uk Kim 
3270db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
32716f9291ceSJung-uk Kim         ret =
32726f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
32736f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
32746f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
32756f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
32766f9291ceSJung-uk Kim         ret =
32776f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
32786f9291ceSJung-uk Kim                                                        s->
32796f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
3280db522d3aSSimon L. B. Nielsen 
32811f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
32826f9291ceSJung-uk Kim     if (s->s3->server_opaque_prf_input_len > 0) {
32836f9291ceSJung-uk Kim         /*
32846f9291ceSJung-uk Kim          * This case may indicate that we, as a client, want to insist on
32856f9291ceSJung-uk Kim          * using opaque PRF inputs. So first verify that we really have a
32866f9291ceSJung-uk Kim          * value from the server too.
32876f9291ceSJung-uk Kim          */
32881f13597dSJung-uk Kim 
32896f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input == NULL) {
32901f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
32911f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
32921f13597dSJung-uk Kim         }
32931f13597dSJung-uk Kim 
32946f9291ceSJung-uk Kim         /*
32956f9291ceSJung-uk Kim          * Anytime the server *has* sent an opaque PRF input, we need to
32966f9291ceSJung-uk Kim          * check that we have a client opaque PRF input of the same size.
32976f9291ceSJung-uk Kim          */
32981f13597dSJung-uk Kim         if (s->s3->client_opaque_prf_input == NULL ||
32996f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len !=
33006f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len) {
33011f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
33021f13597dSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
33031f13597dSJung-uk Kim         }
33041f13597dSJung-uk Kim     }
33051f13597dSJung-uk Kim # endif
33061f13597dSJung-uk Kim 
33078180e704SJung-uk Kim     OPENSSL_free(s->tlsext_ocsp_resp);
33088180e704SJung-uk Kim     s->tlsext_ocsp_resp = NULL;
33098180e704SJung-uk Kim     s->tlsext_ocsp_resplen = -1;
33106f9291ceSJung-uk Kim     /*
33116f9291ceSJung-uk Kim      * If we've requested certificate status and we wont get one tell the
33126f9291ceSJung-uk Kim      * callback
3313db522d3aSSimon L. B. Nielsen      */
3314db522d3aSSimon L. B. Nielsen     if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
33158180e704SJung-uk Kim         && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) {
3316db522d3aSSimon L. B. Nielsen         int r;
33176f9291ceSJung-uk Kim         /*
33188180e704SJung-uk Kim          * Call callback with resp == NULL and resplen == -1 so callback
33198180e704SJung-uk Kim          * knows there is no response
3320db522d3aSSimon L. B. Nielsen          */
3321db522d3aSSimon L. B. Nielsen         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
33226f9291ceSJung-uk Kim         if (r == 0) {
3323db522d3aSSimon L. B. Nielsen             al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
3324db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
3325db522d3aSSimon L. B. Nielsen         }
33266f9291ceSJung-uk Kim         if (r < 0) {
3327db522d3aSSimon L. B. Nielsen             al = SSL_AD_INTERNAL_ERROR;
3328db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
3329db522d3aSSimon L. B. Nielsen         }
3330db522d3aSSimon L. B. Nielsen     }
3331db522d3aSSimon L. B. Nielsen 
33326f9291ceSJung-uk Kim     switch (ret) {
3333db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
3334db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
3335db522d3aSSimon L. B. Nielsen         return -1;
3336db522d3aSSimon L. B. Nielsen 
3337db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
3338db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
3339db522d3aSSimon L. B. Nielsen         return 1;
3340db522d3aSSimon L. B. Nielsen 
3341db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
3342db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
3343db522d3aSSimon L. B. Nielsen     default:
3344db522d3aSSimon L. B. Nielsen         return 1;
3345db522d3aSSimon L. B. Nielsen     }
3346db522d3aSSimon L. B. Nielsen }
3347db522d3aSSimon L. B. Nielsen 
33487bded2dbSJung-uk Kim int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
33497bded2dbSJung-uk Kim                                  int n)
33507bded2dbSJung-uk Kim {
33517bded2dbSJung-uk Kim     int al = -1;
33527bded2dbSJung-uk Kim     if (s->version < SSL3_VERSION)
33537bded2dbSJung-uk Kim         return 1;
33547bded2dbSJung-uk Kim     if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) {
33557bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
33567bded2dbSJung-uk Kim         return 0;
33577bded2dbSJung-uk Kim     }
33587bded2dbSJung-uk Kim 
33597bded2dbSJung-uk Kim     if (ssl_check_serverhello_tlsext(s) <= 0) {
33607bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
33617bded2dbSJung-uk Kim         return 0;
33627bded2dbSJung-uk Kim     }
33637bded2dbSJung-uk Kim     return 1;
33647bded2dbSJung-uk Kim }
33657bded2dbSJung-uk Kim 
33666f9291ceSJung-uk Kim /*-
33676f9291ceSJung-uk Kim  * Since the server cache lookup is done early on in the processing of the
33681f13597dSJung-uk Kim  * ClientHello, and other operations depend on the result, we need to handle
33691f13597dSJung-uk Kim  * any TLS session ticket extension at the same time.
33701f13597dSJung-uk Kim  *
33711f13597dSJung-uk Kim  *   session_id: points at the session ID in the ClientHello. This code will
33721f13597dSJung-uk Kim  *       read past the end of this in order to parse out the session ticket
33731f13597dSJung-uk Kim  *       extension, if any.
33741f13597dSJung-uk Kim  *   len: the length of the session ID.
33751f13597dSJung-uk Kim  *   limit: a pointer to the first byte after the ClientHello.
33761f13597dSJung-uk Kim  *   ret: (output) on return, if a ticket was decrypted, then this is set to
33771f13597dSJung-uk Kim  *       point to the resulting session.
33781f13597dSJung-uk Kim  *
33791f13597dSJung-uk Kim  * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
33801f13597dSJung-uk Kim  * ciphersuite, in which case we have no use for session tickets and one will
33811f13597dSJung-uk Kim  * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
33821f13597dSJung-uk Kim  *
33831f13597dSJung-uk Kim  * Returns:
33841f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
33851f13597dSJung-uk Kim  *    0: no ticket was found (or was ignored, based on settings).
33861f13597dSJung-uk Kim  *    1: a zero length extension was found, indicating that the client supports
33871f13597dSJung-uk Kim  *       session tickets but doesn't currently have one to offer.
33881f13597dSJung-uk Kim  *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
33891f13597dSJung-uk Kim  *       couldn't be decrypted because of a non-fatal error.
33901f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *ret was set.
33911f13597dSJung-uk Kim  *
33921f13597dSJung-uk Kim  * Side effects:
33931f13597dSJung-uk Kim  *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
33941f13597dSJung-uk Kim  *   a new session ticket to the client because the client indicated support
33951f13597dSJung-uk Kim  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
33961f13597dSJung-uk Kim  *   a session ticket or we couldn't use the one it gave us, or if
33971f13597dSJung-uk Kim  *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
33981f13597dSJung-uk Kim  *   Otherwise, s->tlsext_ticket_expected is set to 0.
3399db522d3aSSimon L. B. Nielsen  */
3400db522d3aSSimon L. B. Nielsen int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
3401db522d3aSSimon L. B. Nielsen                         const unsigned char *limit, SSL_SESSION **ret)
3402db522d3aSSimon L. B. Nielsen {
3403db522d3aSSimon L. B. Nielsen     /* Point after session ID in client hello */
3404db522d3aSSimon L. B. Nielsen     const unsigned char *p = session_id + len;
3405db522d3aSSimon L. B. Nielsen     unsigned short i;
3406db522d3aSSimon L. B. Nielsen 
34071f13597dSJung-uk Kim     *ret = NULL;
34081f13597dSJung-uk Kim     s->tlsext_ticket_expected = 0;
34091f13597dSJung-uk Kim 
34106f9291ceSJung-uk Kim     /*
34116f9291ceSJung-uk Kim      * If tickets disabled behave as if no ticket present to permit stateful
34126f9291ceSJung-uk Kim      * resumption.
3413db522d3aSSimon L. B. Nielsen      */
3414db522d3aSSimon L. B. Nielsen     if (SSL_get_options(s) & SSL_OP_NO_TICKET)
34151f13597dSJung-uk Kim         return 0;
3416db522d3aSSimon L. B. Nielsen     if ((s->version <= SSL3_VERSION) || !limit)
34171f13597dSJung-uk Kim         return 0;
3418db522d3aSSimon L. B. Nielsen     if (p >= limit)
3419db522d3aSSimon L. B. Nielsen         return -1;
34206a599222SSimon L. B. Nielsen     /* Skip past DTLS cookie */
34217bded2dbSJung-uk Kim     if (SSL_IS_DTLS(s)) {
34226a599222SSimon L. B. Nielsen         i = *(p++);
3423aeb5019cSJung-uk Kim 
3424aeb5019cSJung-uk Kim         if (limit - p <= i)
34256a599222SSimon L. B. Nielsen             return -1;
3426aeb5019cSJung-uk Kim 
3427aeb5019cSJung-uk Kim         p += i;
34286a599222SSimon L. B. Nielsen     }
3429db522d3aSSimon L. B. Nielsen     /* Skip past cipher list */
3430db522d3aSSimon L. B. Nielsen     n2s(p, i);
3431aeb5019cSJung-uk Kim     if (limit - p <= i)
3432db522d3aSSimon L. B. Nielsen         return -1;
3433aeb5019cSJung-uk Kim     p += i;
3434aeb5019cSJung-uk Kim 
3435db522d3aSSimon L. B. Nielsen     /* Skip past compression algorithm list */
3436db522d3aSSimon L. B. Nielsen     i = *(p++);
3437aeb5019cSJung-uk Kim     if (limit - p < i)
3438db522d3aSSimon L. B. Nielsen         return -1;
3439aeb5019cSJung-uk Kim     p += i;
3440aeb5019cSJung-uk Kim 
3441db522d3aSSimon L. B. Nielsen     /* Now at start of extensions */
3442aeb5019cSJung-uk Kim     if (limit - p <= 2)
34431f13597dSJung-uk Kim         return 0;
3444db522d3aSSimon L. B. Nielsen     n2s(p, i);
3445aeb5019cSJung-uk Kim     while (limit - p >= 4) {
3446db522d3aSSimon L. B. Nielsen         unsigned short type, size;
3447db522d3aSSimon L. B. Nielsen         n2s(p, type);
3448db522d3aSSimon L. B. Nielsen         n2s(p, size);
3449aeb5019cSJung-uk Kim         if (limit - p < size)
34501f13597dSJung-uk Kim             return 0;
34516f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_session_ticket) {
34521f13597dSJung-uk Kim             int r;
34536f9291ceSJung-uk Kim             if (size == 0) {
34546f9291ceSJung-uk Kim                 /*
34556f9291ceSJung-uk Kim                  * The client will accept a ticket but doesn't currently have
34566f9291ceSJung-uk Kim                  * one.
34576f9291ceSJung-uk Kim                  */
3458db522d3aSSimon L. B. Nielsen                 s->tlsext_ticket_expected = 1;
34591f13597dSJung-uk Kim                 return 1;
3460db522d3aSSimon L. B. Nielsen             }
34616f9291ceSJung-uk Kim             if (s->tls_session_secret_cb) {
34626f9291ceSJung-uk Kim                 /*
34636f9291ceSJung-uk Kim                  * Indicate that the ticket couldn't be decrypted rather than
34646f9291ceSJung-uk Kim                  * generating the session from ticket now, trigger
34656f9291ceSJung-uk Kim                  * abbreviated handshake based on external mechanism to
34666f9291ceSJung-uk Kim                  * calculate the master secret later.
34676f9291ceSJung-uk Kim                  */
34681f13597dSJung-uk Kim                 return 2;
34691f13597dSJung-uk Kim             }
34701f13597dSJung-uk Kim             r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
34716f9291ceSJung-uk Kim             switch (r) {
34721f13597dSJung-uk Kim             case 2:            /* ticket couldn't be decrypted */
34731f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
34741f13597dSJung-uk Kim                 return 2;
34751f13597dSJung-uk Kim             case 3:            /* ticket was decrypted */
34761f13597dSJung-uk Kim                 return r;
34771f13597dSJung-uk Kim             case 4:            /* ticket decrypted but need to renew */
34781f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
34791f13597dSJung-uk Kim                 return 3;
34801f13597dSJung-uk Kim             default:           /* fatal error */
34811f13597dSJung-uk Kim                 return -1;
34821f13597dSJung-uk Kim             }
3483db522d3aSSimon L. B. Nielsen         }
3484db522d3aSSimon L. B. Nielsen         p += size;
3485db522d3aSSimon L. B. Nielsen     }
34861f13597dSJung-uk Kim     return 0;
3487db522d3aSSimon L. B. Nielsen }
3488db522d3aSSimon L. B. Nielsen 
34896f9291ceSJung-uk Kim /*-
34906f9291ceSJung-uk Kim  * tls_decrypt_ticket attempts to decrypt a session ticket.
34911f13597dSJung-uk Kim  *
34921f13597dSJung-uk Kim  *   etick: points to the body of the session ticket extension.
34931f13597dSJung-uk Kim  *   eticklen: the length of the session tickets extenion.
34941f13597dSJung-uk Kim  *   sess_id: points at the session ID.
34951f13597dSJung-uk Kim  *   sesslen: the length of the session ID.
34961f13597dSJung-uk Kim  *   psess: (output) on return, if a ticket was decrypted, then this is set to
34971f13597dSJung-uk Kim  *       point to the resulting session.
34981f13597dSJung-uk Kim  *
34991f13597dSJung-uk Kim  * Returns:
35001f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
35011f13597dSJung-uk Kim  *    2: the ticket couldn't be decrypted.
35021f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *psess was set.
35031f13597dSJung-uk Kim  *    4: same as 3, but the ticket needs to be renewed.
35041f13597dSJung-uk Kim  */
35056f9291ceSJung-uk Kim static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
35066f9291ceSJung-uk Kim                               int eticklen, const unsigned char *sess_id,
35076f9291ceSJung-uk Kim                               int sesslen, SSL_SESSION **psess)
3508db522d3aSSimon L. B. Nielsen {
3509db522d3aSSimon L. B. Nielsen     SSL_SESSION *sess;
3510db522d3aSSimon L. B. Nielsen     unsigned char *sdec;
3511db522d3aSSimon L. B. Nielsen     const unsigned char *p;
3512db522d3aSSimon L. B. Nielsen     int slen, mlen, renew_ticket = 0;
3513db522d3aSSimon L. B. Nielsen     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
3514db522d3aSSimon L. B. Nielsen     HMAC_CTX hctx;
3515db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX ctx;
35166a599222SSimon L. B. Nielsen     SSL_CTX *tctx = s->initial_ctx;
3517aeb5019cSJung-uk Kim 
3518*dee36b4fSJung-uk Kim     /* Need at least keyname + iv */
3519*dee36b4fSJung-uk Kim     if (eticklen < 16 + EVP_MAX_IV_LENGTH)
3520*dee36b4fSJung-uk Kim         return 2;
3521*dee36b4fSJung-uk Kim 
3522db522d3aSSimon L. B. Nielsen     /* Initialize session ticket encryption and HMAC contexts */
3523db522d3aSSimon L. B. Nielsen     HMAC_CTX_init(&hctx);
3524db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_init(&ctx);
35256f9291ceSJung-uk Kim     if (tctx->tlsext_ticket_key_cb) {
3526db522d3aSSimon L. B. Nielsen         unsigned char *nctick = (unsigned char *)etick;
35276a599222SSimon L. B. Nielsen         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
3528db522d3aSSimon L. B. Nielsen                                             &ctx, &hctx, 0);
3529db522d3aSSimon L. B. Nielsen         if (rv < 0)
3530*dee36b4fSJung-uk Kim             goto err;
3531*dee36b4fSJung-uk Kim         if (rv == 0) {
3532*dee36b4fSJung-uk Kim             HMAC_CTX_cleanup(&hctx);
3533*dee36b4fSJung-uk Kim             EVP_CIPHER_CTX_cleanup(&ctx);
35341f13597dSJung-uk Kim             return 2;
3535*dee36b4fSJung-uk Kim         }
3536db522d3aSSimon L. B. Nielsen         if (rv == 2)
3537db522d3aSSimon L. B. Nielsen             renew_ticket = 1;
35386f9291ceSJung-uk Kim     } else {
3539db522d3aSSimon L. B. Nielsen         /* Check key name matches */
35406a599222SSimon L. B. Nielsen         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
35411f13597dSJung-uk Kim             return 2;
354280815a77SJung-uk Kim         if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
354380815a77SJung-uk Kim                          tlsext_tick_md(), NULL) <= 0
354480815a77SJung-uk Kim                 || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
354580815a77SJung-uk Kim                                       tctx->tlsext_tick_aes_key,
354680815a77SJung-uk Kim                                       etick + 16) <= 0) {
354780815a77SJung-uk Kim             goto err;
354880815a77SJung-uk Kim        }
3549db522d3aSSimon L. B. Nielsen     }
35506f9291ceSJung-uk Kim     /*
35516f9291ceSJung-uk Kim      * Attempt to process session ticket, first conduct sanity and integrity
35526f9291ceSJung-uk Kim      * checks on ticket.
3553db522d3aSSimon L. B. Nielsen      */
3554db522d3aSSimon L. B. Nielsen     mlen = HMAC_size(&hctx);
35556f9291ceSJung-uk Kim     if (mlen < 0) {
355680815a77SJung-uk Kim         goto err;
35571f13597dSJung-uk Kim     }
3558aeb5019cSJung-uk Kim     /* Sanity check ticket length: must exceed keyname + IV + HMAC */
3559aeb5019cSJung-uk Kim     if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) {
3560aeb5019cSJung-uk Kim         HMAC_CTX_cleanup(&hctx);
3561aeb5019cSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
3562aeb5019cSJung-uk Kim         return 2;
3563aeb5019cSJung-uk Kim     }
3564aeb5019cSJung-uk Kim 
3565db522d3aSSimon L. B. Nielsen     eticklen -= mlen;
3566db522d3aSSimon L. B. Nielsen     /* Check HMAC of encrypted ticket */
356780815a77SJung-uk Kim     if (HMAC_Update(&hctx, etick, eticklen) <= 0
356880815a77SJung-uk Kim             || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
356980815a77SJung-uk Kim         goto err;
357080815a77SJung-uk Kim     }
3571db522d3aSSimon L. B. Nielsen     HMAC_CTX_cleanup(&hctx);
35726f9291ceSJung-uk Kim     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
3573fa5fddf1SJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
35741f13597dSJung-uk Kim         return 2;
3575fa5fddf1SJung-uk Kim     }
3576db522d3aSSimon L. B. Nielsen     /* Attempt to decrypt session data */
3577db522d3aSSimon L. B. Nielsen     /* Move p after IV to start of encrypted ticket, update length */
3578db522d3aSSimon L. B. Nielsen     p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
3579db522d3aSSimon L. B. Nielsen     eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
3580db522d3aSSimon L. B. Nielsen     sdec = OPENSSL_malloc(eticklen);
3581b8721c16SJung-uk Kim     if (sdec == NULL
3582b8721c16SJung-uk Kim             || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
3583db522d3aSSimon L. B. Nielsen         EVP_CIPHER_CTX_cleanup(&ctx);
3584b8721c16SJung-uk Kim         OPENSSL_free(sdec);
3585db522d3aSSimon L. B. Nielsen         return -1;
3586db522d3aSSimon L. B. Nielsen     }
35876f9291ceSJung-uk Kim     if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
3588a93cbc2bSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
3589a93cbc2bSJung-uk Kim         OPENSSL_free(sdec);
35901f13597dSJung-uk Kim         return 2;
3591a93cbc2bSJung-uk Kim     }
3592db522d3aSSimon L. B. Nielsen     slen += mlen;
3593db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_cleanup(&ctx);
3594db522d3aSSimon L. B. Nielsen     p = sdec;
3595db522d3aSSimon L. B. Nielsen 
3596db522d3aSSimon L. B. Nielsen     sess = d2i_SSL_SESSION(NULL, &p, slen);
3597ed7112f0SJung-uk Kim     slen -= p - sdec;
3598db522d3aSSimon L. B. Nielsen     OPENSSL_free(sdec);
35996f9291ceSJung-uk Kim     if (sess) {
3600ed7112f0SJung-uk Kim         /* Some additional consistency checks */
3601ed7112f0SJung-uk Kim         if (slen != 0 || sess->session_id_length != 0) {
3602ed7112f0SJung-uk Kim             SSL_SESSION_free(sess);
3603ed7112f0SJung-uk Kim             return 2;
3604ed7112f0SJung-uk Kim         }
36056f9291ceSJung-uk Kim         /*
36066f9291ceSJung-uk Kim          * The session ID, if non-empty, is used by some clients to detect
36076f9291ceSJung-uk Kim          * that the ticket has been accepted. So we copy it to the session
36086f9291ceSJung-uk Kim          * structure. If it is empty set length to zero as required by
36096f9291ceSJung-uk Kim          * standard.
3610db522d3aSSimon L. B. Nielsen          */
3611db522d3aSSimon L. B. Nielsen         if (sesslen)
3612db522d3aSSimon L. B. Nielsen             memcpy(sess->session_id, sess_id, sesslen);
3613db522d3aSSimon L. B. Nielsen         sess->session_id_length = sesslen;
3614db522d3aSSimon L. B. Nielsen         *psess = sess;
36151f13597dSJung-uk Kim         if (renew_ticket)
36161f13597dSJung-uk Kim             return 4;
36171f13597dSJung-uk Kim         else
36181f13597dSJung-uk Kim             return 3;
36191f13597dSJung-uk Kim     }
36201f13597dSJung-uk Kim     ERR_clear_error();
36216f9291ceSJung-uk Kim     /*
36226f9291ceSJung-uk Kim      * For session parse failure, indicate that we need to send a new ticket.
36236f9291ceSJung-uk Kim      */
36241f13597dSJung-uk Kim     return 2;
362580815a77SJung-uk Kim err:
362680815a77SJung-uk Kim     EVP_CIPHER_CTX_cleanup(&ctx);
362780815a77SJung-uk Kim     HMAC_CTX_cleanup(&hctx);
362880815a77SJung-uk Kim     return -1;
36291f13597dSJung-uk Kim }
36301f13597dSJung-uk Kim 
36311f13597dSJung-uk Kim /* Tables to translate from NIDs to TLS v1.2 ids */
36321f13597dSJung-uk Kim 
36336f9291ceSJung-uk Kim typedef struct {
36341f13597dSJung-uk Kim     int nid;
36351f13597dSJung-uk Kim     int id;
36361f13597dSJung-uk Kim } tls12_lookup;
36371f13597dSJung-uk Kim 
36381f13597dSJung-uk Kim static tls12_lookup tls12_md[] = {
36391f13597dSJung-uk Kim     {NID_md5, TLSEXT_hash_md5},
36401f13597dSJung-uk Kim     {NID_sha1, TLSEXT_hash_sha1},
36411f13597dSJung-uk Kim     {NID_sha224, TLSEXT_hash_sha224},
36421f13597dSJung-uk Kim     {NID_sha256, TLSEXT_hash_sha256},
36431f13597dSJung-uk Kim     {NID_sha384, TLSEXT_hash_sha384},
36441f13597dSJung-uk Kim     {NID_sha512, TLSEXT_hash_sha512}
36451f13597dSJung-uk Kim };
36461f13597dSJung-uk Kim 
36471f13597dSJung-uk Kim static tls12_lookup tls12_sig[] = {
36481f13597dSJung-uk Kim     {EVP_PKEY_RSA, TLSEXT_signature_rsa},
36491f13597dSJung-uk Kim     {EVP_PKEY_DSA, TLSEXT_signature_dsa},
36501f13597dSJung-uk Kim     {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
36511f13597dSJung-uk Kim };
36521f13597dSJung-uk Kim 
36531f13597dSJung-uk Kim static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
36541f13597dSJung-uk Kim {
36551f13597dSJung-uk Kim     size_t i;
36566f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
36571f13597dSJung-uk Kim         if (table[i].nid == nid)
36581f13597dSJung-uk Kim             return table[i].id;
36591f13597dSJung-uk Kim     }
36601f13597dSJung-uk Kim     return -1;
36611f13597dSJung-uk Kim }
36626f9291ceSJung-uk Kim 
36631f13597dSJung-uk Kim static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
36641f13597dSJung-uk Kim {
36651f13597dSJung-uk Kim     size_t i;
36666f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
36677bded2dbSJung-uk Kim         if ((table[i].id) == id)
36681f13597dSJung-uk Kim             return table[i].nid;
36691f13597dSJung-uk Kim     }
36707bded2dbSJung-uk Kim     return NID_undef;
36711f13597dSJung-uk Kim }
36721f13597dSJung-uk Kim 
36736f9291ceSJung-uk Kim int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
36746f9291ceSJung-uk Kim                          const EVP_MD *md)
36751f13597dSJung-uk Kim {
36761f13597dSJung-uk Kim     int sig_id, md_id;
36771f13597dSJung-uk Kim     if (!md)
36781f13597dSJung-uk Kim         return 0;
36791f13597dSJung-uk Kim     md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
36801f13597dSJung-uk Kim                           sizeof(tls12_md) / sizeof(tls12_lookup));
36811f13597dSJung-uk Kim     if (md_id == -1)
36821f13597dSJung-uk Kim         return 0;
36831f13597dSJung-uk Kim     sig_id = tls12_get_sigid(pk);
36841f13597dSJung-uk Kim     if (sig_id == -1)
36851f13597dSJung-uk Kim         return 0;
36861f13597dSJung-uk Kim     p[0] = (unsigned char)md_id;
36871f13597dSJung-uk Kim     p[1] = (unsigned char)sig_id;
3688db522d3aSSimon L. B. Nielsen     return 1;
3689db522d3aSSimon L. B. Nielsen }
36901f13597dSJung-uk Kim 
36911f13597dSJung-uk Kim int tls12_get_sigid(const EVP_PKEY *pk)
36921f13597dSJung-uk Kim {
36931f13597dSJung-uk Kim     return tls12_find_id(pk->type, tls12_sig,
36941f13597dSJung-uk Kim                          sizeof(tls12_sig) / sizeof(tls12_lookup));
36951f13597dSJung-uk Kim }
36961f13597dSJung-uk Kim 
36971f13597dSJung-uk Kim const EVP_MD *tls12_get_hash(unsigned char hash_alg)
36981f13597dSJung-uk Kim {
36996f9291ceSJung-uk Kim     switch (hash_alg) {
37007bded2dbSJung-uk Kim # ifndef OPENSSL_NO_MD5
37017bded2dbSJung-uk Kim     case TLSEXT_hash_md5:
37027bded2dbSJung-uk Kim #  ifdef OPENSSL_FIPS
37037bded2dbSJung-uk Kim         if (FIPS_mode())
37047bded2dbSJung-uk Kim             return NULL;
37057bded2dbSJung-uk Kim #  endif
37067bded2dbSJung-uk Kim         return EVP_md5();
37077bded2dbSJung-uk Kim # endif
37081f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
37091f13597dSJung-uk Kim     case TLSEXT_hash_sha1:
37101f13597dSJung-uk Kim         return EVP_sha1();
37111f13597dSJung-uk Kim # endif
37121f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
37131f13597dSJung-uk Kim     case TLSEXT_hash_sha224:
37141f13597dSJung-uk Kim         return EVP_sha224();
37151f13597dSJung-uk Kim 
37161f13597dSJung-uk Kim     case TLSEXT_hash_sha256:
37171f13597dSJung-uk Kim         return EVP_sha256();
37181f13597dSJung-uk Kim # endif
37191f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
37201f13597dSJung-uk Kim     case TLSEXT_hash_sha384:
37211f13597dSJung-uk Kim         return EVP_sha384();
37221f13597dSJung-uk Kim 
37231f13597dSJung-uk Kim     case TLSEXT_hash_sha512:
37241f13597dSJung-uk Kim         return EVP_sha512();
37251f13597dSJung-uk Kim # endif
37261f13597dSJung-uk Kim     default:
37271f13597dSJung-uk Kim         return NULL;
37281f13597dSJung-uk Kim 
37291f13597dSJung-uk Kim     }
37301f13597dSJung-uk Kim }
37311f13597dSJung-uk Kim 
37327bded2dbSJung-uk Kim static int tls12_get_pkey_idx(unsigned char sig_alg)
37337bded2dbSJung-uk Kim {
37347bded2dbSJung-uk Kim     switch (sig_alg) {
37357bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA
37367bded2dbSJung-uk Kim     case TLSEXT_signature_rsa:
37377bded2dbSJung-uk Kim         return SSL_PKEY_RSA_SIGN;
37387bded2dbSJung-uk Kim # endif
37397bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA
37407bded2dbSJung-uk Kim     case TLSEXT_signature_dsa:
37417bded2dbSJung-uk Kim         return SSL_PKEY_DSA_SIGN;
37427bded2dbSJung-uk Kim # endif
37437bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
37447bded2dbSJung-uk Kim     case TLSEXT_signature_ecdsa:
37457bded2dbSJung-uk Kim         return SSL_PKEY_ECC;
37467bded2dbSJung-uk Kim # endif
37477bded2dbSJung-uk Kim     }
37487bded2dbSJung-uk Kim     return -1;
37497bded2dbSJung-uk Kim }
37507bded2dbSJung-uk Kim 
37517bded2dbSJung-uk Kim /* Convert TLS 1.2 signature algorithm extension values into NIDs */
37527bded2dbSJung-uk Kim static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
37537bded2dbSJung-uk Kim                                int *psignhash_nid, const unsigned char *data)
37547bded2dbSJung-uk Kim {
37558180e704SJung-uk Kim     int sign_nid = NID_undef, hash_nid = NID_undef;
37567bded2dbSJung-uk Kim     if (!phash_nid && !psign_nid && !psignhash_nid)
37577bded2dbSJung-uk Kim         return;
37587bded2dbSJung-uk Kim     if (phash_nid || psignhash_nid) {
37597bded2dbSJung-uk Kim         hash_nid = tls12_find_nid(data[0], tls12_md,
37607bded2dbSJung-uk Kim                                   sizeof(tls12_md) / sizeof(tls12_lookup));
37617bded2dbSJung-uk Kim         if (phash_nid)
37627bded2dbSJung-uk Kim             *phash_nid = hash_nid;
37637bded2dbSJung-uk Kim     }
37647bded2dbSJung-uk Kim     if (psign_nid || psignhash_nid) {
37657bded2dbSJung-uk Kim         sign_nid = tls12_find_nid(data[1], tls12_sig,
37667bded2dbSJung-uk Kim                                   sizeof(tls12_sig) / sizeof(tls12_lookup));
37677bded2dbSJung-uk Kim         if (psign_nid)
37687bded2dbSJung-uk Kim             *psign_nid = sign_nid;
37697bded2dbSJung-uk Kim     }
37707bded2dbSJung-uk Kim     if (psignhash_nid) {
37718180e704SJung-uk Kim         if (sign_nid == NID_undef || hash_nid == NID_undef
37728180e704SJung-uk Kim                 || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid,
37738180e704SJung-uk Kim                                           sign_nid) <= 0)
37747bded2dbSJung-uk Kim             *psignhash_nid = NID_undef;
37757bded2dbSJung-uk Kim     }
37767bded2dbSJung-uk Kim }
37777bded2dbSJung-uk Kim 
37787bded2dbSJung-uk Kim /* Given preference and allowed sigalgs set shared sigalgs */
37797bded2dbSJung-uk Kim static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig,
37807bded2dbSJung-uk Kim                                    const unsigned char *pref, size_t preflen,
37817bded2dbSJung-uk Kim                                    const unsigned char *allow,
37827bded2dbSJung-uk Kim                                    size_t allowlen)
37837bded2dbSJung-uk Kim {
37847bded2dbSJung-uk Kim     const unsigned char *ptmp, *atmp;
37857bded2dbSJung-uk Kim     size_t i, j, nmatch = 0;
37867bded2dbSJung-uk Kim     for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
37877bded2dbSJung-uk Kim         /* Skip disabled hashes or signature algorithms */
37887bded2dbSJung-uk Kim         if (tls12_get_hash(ptmp[0]) == NULL)
37897bded2dbSJung-uk Kim             continue;
37907bded2dbSJung-uk Kim         if (tls12_get_pkey_idx(ptmp[1]) == -1)
37917bded2dbSJung-uk Kim             continue;
37927bded2dbSJung-uk Kim         for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
37937bded2dbSJung-uk Kim             if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
37947bded2dbSJung-uk Kim                 nmatch++;
37957bded2dbSJung-uk Kim                 if (shsig) {
37967bded2dbSJung-uk Kim                     shsig->rhash = ptmp[0];
37977bded2dbSJung-uk Kim                     shsig->rsign = ptmp[1];
37987bded2dbSJung-uk Kim                     tls1_lookup_sigalg(&shsig->hash_nid,
37997bded2dbSJung-uk Kim                                        &shsig->sign_nid,
38007bded2dbSJung-uk Kim                                        &shsig->signandhash_nid, ptmp);
38017bded2dbSJung-uk Kim                     shsig++;
38027bded2dbSJung-uk Kim                 }
38037bded2dbSJung-uk Kim                 break;
38047bded2dbSJung-uk Kim             }
38057bded2dbSJung-uk Kim         }
38067bded2dbSJung-uk Kim     }
38077bded2dbSJung-uk Kim     return nmatch;
38087bded2dbSJung-uk Kim }
38097bded2dbSJung-uk Kim 
38107bded2dbSJung-uk Kim /* Set shared signature algorithms for SSL structures */
38117bded2dbSJung-uk Kim static int tls1_set_shared_sigalgs(SSL *s)
38127bded2dbSJung-uk Kim {
38137bded2dbSJung-uk Kim     const unsigned char *pref, *allow, *conf;
38147bded2dbSJung-uk Kim     size_t preflen, allowlen, conflen;
38157bded2dbSJung-uk Kim     size_t nmatch;
38167bded2dbSJung-uk Kim     TLS_SIGALGS *salgs = NULL;
38177bded2dbSJung-uk Kim     CERT *c = s->cert;
38187bded2dbSJung-uk Kim     unsigned int is_suiteb = tls1_suiteb(s);
38197bded2dbSJung-uk Kim     if (c->shared_sigalgs) {
38207bded2dbSJung-uk Kim         OPENSSL_free(c->shared_sigalgs);
38217bded2dbSJung-uk Kim         c->shared_sigalgs = NULL;
38227bded2dbSJung-uk Kim         c->shared_sigalgslen = 0;
38237bded2dbSJung-uk Kim     }
38247bded2dbSJung-uk Kim     /* If client use client signature algorithms if not NULL */
38257bded2dbSJung-uk Kim     if (!s->server && c->client_sigalgs && !is_suiteb) {
38267bded2dbSJung-uk Kim         conf = c->client_sigalgs;
38277bded2dbSJung-uk Kim         conflen = c->client_sigalgslen;
38287bded2dbSJung-uk Kim     } else if (c->conf_sigalgs && !is_suiteb) {
38297bded2dbSJung-uk Kim         conf = c->conf_sigalgs;
38307bded2dbSJung-uk Kim         conflen = c->conf_sigalgslen;
38317bded2dbSJung-uk Kim     } else
3832ed7112f0SJung-uk Kim         conflen = tls12_get_psigalgs(s, 0, &conf);
38337bded2dbSJung-uk Kim     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
38347bded2dbSJung-uk Kim         pref = conf;
38357bded2dbSJung-uk Kim         preflen = conflen;
38367bded2dbSJung-uk Kim         allow = c->peer_sigalgs;
38377bded2dbSJung-uk Kim         allowlen = c->peer_sigalgslen;
38387bded2dbSJung-uk Kim     } else {
38397bded2dbSJung-uk Kim         allow = conf;
38407bded2dbSJung-uk Kim         allowlen = conflen;
38417bded2dbSJung-uk Kim         pref = c->peer_sigalgs;
38427bded2dbSJung-uk Kim         preflen = c->peer_sigalgslen;
38437bded2dbSJung-uk Kim     }
38447bded2dbSJung-uk Kim     nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
38457bded2dbSJung-uk Kim     if (nmatch) {
38467bded2dbSJung-uk Kim         salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
38477bded2dbSJung-uk Kim         if (!salgs)
38487bded2dbSJung-uk Kim             return 0;
38497bded2dbSJung-uk Kim         nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
38507bded2dbSJung-uk Kim     } else {
38517bded2dbSJung-uk Kim         salgs = NULL;
38527bded2dbSJung-uk Kim     }
38537bded2dbSJung-uk Kim     c->shared_sigalgs = salgs;
38547bded2dbSJung-uk Kim     c->shared_sigalgslen = nmatch;
38557bded2dbSJung-uk Kim     return 1;
38567bded2dbSJung-uk Kim }
38577bded2dbSJung-uk Kim 
38581f13597dSJung-uk Kim /* Set preferred digest for each key type */
38591f13597dSJung-uk Kim 
38607bded2dbSJung-uk Kim int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
38611f13597dSJung-uk Kim {
38621f13597dSJung-uk Kim     CERT *c = s->cert;
38637bded2dbSJung-uk Kim     /* Extension ignored for inappropriate versions */
38647bded2dbSJung-uk Kim     if (!SSL_USE_SIGALGS(s))
38651f13597dSJung-uk Kim         return 1;
38661f13597dSJung-uk Kim     /* Should never happen */
38671f13597dSJung-uk Kim     if (!c)
38681f13597dSJung-uk Kim         return 0;
38691f13597dSJung-uk Kim 
38707bded2dbSJung-uk Kim     if (c->peer_sigalgs)
38717bded2dbSJung-uk Kim         OPENSSL_free(c->peer_sigalgs);
38727bded2dbSJung-uk Kim     c->peer_sigalgs = OPENSSL_malloc(dsize);
38737bded2dbSJung-uk Kim     if (!c->peer_sigalgs)
38747bded2dbSJung-uk Kim         return 0;
38757bded2dbSJung-uk Kim     c->peer_sigalgslen = dsize;
38767bded2dbSJung-uk Kim     memcpy(c->peer_sigalgs, data, dsize);
38777bded2dbSJung-uk Kim     return 1;
38781f13597dSJung-uk Kim }
38791f13597dSJung-uk Kim 
38807bded2dbSJung-uk Kim int tls1_process_sigalgs(SSL *s)
38817bded2dbSJung-uk Kim {
38827bded2dbSJung-uk Kim     int idx;
38837bded2dbSJung-uk Kim     size_t i;
38847bded2dbSJung-uk Kim     const EVP_MD *md;
38857bded2dbSJung-uk Kim     CERT *c = s->cert;
38867bded2dbSJung-uk Kim     TLS_SIGALGS *sigptr;
38877bded2dbSJung-uk Kim     if (!tls1_set_shared_sigalgs(s))
38887bded2dbSJung-uk Kim         return 0;
38897bded2dbSJung-uk Kim 
38907bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
38917bded2dbSJung-uk Kim     if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
38927bded2dbSJung-uk Kim         /*
38937bded2dbSJung-uk Kim          * Use first set signature preference to force message digest,
38947bded2dbSJung-uk Kim          * ignoring any peer preferences.
38957bded2dbSJung-uk Kim          */
38967bded2dbSJung-uk Kim         const unsigned char *sigs = NULL;
38977bded2dbSJung-uk Kim         if (s->server)
38987bded2dbSJung-uk Kim             sigs = c->conf_sigalgs;
38997bded2dbSJung-uk Kim         else
39007bded2dbSJung-uk Kim             sigs = c->client_sigalgs;
39017bded2dbSJung-uk Kim         if (sigs) {
39027bded2dbSJung-uk Kim             idx = tls12_get_pkey_idx(sigs[1]);
39037bded2dbSJung-uk Kim             md = tls12_get_hash(sigs[0]);
39041f13597dSJung-uk Kim             c->pkeys[idx].digest = md;
39057bded2dbSJung-uk Kim             c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
39067bded2dbSJung-uk Kim             if (idx == SSL_PKEY_RSA_SIGN) {
39077bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
39087bded2dbSJung-uk Kim                     CERT_PKEY_EXPLICIT_SIGN;
39097bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
39107bded2dbSJung-uk Kim             }
39117bded2dbSJung-uk Kim         }
39127bded2dbSJung-uk Kim     }
39137bded2dbSJung-uk Kim # endif
39147bded2dbSJung-uk Kim 
39157bded2dbSJung-uk Kim     for (i = 0, sigptr = c->shared_sigalgs;
39167bded2dbSJung-uk Kim          i < c->shared_sigalgslen; i++, sigptr++) {
39177bded2dbSJung-uk Kim         idx = tls12_get_pkey_idx(sigptr->rsign);
39187bded2dbSJung-uk Kim         if (idx > 0 && c->pkeys[idx].digest == NULL) {
39197bded2dbSJung-uk Kim             md = tls12_get_hash(sigptr->rhash);
39207bded2dbSJung-uk Kim             c->pkeys[idx].digest = md;
39217bded2dbSJung-uk Kim             c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
39227bded2dbSJung-uk Kim             if (idx == SSL_PKEY_RSA_SIGN) {
39237bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
39247bded2dbSJung-uk Kim                     CERT_PKEY_EXPLICIT_SIGN;
39251f13597dSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
39261f13597dSJung-uk Kim             }
39271f13597dSJung-uk Kim         }
39281f13597dSJung-uk Kim 
39291f13597dSJung-uk Kim     }
39307bded2dbSJung-uk Kim     /*
39317bded2dbSJung-uk Kim      * In strict mode leave unset digests as NULL to indicate we can't use
39327bded2dbSJung-uk Kim      * the certificate for signing.
39337bded2dbSJung-uk Kim      */
39347bded2dbSJung-uk Kim     if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
39356f9291ceSJung-uk Kim         /*
39366f9291ceSJung-uk Kim          * Set any remaining keys to default values. NOTE: if alg is not
39371f13597dSJung-uk Kim          * supported it stays as NULL.
3938db522d3aSSimon L. B. Nielsen          */
39391f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA
39401f13597dSJung-uk Kim         if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
394109286989SJung-uk Kim             c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
39421f13597dSJung-uk Kim # endif
39431f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA
39446f9291ceSJung-uk Kim         if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
39451f13597dSJung-uk Kim             c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
39461f13597dSJung-uk Kim             c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
39471f13597dSJung-uk Kim         }
39481f13597dSJung-uk Kim # endif
39491f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
39501f13597dSJung-uk Kim         if (!c->pkeys[SSL_PKEY_ECC].digest)
395109286989SJung-uk Kim             c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
39521f13597dSJung-uk Kim # endif
39537bded2dbSJung-uk Kim     }
39541f13597dSJung-uk Kim     return 1;
39551f13597dSJung-uk Kim }
39561f13597dSJung-uk Kim 
39577bded2dbSJung-uk Kim int SSL_get_sigalgs(SSL *s, int idx,
39587bded2dbSJung-uk Kim                     int *psign, int *phash, int *psignhash,
39597bded2dbSJung-uk Kim                     unsigned char *rsig, unsigned char *rhash)
39607bded2dbSJung-uk Kim {
39617bded2dbSJung-uk Kim     const unsigned char *psig = s->cert->peer_sigalgs;
39627bded2dbSJung-uk Kim     if (psig == NULL)
39637bded2dbSJung-uk Kim         return 0;
39647bded2dbSJung-uk Kim     if (idx >= 0) {
39657bded2dbSJung-uk Kim         idx <<= 1;
39667bded2dbSJung-uk Kim         if (idx >= (int)s->cert->peer_sigalgslen)
39677bded2dbSJung-uk Kim             return 0;
39687bded2dbSJung-uk Kim         psig += idx;
39697bded2dbSJung-uk Kim         if (rhash)
39707bded2dbSJung-uk Kim             *rhash = psig[0];
39717bded2dbSJung-uk Kim         if (rsig)
39727bded2dbSJung-uk Kim             *rsig = psig[1];
39737bded2dbSJung-uk Kim         tls1_lookup_sigalg(phash, psign, psignhash, psig);
39747bded2dbSJung-uk Kim     }
39757bded2dbSJung-uk Kim     return s->cert->peer_sigalgslen / 2;
39767bded2dbSJung-uk Kim }
39777bded2dbSJung-uk Kim 
39787bded2dbSJung-uk Kim int SSL_get_shared_sigalgs(SSL *s, int idx,
39797bded2dbSJung-uk Kim                            int *psign, int *phash, int *psignhash,
39807bded2dbSJung-uk Kim                            unsigned char *rsig, unsigned char *rhash)
39817bded2dbSJung-uk Kim {
39827bded2dbSJung-uk Kim     TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
39837bded2dbSJung-uk Kim     if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen)
39847bded2dbSJung-uk Kim         return 0;
39857bded2dbSJung-uk Kim     shsigalgs += idx;
39867bded2dbSJung-uk Kim     if (phash)
39877bded2dbSJung-uk Kim         *phash = shsigalgs->hash_nid;
39887bded2dbSJung-uk Kim     if (psign)
39897bded2dbSJung-uk Kim         *psign = shsigalgs->sign_nid;
39907bded2dbSJung-uk Kim     if (psignhash)
39917bded2dbSJung-uk Kim         *psignhash = shsigalgs->signandhash_nid;
39927bded2dbSJung-uk Kim     if (rsig)
39937bded2dbSJung-uk Kim         *rsig = shsigalgs->rsign;
39947bded2dbSJung-uk Kim     if (rhash)
39957bded2dbSJung-uk Kim         *rhash = shsigalgs->rhash;
39967bded2dbSJung-uk Kim     return s->cert->shared_sigalgslen;
39977bded2dbSJung-uk Kim }
39981f13597dSJung-uk Kim 
39991f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
40006f9291ceSJung-uk Kim int tls1_process_heartbeat(SSL *s)
40011f13597dSJung-uk Kim {
40021f13597dSJung-uk Kim     unsigned char *p = &s->s3->rrec.data[0], *pl;
40031f13597dSJung-uk Kim     unsigned short hbtype;
40041f13597dSJung-uk Kim     unsigned int payload;
40051f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
40061f13597dSJung-uk Kim 
40071f13597dSJung-uk Kim     if (s->msg_callback)
40081f13597dSJung-uk Kim         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
40091f13597dSJung-uk Kim                         &s->s3->rrec.data[0], s->s3->rrec.length,
40101f13597dSJung-uk Kim                         s, s->msg_callback_arg);
40111f13597dSJung-uk Kim 
401225bfde79SXin LI     /* Read type and payload length first */
401325bfde79SXin LI     if (1 + 2 + 16 > s->s3->rrec.length)
401425bfde79SXin LI         return 0;               /* silently discard */
401525bfde79SXin LI     hbtype = *p++;
401625bfde79SXin LI     n2s(p, payload);
401725bfde79SXin LI     if (1 + 2 + payload + 16 > s->s3->rrec.length)
401825bfde79SXin LI         return 0;               /* silently discard per RFC 6520 sec. 4 */
401925bfde79SXin LI     pl = p;
402025bfde79SXin LI 
40216f9291ceSJung-uk Kim     if (hbtype == TLS1_HB_REQUEST) {
40221f13597dSJung-uk Kim         unsigned char *buffer, *bp;
40231f13597dSJung-uk Kim         int r;
40241f13597dSJung-uk Kim 
40256f9291ceSJung-uk Kim         /*
40266f9291ceSJung-uk Kim          * Allocate memory for the response, size is 1 bytes message type,
40276f9291ceSJung-uk Kim          * plus 2 bytes payload length, plus payload, plus padding
40281f13597dSJung-uk Kim          */
40291f13597dSJung-uk Kim         buffer = OPENSSL_malloc(1 + 2 + payload + padding);
4030b8721c16SJung-uk Kim         if (buffer == NULL)
4031b8721c16SJung-uk Kim             return -1;
40321f13597dSJung-uk Kim         bp = buffer;
40331f13597dSJung-uk Kim 
40341f13597dSJung-uk Kim         /* Enter response type, length and copy payload */
40351f13597dSJung-uk Kim         *bp++ = TLS1_HB_RESPONSE;
40361f13597dSJung-uk Kim         s2n(payload, bp);
40371f13597dSJung-uk Kim         memcpy(bp, pl, payload);
40381f13597dSJung-uk Kim         bp += payload;
40391f13597dSJung-uk Kim         /* Random padding */
4040aeb5019cSJung-uk Kim         if (RAND_bytes(bp, padding) <= 0) {
4041ed6b93beSJung-uk Kim             OPENSSL_free(buffer);
4042ed6b93beSJung-uk Kim             return -1;
4043ed6b93beSJung-uk Kim         }
40441f13597dSJung-uk Kim 
40456f9291ceSJung-uk Kim         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
40466f9291ceSJung-uk Kim                              3 + payload + padding);
40471f13597dSJung-uk Kim 
40481f13597dSJung-uk Kim         if (r >= 0 && s->msg_callback)
40491f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
40501f13597dSJung-uk Kim                             buffer, 3 + payload + padding,
40511f13597dSJung-uk Kim                             s, s->msg_callback_arg);
40521f13597dSJung-uk Kim 
40531f13597dSJung-uk Kim         OPENSSL_free(buffer);
40541f13597dSJung-uk Kim 
40551f13597dSJung-uk Kim         if (r < 0)
40561f13597dSJung-uk Kim             return r;
40576f9291ceSJung-uk Kim     } else if (hbtype == TLS1_HB_RESPONSE) {
40581f13597dSJung-uk Kim         unsigned int seq;
40591f13597dSJung-uk Kim 
40606f9291ceSJung-uk Kim         /*
40616f9291ceSJung-uk Kim          * We only send sequence numbers (2 bytes unsigned int), and 16
40626f9291ceSJung-uk Kim          * random bytes, so we just try to read the sequence number
40636f9291ceSJung-uk Kim          */
40641f13597dSJung-uk Kim         n2s(pl, seq);
40651f13597dSJung-uk Kim 
40666f9291ceSJung-uk Kim         if (payload == 18 && seq == s->tlsext_hb_seq) {
40671f13597dSJung-uk Kim             s->tlsext_hb_seq++;
40681f13597dSJung-uk Kim             s->tlsext_hb_pending = 0;
40691f13597dSJung-uk Kim         }
40701f13597dSJung-uk Kim     }
40711f13597dSJung-uk Kim 
4072db522d3aSSimon L. B. Nielsen     return 0;
4073db522d3aSSimon L. B. Nielsen }
4074db522d3aSSimon L. B. Nielsen 
40756f9291ceSJung-uk Kim int tls1_heartbeat(SSL *s)
40761f13597dSJung-uk Kim {
40771f13597dSJung-uk Kim     unsigned char *buf, *p;
4078ed6b93beSJung-uk Kim     int ret = -1;
40791f13597dSJung-uk Kim     unsigned int payload = 18;  /* Sequence number + random bytes */
40801f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
40811f13597dSJung-uk Kim 
40821f13597dSJung-uk Kim     /* Only send if peer supports and accepts HB requests... */
40831f13597dSJung-uk Kim     if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
40846f9291ceSJung-uk Kim         s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
40851f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
40861f13597dSJung-uk Kim         return -1;
40871f13597dSJung-uk Kim     }
40881f13597dSJung-uk Kim 
40891f13597dSJung-uk Kim     /* ...and there is none in flight yet... */
40906f9291ceSJung-uk Kim     if (s->tlsext_hb_pending) {
40911f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
40921f13597dSJung-uk Kim         return -1;
40931f13597dSJung-uk Kim     }
40941f13597dSJung-uk Kim 
40951f13597dSJung-uk Kim     /* ...and no handshake in progress. */
40966f9291ceSJung-uk Kim     if (SSL_in_init(s) || s->in_handshake) {
40971f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
40981f13597dSJung-uk Kim         return -1;
40991f13597dSJung-uk Kim     }
41001f13597dSJung-uk Kim 
41016f9291ceSJung-uk Kim     /*
41026f9291ceSJung-uk Kim      * Check if padding is too long, payload and padding must not exceed 2^14
41036f9291ceSJung-uk Kim      * - 3 = 16381 bytes in total.
41041f13597dSJung-uk Kim      */
41051f13597dSJung-uk Kim     OPENSSL_assert(payload + padding <= 16381);
41061f13597dSJung-uk Kim 
41076f9291ceSJung-uk Kim     /*-
41086f9291ceSJung-uk Kim      * Create HeartBeat message, we just use a sequence number
41091f13597dSJung-uk Kim      * as payload to distuingish different messages and add
41101f13597dSJung-uk Kim      * some random stuff.
41111f13597dSJung-uk Kim      *  - Message Type, 1 byte
41121f13597dSJung-uk Kim      *  - Payload Length, 2 bytes (unsigned int)
41131f13597dSJung-uk Kim      *  - Payload, the sequence number (2 bytes uint)
41141f13597dSJung-uk Kim      *  - Payload, random bytes (16 bytes uint)
41151f13597dSJung-uk Kim      *  - Padding
41161f13597dSJung-uk Kim      */
41171f13597dSJung-uk Kim     buf = OPENSSL_malloc(1 + 2 + payload + padding);
4118aeb5019cSJung-uk Kim     if (buf == NULL)
4119aeb5019cSJung-uk Kim         return -1;
41201f13597dSJung-uk Kim     p = buf;
41211f13597dSJung-uk Kim     /* Message Type */
41221f13597dSJung-uk Kim     *p++ = TLS1_HB_REQUEST;
41231f13597dSJung-uk Kim     /* Payload length (18 bytes here) */
41241f13597dSJung-uk Kim     s2n(payload, p);
41251f13597dSJung-uk Kim     /* Sequence number */
41261f13597dSJung-uk Kim     s2n(s->tlsext_hb_seq, p);
41271f13597dSJung-uk Kim     /* 16 random bytes */
4128aeb5019cSJung-uk Kim     if (RAND_bytes(p, 16) <= 0) {
4129ed6b93beSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
4130ed6b93beSJung-uk Kim         goto err;
4131ed6b93beSJung-uk Kim     }
41321f13597dSJung-uk Kim     p += 16;
41331f13597dSJung-uk Kim     /* Random padding */
4134aeb5019cSJung-uk Kim     if (RAND_bytes(p, padding) <= 0) {
4135ed6b93beSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
4136ed6b93beSJung-uk Kim         goto err;
4137ed6b93beSJung-uk Kim     }
41381f13597dSJung-uk Kim 
41391f13597dSJung-uk Kim     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
41406f9291ceSJung-uk Kim     if (ret >= 0) {
41411f13597dSJung-uk Kim         if (s->msg_callback)
41421f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
41431f13597dSJung-uk Kim                             buf, 3 + payload + padding,
41441f13597dSJung-uk Kim                             s, s->msg_callback_arg);
41451f13597dSJung-uk Kim 
41461f13597dSJung-uk Kim         s->tlsext_hb_pending = 1;
41471f13597dSJung-uk Kim     }
41481f13597dSJung-uk Kim 
4149ed6b93beSJung-uk Kim err:
41501f13597dSJung-uk Kim     OPENSSL_free(buf);
41511f13597dSJung-uk Kim 
41521f13597dSJung-uk Kim     return ret;
41531f13597dSJung-uk Kim }
4154db522d3aSSimon L. B. Nielsen # endif
41557bded2dbSJung-uk Kim 
41567bded2dbSJung-uk Kim # define MAX_SIGALGLEN   (TLSEXT_hash_num * TLSEXT_signature_num * 2)
41577bded2dbSJung-uk Kim 
41587bded2dbSJung-uk Kim typedef struct {
41597bded2dbSJung-uk Kim     size_t sigalgcnt;
41607bded2dbSJung-uk Kim     int sigalgs[MAX_SIGALGLEN];
41617bded2dbSJung-uk Kim } sig_cb_st;
41627bded2dbSJung-uk Kim 
41637bded2dbSJung-uk Kim static int sig_cb(const char *elem, int len, void *arg)
41647bded2dbSJung-uk Kim {
41657bded2dbSJung-uk Kim     sig_cb_st *sarg = arg;
41667bded2dbSJung-uk Kim     size_t i;
41677bded2dbSJung-uk Kim     char etmp[20], *p;
41687bded2dbSJung-uk Kim     int sig_alg, hash_alg;
41697bded2dbSJung-uk Kim     if (elem == NULL)
41707bded2dbSJung-uk Kim         return 0;
41717bded2dbSJung-uk Kim     if (sarg->sigalgcnt == MAX_SIGALGLEN)
41727bded2dbSJung-uk Kim         return 0;
41737bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
41747bded2dbSJung-uk Kim         return 0;
41757bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
41767bded2dbSJung-uk Kim     etmp[len] = 0;
41777bded2dbSJung-uk Kim     p = strchr(etmp, '+');
41787bded2dbSJung-uk Kim     if (!p)
41797bded2dbSJung-uk Kim         return 0;
41807bded2dbSJung-uk Kim     *p = 0;
41817bded2dbSJung-uk Kim     p++;
41827bded2dbSJung-uk Kim     if (!*p)
41837bded2dbSJung-uk Kim         return 0;
41847bded2dbSJung-uk Kim 
41857bded2dbSJung-uk Kim     if (!strcmp(etmp, "RSA"))
41867bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_RSA;
41877bded2dbSJung-uk Kim     else if (!strcmp(etmp, "DSA"))
41887bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_DSA;
41897bded2dbSJung-uk Kim     else if (!strcmp(etmp, "ECDSA"))
41907bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_EC;
41917bded2dbSJung-uk Kim     else
41927bded2dbSJung-uk Kim         return 0;
41937bded2dbSJung-uk Kim 
41947bded2dbSJung-uk Kim     hash_alg = OBJ_sn2nid(p);
41957bded2dbSJung-uk Kim     if (hash_alg == NID_undef)
41967bded2dbSJung-uk Kim         hash_alg = OBJ_ln2nid(p);
41977bded2dbSJung-uk Kim     if (hash_alg == NID_undef)
41987bded2dbSJung-uk Kim         return 0;
41997bded2dbSJung-uk Kim 
42007bded2dbSJung-uk Kim     for (i = 0; i < sarg->sigalgcnt; i += 2) {
42017bded2dbSJung-uk Kim         if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg)
42027bded2dbSJung-uk Kim             return 0;
42037bded2dbSJung-uk Kim     }
42047bded2dbSJung-uk Kim     sarg->sigalgs[sarg->sigalgcnt++] = hash_alg;
42057bded2dbSJung-uk Kim     sarg->sigalgs[sarg->sigalgcnt++] = sig_alg;
42067bded2dbSJung-uk Kim     return 1;
42077bded2dbSJung-uk Kim }
42087bded2dbSJung-uk Kim 
42097bded2dbSJung-uk Kim /*
42107bded2dbSJung-uk Kim  * Set suppored signature algorithms based on a colon separated list of the
42117bded2dbSJung-uk Kim  * form sig+hash e.g. RSA+SHA512:DSA+SHA512
42127bded2dbSJung-uk Kim  */
42137bded2dbSJung-uk Kim int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
42147bded2dbSJung-uk Kim {
42157bded2dbSJung-uk Kim     sig_cb_st sig;
42167bded2dbSJung-uk Kim     sig.sigalgcnt = 0;
42177bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
42187bded2dbSJung-uk Kim         return 0;
42197bded2dbSJung-uk Kim     if (c == NULL)
42207bded2dbSJung-uk Kim         return 1;
42217bded2dbSJung-uk Kim     return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
42227bded2dbSJung-uk Kim }
42237bded2dbSJung-uk Kim 
42247bded2dbSJung-uk Kim int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
42257bded2dbSJung-uk Kim                      int client)
42267bded2dbSJung-uk Kim {
42277bded2dbSJung-uk Kim     unsigned char *sigalgs, *sptr;
42287bded2dbSJung-uk Kim     int rhash, rsign;
42297bded2dbSJung-uk Kim     size_t i;
42307bded2dbSJung-uk Kim     if (salglen & 1)
42317bded2dbSJung-uk Kim         return 0;
42327bded2dbSJung-uk Kim     sigalgs = OPENSSL_malloc(salglen);
42337bded2dbSJung-uk Kim     if (sigalgs == NULL)
42347bded2dbSJung-uk Kim         return 0;
42357bded2dbSJung-uk Kim     for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
42367bded2dbSJung-uk Kim         rhash = tls12_find_id(*psig_nids++, tls12_md,
42377bded2dbSJung-uk Kim                               sizeof(tls12_md) / sizeof(tls12_lookup));
42387bded2dbSJung-uk Kim         rsign = tls12_find_id(*psig_nids++, tls12_sig,
42397bded2dbSJung-uk Kim                               sizeof(tls12_sig) / sizeof(tls12_lookup));
42407bded2dbSJung-uk Kim 
42417bded2dbSJung-uk Kim         if (rhash == -1 || rsign == -1)
42427bded2dbSJung-uk Kim             goto err;
42437bded2dbSJung-uk Kim         *sptr++ = rhash;
42447bded2dbSJung-uk Kim         *sptr++ = rsign;
42457bded2dbSJung-uk Kim     }
42467bded2dbSJung-uk Kim 
42477bded2dbSJung-uk Kim     if (client) {
42487bded2dbSJung-uk Kim         if (c->client_sigalgs)
42497bded2dbSJung-uk Kim             OPENSSL_free(c->client_sigalgs);
42507bded2dbSJung-uk Kim         c->client_sigalgs = sigalgs;
42517bded2dbSJung-uk Kim         c->client_sigalgslen = salglen;
42527bded2dbSJung-uk Kim     } else {
42537bded2dbSJung-uk Kim         if (c->conf_sigalgs)
42547bded2dbSJung-uk Kim             OPENSSL_free(c->conf_sigalgs);
42557bded2dbSJung-uk Kim         c->conf_sigalgs = sigalgs;
42567bded2dbSJung-uk Kim         c->conf_sigalgslen = salglen;
42577bded2dbSJung-uk Kim     }
42587bded2dbSJung-uk Kim 
42597bded2dbSJung-uk Kim     return 1;
42607bded2dbSJung-uk Kim 
42617bded2dbSJung-uk Kim  err:
42627bded2dbSJung-uk Kim     OPENSSL_free(sigalgs);
42637bded2dbSJung-uk Kim     return 0;
42647bded2dbSJung-uk Kim }
42657bded2dbSJung-uk Kim 
42667bded2dbSJung-uk Kim static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
42677bded2dbSJung-uk Kim {
42687bded2dbSJung-uk Kim     int sig_nid;
42697bded2dbSJung-uk Kim     size_t i;
42707bded2dbSJung-uk Kim     if (default_nid == -1)
42717bded2dbSJung-uk Kim         return 1;
42727bded2dbSJung-uk Kim     sig_nid = X509_get_signature_nid(x);
42737bded2dbSJung-uk Kim     if (default_nid)
42747bded2dbSJung-uk Kim         return sig_nid == default_nid ? 1 : 0;
42757bded2dbSJung-uk Kim     for (i = 0; i < c->shared_sigalgslen; i++)
42767bded2dbSJung-uk Kim         if (sig_nid == c->shared_sigalgs[i].signandhash_nid)
42777bded2dbSJung-uk Kim             return 1;
42787bded2dbSJung-uk Kim     return 0;
42797bded2dbSJung-uk Kim }
42807bded2dbSJung-uk Kim 
42817bded2dbSJung-uk Kim /* Check to see if a certificate issuer name matches list of CA names */
42827bded2dbSJung-uk Kim static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
42837bded2dbSJung-uk Kim {
42847bded2dbSJung-uk Kim     X509_NAME *nm;
42857bded2dbSJung-uk Kim     int i;
42867bded2dbSJung-uk Kim     nm = X509_get_issuer_name(x);
42877bded2dbSJung-uk Kim     for (i = 0; i < sk_X509_NAME_num(names); i++) {
42887bded2dbSJung-uk Kim         if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
42897bded2dbSJung-uk Kim             return 1;
42907bded2dbSJung-uk Kim     }
42917bded2dbSJung-uk Kim     return 0;
42927bded2dbSJung-uk Kim }
42937bded2dbSJung-uk Kim 
42947bded2dbSJung-uk Kim /*
42957bded2dbSJung-uk Kim  * Check certificate chain is consistent with TLS extensions and is usable by
42967bded2dbSJung-uk Kim  * server. This servers two purposes: it allows users to check chains before
42977bded2dbSJung-uk Kim  * passing them to the server and it allows the server to check chains before
42987bded2dbSJung-uk Kim  * attempting to use them.
42997bded2dbSJung-uk Kim  */
43007bded2dbSJung-uk Kim 
43017bded2dbSJung-uk Kim /* Flags which need to be set for a certificate when stict mode not set */
43027bded2dbSJung-uk Kim 
43037bded2dbSJung-uk Kim # define CERT_PKEY_VALID_FLAGS \
43047bded2dbSJung-uk Kim         (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
43057bded2dbSJung-uk Kim /* Strict mode flags */
43067bded2dbSJung-uk Kim # define CERT_PKEY_STRICT_FLAGS \
43077bded2dbSJung-uk Kim          (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
43087bded2dbSJung-uk Kim          | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
43097bded2dbSJung-uk Kim 
43107bded2dbSJung-uk Kim int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
43117bded2dbSJung-uk Kim                      int idx)
43127bded2dbSJung-uk Kim {
43137bded2dbSJung-uk Kim     int i;
43147bded2dbSJung-uk Kim     int rv = 0;
43157bded2dbSJung-uk Kim     int check_flags = 0, strict_mode;
43167bded2dbSJung-uk Kim     CERT_PKEY *cpk = NULL;
43177bded2dbSJung-uk Kim     CERT *c = s->cert;
43187bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
43197bded2dbSJung-uk Kim     /* idx == -1 means checking server chains */
43207bded2dbSJung-uk Kim     if (idx != -1) {
43217bded2dbSJung-uk Kim         /* idx == -2 means checking client certificate chains */
43227bded2dbSJung-uk Kim         if (idx == -2) {
43237bded2dbSJung-uk Kim             cpk = c->key;
43247bded2dbSJung-uk Kim             idx = cpk - c->pkeys;
43257bded2dbSJung-uk Kim         } else
43267bded2dbSJung-uk Kim             cpk = c->pkeys + idx;
43277bded2dbSJung-uk Kim         x = cpk->x509;
43287bded2dbSJung-uk Kim         pk = cpk->privatekey;
43297bded2dbSJung-uk Kim         chain = cpk->chain;
43307bded2dbSJung-uk Kim         strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
43317bded2dbSJung-uk Kim         /* If no cert or key, forget it */
43327bded2dbSJung-uk Kim         if (!x || !pk)
43337bded2dbSJung-uk Kim             goto end;
43347bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
43357bded2dbSJung-uk Kim         /* Allow any certificate to pass test */
43367bded2dbSJung-uk Kim         if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
43377bded2dbSJung-uk Kim             rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN |
43387bded2dbSJung-uk Kim                 CERT_PKEY_VALID | CERT_PKEY_SIGN;
43397bded2dbSJung-uk Kim             cpk->valid_flags = rv;
43407bded2dbSJung-uk Kim             return rv;
43417bded2dbSJung-uk Kim         }
43427bded2dbSJung-uk Kim # endif
43437bded2dbSJung-uk Kim     } else {
43447bded2dbSJung-uk Kim         if (!x || !pk)
43457bded2dbSJung-uk Kim             return 0;
43467bded2dbSJung-uk Kim         idx = ssl_cert_type(x, pk);
43477bded2dbSJung-uk Kim         if (idx == -1)
43487bded2dbSJung-uk Kim             return 0;
43497bded2dbSJung-uk Kim         cpk = c->pkeys + idx;
43507bded2dbSJung-uk Kim         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
43517bded2dbSJung-uk Kim             check_flags = CERT_PKEY_STRICT_FLAGS;
43527bded2dbSJung-uk Kim         else
43537bded2dbSJung-uk Kim             check_flags = CERT_PKEY_VALID_FLAGS;
43547bded2dbSJung-uk Kim         strict_mode = 1;
43557bded2dbSJung-uk Kim     }
43567bded2dbSJung-uk Kim 
43577bded2dbSJung-uk Kim     if (suiteb_flags) {
43587bded2dbSJung-uk Kim         int ok;
43597bded2dbSJung-uk Kim         if (check_flags)
43607bded2dbSJung-uk Kim             check_flags |= CERT_PKEY_SUITEB;
43617bded2dbSJung-uk Kim         ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
43627bded2dbSJung-uk Kim         if (ok == X509_V_OK)
43637bded2dbSJung-uk Kim             rv |= CERT_PKEY_SUITEB;
43647bded2dbSJung-uk Kim         else if (!check_flags)
43657bded2dbSJung-uk Kim             goto end;
43667bded2dbSJung-uk Kim     }
43677bded2dbSJung-uk Kim 
43687bded2dbSJung-uk Kim     /*
43697bded2dbSJung-uk Kim      * Check all signature algorithms are consistent with signature
43707bded2dbSJung-uk Kim      * algorithms extension if TLS 1.2 or later and strict mode.
43717bded2dbSJung-uk Kim      */
43727bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
43737bded2dbSJung-uk Kim         int default_nid;
43747bded2dbSJung-uk Kim         unsigned char rsign = 0;
43757bded2dbSJung-uk Kim         if (c->peer_sigalgs)
43767bded2dbSJung-uk Kim             default_nid = 0;
43777bded2dbSJung-uk Kim         /* If no sigalgs extension use defaults from RFC5246 */
43787bded2dbSJung-uk Kim         else {
43797bded2dbSJung-uk Kim             switch (idx) {
43807bded2dbSJung-uk Kim             case SSL_PKEY_RSA_ENC:
43817bded2dbSJung-uk Kim             case SSL_PKEY_RSA_SIGN:
43827bded2dbSJung-uk Kim             case SSL_PKEY_DH_RSA:
43837bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_rsa;
43847bded2dbSJung-uk Kim                 default_nid = NID_sha1WithRSAEncryption;
43857bded2dbSJung-uk Kim                 break;
43867bded2dbSJung-uk Kim 
43877bded2dbSJung-uk Kim             case SSL_PKEY_DSA_SIGN:
43887bded2dbSJung-uk Kim             case SSL_PKEY_DH_DSA:
43897bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_dsa;
43907bded2dbSJung-uk Kim                 default_nid = NID_dsaWithSHA1;
43917bded2dbSJung-uk Kim                 break;
43927bded2dbSJung-uk Kim 
43937bded2dbSJung-uk Kim             case SSL_PKEY_ECC:
43947bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_ecdsa;
43957bded2dbSJung-uk Kim                 default_nid = NID_ecdsa_with_SHA1;
43967bded2dbSJung-uk Kim                 break;
43977bded2dbSJung-uk Kim 
43987bded2dbSJung-uk Kim             default:
43997bded2dbSJung-uk Kim                 default_nid = -1;
44007bded2dbSJung-uk Kim                 break;
44017bded2dbSJung-uk Kim             }
44027bded2dbSJung-uk Kim         }
44037bded2dbSJung-uk Kim         /*
44047bded2dbSJung-uk Kim          * If peer sent no signature algorithms extension and we have set
44057bded2dbSJung-uk Kim          * preferred signature algorithms check we support sha1.
44067bded2dbSJung-uk Kim          */
44077bded2dbSJung-uk Kim         if (default_nid > 0 && c->conf_sigalgs) {
44087bded2dbSJung-uk Kim             size_t j;
44097bded2dbSJung-uk Kim             const unsigned char *p = c->conf_sigalgs;
44107bded2dbSJung-uk Kim             for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) {
44117bded2dbSJung-uk Kim                 if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign)
44127bded2dbSJung-uk Kim                     break;
44137bded2dbSJung-uk Kim             }
44147bded2dbSJung-uk Kim             if (j == c->conf_sigalgslen) {
44157bded2dbSJung-uk Kim                 if (check_flags)
44167bded2dbSJung-uk Kim                     goto skip_sigs;
44177bded2dbSJung-uk Kim                 else
44187bded2dbSJung-uk Kim                     goto end;
44197bded2dbSJung-uk Kim             }
44207bded2dbSJung-uk Kim         }
44217bded2dbSJung-uk Kim         /* Check signature algorithm of each cert in chain */
44227bded2dbSJung-uk Kim         if (!tls1_check_sig_alg(c, x, default_nid)) {
44237bded2dbSJung-uk Kim             if (!check_flags)
44247bded2dbSJung-uk Kim                 goto end;
44257bded2dbSJung-uk Kim         } else
44267bded2dbSJung-uk Kim             rv |= CERT_PKEY_EE_SIGNATURE;
44277bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_SIGNATURE;
44287bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
44297bded2dbSJung-uk Kim             if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) {
44307bded2dbSJung-uk Kim                 if (check_flags) {
44317bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_SIGNATURE;
44327bded2dbSJung-uk Kim                     break;
44337bded2dbSJung-uk Kim                 } else
44347bded2dbSJung-uk Kim                     goto end;
44357bded2dbSJung-uk Kim             }
44367bded2dbSJung-uk Kim         }
44377bded2dbSJung-uk Kim     }
44387bded2dbSJung-uk Kim     /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
44397bded2dbSJung-uk Kim     else if (check_flags)
44407bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
44417bded2dbSJung-uk Kim  skip_sigs:
44427bded2dbSJung-uk Kim     /* Check cert parameters are consistent */
44437bded2dbSJung-uk Kim     if (tls1_check_cert_param(s, x, check_flags ? 1 : 2))
44447bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_PARAM;
44457bded2dbSJung-uk Kim     else if (!check_flags)
44467bded2dbSJung-uk Kim         goto end;
44477bded2dbSJung-uk Kim     if (!s->server)
44487bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
44497bded2dbSJung-uk Kim     /* In strict mode check rest of chain too */
44507bded2dbSJung-uk Kim     else if (strict_mode) {
44517bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
44527bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
44537bded2dbSJung-uk Kim             X509 *ca = sk_X509_value(chain, i);
44547bded2dbSJung-uk Kim             if (!tls1_check_cert_param(s, ca, 0)) {
44557bded2dbSJung-uk Kim                 if (check_flags) {
44567bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_PARAM;
44577bded2dbSJung-uk Kim                     break;
44587bded2dbSJung-uk Kim                 } else
44597bded2dbSJung-uk Kim                     goto end;
44607bded2dbSJung-uk Kim             }
44617bded2dbSJung-uk Kim         }
44627bded2dbSJung-uk Kim     }
44637bded2dbSJung-uk Kim     if (!s->server && strict_mode) {
44647bded2dbSJung-uk Kim         STACK_OF(X509_NAME) *ca_dn;
44657bded2dbSJung-uk Kim         int check_type = 0;
44667bded2dbSJung-uk Kim         switch (pk->type) {
44677bded2dbSJung-uk Kim         case EVP_PKEY_RSA:
44687bded2dbSJung-uk Kim             check_type = TLS_CT_RSA_SIGN;
44697bded2dbSJung-uk Kim             break;
44707bded2dbSJung-uk Kim         case EVP_PKEY_DSA:
44717bded2dbSJung-uk Kim             check_type = TLS_CT_DSS_SIGN;
44727bded2dbSJung-uk Kim             break;
44737bded2dbSJung-uk Kim         case EVP_PKEY_EC:
44747bded2dbSJung-uk Kim             check_type = TLS_CT_ECDSA_SIGN;
44757bded2dbSJung-uk Kim             break;
44767bded2dbSJung-uk Kim         case EVP_PKEY_DH:
44777bded2dbSJung-uk Kim         case EVP_PKEY_DHX:
44787bded2dbSJung-uk Kim             {
44797bded2dbSJung-uk Kim                 int cert_type = X509_certificate_type(x, pk);
44807bded2dbSJung-uk Kim                 if (cert_type & EVP_PKS_RSA)
44817bded2dbSJung-uk Kim                     check_type = TLS_CT_RSA_FIXED_DH;
44827bded2dbSJung-uk Kim                 if (cert_type & EVP_PKS_DSA)
44837bded2dbSJung-uk Kim                     check_type = TLS_CT_DSS_FIXED_DH;
44847bded2dbSJung-uk Kim             }
44857bded2dbSJung-uk Kim         }
44867bded2dbSJung-uk Kim         if (check_type) {
44877bded2dbSJung-uk Kim             const unsigned char *ctypes;
44887bded2dbSJung-uk Kim             int ctypelen;
44897bded2dbSJung-uk Kim             if (c->ctypes) {
44907bded2dbSJung-uk Kim                 ctypes = c->ctypes;
44917bded2dbSJung-uk Kim                 ctypelen = (int)c->ctype_num;
44927bded2dbSJung-uk Kim             } else {
44937bded2dbSJung-uk Kim                 ctypes = (unsigned char *)s->s3->tmp.ctype;
44947bded2dbSJung-uk Kim                 ctypelen = s->s3->tmp.ctype_num;
44957bded2dbSJung-uk Kim             }
44967bded2dbSJung-uk Kim             for (i = 0; i < ctypelen; i++) {
44977bded2dbSJung-uk Kim                 if (ctypes[i] == check_type) {
44987bded2dbSJung-uk Kim                     rv |= CERT_PKEY_CERT_TYPE;
44997bded2dbSJung-uk Kim                     break;
45007bded2dbSJung-uk Kim                 }
45017bded2dbSJung-uk Kim             }
45027bded2dbSJung-uk Kim             if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
45037bded2dbSJung-uk Kim                 goto end;
45047bded2dbSJung-uk Kim         } else
45057bded2dbSJung-uk Kim             rv |= CERT_PKEY_CERT_TYPE;
45067bded2dbSJung-uk Kim 
45077bded2dbSJung-uk Kim         ca_dn = s->s3->tmp.ca_names;
45087bded2dbSJung-uk Kim 
45097bded2dbSJung-uk Kim         if (!sk_X509_NAME_num(ca_dn))
45107bded2dbSJung-uk Kim             rv |= CERT_PKEY_ISSUER_NAME;
45117bded2dbSJung-uk Kim 
45127bded2dbSJung-uk Kim         if (!(rv & CERT_PKEY_ISSUER_NAME)) {
45137bded2dbSJung-uk Kim             if (ssl_check_ca_name(ca_dn, x))
45147bded2dbSJung-uk Kim                 rv |= CERT_PKEY_ISSUER_NAME;
45157bded2dbSJung-uk Kim         }
45167bded2dbSJung-uk Kim         if (!(rv & CERT_PKEY_ISSUER_NAME)) {
45177bded2dbSJung-uk Kim             for (i = 0; i < sk_X509_num(chain); i++) {
45187bded2dbSJung-uk Kim                 X509 *xtmp = sk_X509_value(chain, i);
45197bded2dbSJung-uk Kim                 if (ssl_check_ca_name(ca_dn, xtmp)) {
45207bded2dbSJung-uk Kim                     rv |= CERT_PKEY_ISSUER_NAME;
45217bded2dbSJung-uk Kim                     break;
45227bded2dbSJung-uk Kim                 }
45237bded2dbSJung-uk Kim             }
45247bded2dbSJung-uk Kim         }
45257bded2dbSJung-uk Kim         if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
45267bded2dbSJung-uk Kim             goto end;
45277bded2dbSJung-uk Kim     } else
45287bded2dbSJung-uk Kim         rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE;
45297bded2dbSJung-uk Kim 
45307bded2dbSJung-uk Kim     if (!check_flags || (rv & check_flags) == check_flags)
45317bded2dbSJung-uk Kim         rv |= CERT_PKEY_VALID;
45327bded2dbSJung-uk Kim 
45337bded2dbSJung-uk Kim  end:
45347bded2dbSJung-uk Kim 
45357bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION) {
45367bded2dbSJung-uk Kim         if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN)
45377bded2dbSJung-uk Kim             rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
45387bded2dbSJung-uk Kim         else if (cpk->digest)
45397bded2dbSJung-uk Kim             rv |= CERT_PKEY_SIGN;
45407bded2dbSJung-uk Kim     } else
45417bded2dbSJung-uk Kim         rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
45427bded2dbSJung-uk Kim 
45437bded2dbSJung-uk Kim     /*
45447bded2dbSJung-uk Kim      * When checking a CERT_PKEY structure all flags are irrelevant if the
45457bded2dbSJung-uk Kim      * chain is invalid.
45467bded2dbSJung-uk Kim      */
45477bded2dbSJung-uk Kim     if (!check_flags) {
45487bded2dbSJung-uk Kim         if (rv & CERT_PKEY_VALID)
45497bded2dbSJung-uk Kim             cpk->valid_flags = rv;
45507bded2dbSJung-uk Kim         else {
45517bded2dbSJung-uk Kim             /* Preserve explicit sign flag, clear rest */
45527bded2dbSJung-uk Kim             cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
45537bded2dbSJung-uk Kim             return 0;
45547bded2dbSJung-uk Kim         }
45557bded2dbSJung-uk Kim     }
45567bded2dbSJung-uk Kim     return rv;
45577bded2dbSJung-uk Kim }
45587bded2dbSJung-uk Kim 
45597bded2dbSJung-uk Kim /* Set validity of certificates in an SSL structure */
45607bded2dbSJung-uk Kim void tls1_set_cert_validity(SSL *s)
45617bded2dbSJung-uk Kim {
45627bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
45637bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
45647bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
45657bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA);
45667bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA);
45677bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
45687bded2dbSJung-uk Kim }
45697bded2dbSJung-uk Kim 
45707bded2dbSJung-uk Kim /* User level utiity function to check a chain is suitable */
45717bded2dbSJung-uk Kim int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
45727bded2dbSJung-uk Kim {
45737bded2dbSJung-uk Kim     return tls1_check_chain(s, x, pk, chain, -1);
45747bded2dbSJung-uk Kim }
45757bded2dbSJung-uk Kim 
45767bded2dbSJung-uk Kim #endif
4577