xref: /freebsd/crypto/openssl/ssl/t1_lib.c (revision aeb5019c481d34f2422c200e4751e24ec940fe3f)
174664626SKris Kennaway /* ssl/t1_lib.c */
274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
374664626SKris Kennaway  * All rights reserved.
474664626SKris Kennaway  *
574664626SKris Kennaway  * This package is an SSL implementation written
674664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
774664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
874664626SKris Kennaway  *
974664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1074664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1174664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1274664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1374664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1474664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1574664626SKris Kennaway  *
1674664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1774664626SKris Kennaway  * the code are not to be removed.
1874664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
1974664626SKris Kennaway  * as the author of the parts of the library used.
2074664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2174664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2274664626SKris Kennaway  *
2374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2474664626SKris Kennaway  * modification, are permitted provided that the following conditions
2574664626SKris Kennaway  * are met:
2674664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2774664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
2874664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3074664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3174664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3274664626SKris Kennaway  *    must display the following acknowledgement:
3374664626SKris Kennaway  *    "This product includes cryptographic software written by
3474664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3574664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3674664626SKris Kennaway  *    being used are not cryptographic related :-).
3774664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
3874664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
3974664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4074664626SKris Kennaway  *
4174664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4274664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4374664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4474664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4574664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4674664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4774664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4874664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4974664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5074664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5174664626SKris Kennaway  * SUCH DAMAGE.
5274664626SKris Kennaway  *
5374664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5474664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5574664626SKris Kennaway  * copied and put under another distribution licence
5674664626SKris Kennaway  * [including the GNU Public Licence.]
5774664626SKris Kennaway  */
581f13597dSJung-uk Kim /* ====================================================================
591f13597dSJung-uk Kim  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
601f13597dSJung-uk Kim  *
611f13597dSJung-uk Kim  * Redistribution and use in source and binary forms, with or without
621f13597dSJung-uk Kim  * modification, are permitted provided that the following conditions
631f13597dSJung-uk Kim  * are met:
641f13597dSJung-uk Kim  *
651f13597dSJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
661f13597dSJung-uk Kim  *    notice, this list of conditions and the following disclaimer.
671f13597dSJung-uk Kim  *
681f13597dSJung-uk Kim  * 2. Redistributions in binary form must reproduce the above copyright
691f13597dSJung-uk Kim  *    notice, this list of conditions and the following disclaimer in
701f13597dSJung-uk Kim  *    the documentation and/or other materials provided with the
711f13597dSJung-uk Kim  *    distribution.
721f13597dSJung-uk Kim  *
731f13597dSJung-uk Kim  * 3. All advertising materials mentioning features or use of this
741f13597dSJung-uk Kim  *    software must display the following acknowledgment:
751f13597dSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
761f13597dSJung-uk Kim  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
771f13597dSJung-uk Kim  *
781f13597dSJung-uk Kim  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
791f13597dSJung-uk Kim  *    endorse or promote products derived from this software without
801f13597dSJung-uk Kim  *    prior written permission. For written permission, please contact
811f13597dSJung-uk Kim  *    openssl-core@openssl.org.
821f13597dSJung-uk Kim  *
831f13597dSJung-uk Kim  * 5. Products derived from this software may not be called "OpenSSL"
841f13597dSJung-uk Kim  *    nor may "OpenSSL" appear in their names without prior written
851f13597dSJung-uk Kim  *    permission of the OpenSSL Project.
861f13597dSJung-uk Kim  *
871f13597dSJung-uk Kim  * 6. Redistributions of any form whatsoever must retain the following
881f13597dSJung-uk Kim  *    acknowledgment:
891f13597dSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
901f13597dSJung-uk Kim  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
911f13597dSJung-uk Kim  *
921f13597dSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
931f13597dSJung-uk Kim  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
941f13597dSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
951f13597dSJung-uk Kim  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
961f13597dSJung-uk Kim  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
971f13597dSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
981f13597dSJung-uk Kim  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
991f13597dSJung-uk Kim  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1001f13597dSJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1011f13597dSJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1021f13597dSJung-uk Kim  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1031f13597dSJung-uk Kim  * OF THE POSSIBILITY OF SUCH DAMAGE.
1041f13597dSJung-uk Kim  * ====================================================================
1051f13597dSJung-uk Kim  *
1061f13597dSJung-uk Kim  * This product includes cryptographic software written by Eric Young
1071f13597dSJung-uk Kim  * (eay@cryptsoft.com).  This product includes software written by Tim
1081f13597dSJung-uk Kim  * Hudson (tjh@cryptsoft.com).
1091f13597dSJung-uk Kim  *
1101f13597dSJung-uk Kim  */
11174664626SKris Kennaway 
11274664626SKris Kennaway #include <stdio.h>
11374664626SKris Kennaway #include <openssl/objects.h>
114db522d3aSSimon L. B. Nielsen #include <openssl/evp.h>
115db522d3aSSimon L. B. Nielsen #include <openssl/hmac.h>
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 
1353b4e3dcbSSimon L. B. Nielsen SSL3_ENC_METHOD TLSv1_enc_data = {
13674664626SKris Kennaway     tls1_enc,
13774664626SKris Kennaway     tls1_mac,
13874664626SKris Kennaway     tls1_setup_key_block,
13974664626SKris Kennaway     tls1_generate_master_secret,
14074664626SKris Kennaway     tls1_change_cipher_state,
14174664626SKris Kennaway     tls1_final_finish_mac,
14274664626SKris Kennaway     TLS1_FINISH_MAC_LENGTH,
14374664626SKris Kennaway     tls1_cert_verify_mac,
14474664626SKris Kennaway     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
14574664626SKris Kennaway     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
14674664626SKris Kennaway     tls1_alert_code,
1471f13597dSJung-uk Kim     tls1_export_keying_material,
1487bded2dbSJung-uk Kim     0,
1497bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
1507bded2dbSJung-uk Kim     ssl3_set_handshake_header,
1517bded2dbSJung-uk Kim     ssl3_handshake_write
1527bded2dbSJung-uk Kim };
1537bded2dbSJung-uk Kim 
1547bded2dbSJung-uk Kim SSL3_ENC_METHOD TLSv1_1_enc_data = {
1557bded2dbSJung-uk Kim     tls1_enc,
1567bded2dbSJung-uk Kim     tls1_mac,
1577bded2dbSJung-uk Kim     tls1_setup_key_block,
1587bded2dbSJung-uk Kim     tls1_generate_master_secret,
1597bded2dbSJung-uk Kim     tls1_change_cipher_state,
1607bded2dbSJung-uk Kim     tls1_final_finish_mac,
1617bded2dbSJung-uk Kim     TLS1_FINISH_MAC_LENGTH,
1627bded2dbSJung-uk Kim     tls1_cert_verify_mac,
1637bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
1647bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
1657bded2dbSJung-uk Kim     tls1_alert_code,
1667bded2dbSJung-uk Kim     tls1_export_keying_material,
1677bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV,
1687bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
1697bded2dbSJung-uk Kim     ssl3_set_handshake_header,
1707bded2dbSJung-uk Kim     ssl3_handshake_write
1717bded2dbSJung-uk Kim };
1727bded2dbSJung-uk Kim 
1737bded2dbSJung-uk Kim SSL3_ENC_METHOD TLSv1_2_enc_data = {
1747bded2dbSJung-uk Kim     tls1_enc,
1757bded2dbSJung-uk Kim     tls1_mac,
1767bded2dbSJung-uk Kim     tls1_setup_key_block,
1777bded2dbSJung-uk Kim     tls1_generate_master_secret,
1787bded2dbSJung-uk Kim     tls1_change_cipher_state,
1797bded2dbSJung-uk Kim     tls1_final_finish_mac,
1807bded2dbSJung-uk Kim     TLS1_FINISH_MAC_LENGTH,
1817bded2dbSJung-uk Kim     tls1_cert_verify_mac,
1827bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
1837bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
1847bded2dbSJung-uk Kim     tls1_alert_code,
1857bded2dbSJung-uk Kim     tls1_export_keying_material,
1867bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
1877bded2dbSJung-uk Kim         | SSL_ENC_FLAG_TLS1_2_CIPHERS,
1887bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
1897bded2dbSJung-uk Kim     ssl3_set_handshake_header,
1907bded2dbSJung-uk Kim     ssl3_handshake_write
19174664626SKris Kennaway };
19274664626SKris Kennaway 
1933b4e3dcbSSimon L. B. Nielsen long tls1_default_timeout(void)
19474664626SKris Kennaway {
1956f9291ceSJung-uk Kim     /*
1966f9291ceSJung-uk Kim      * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for
1976f9291ceSJung-uk Kim      * http, the cache would over fill
1986f9291ceSJung-uk Kim      */
19974664626SKris Kennaway     return (60 * 60 * 2);
20074664626SKris Kennaway }
20174664626SKris Kennaway 
20274664626SKris Kennaway int tls1_new(SSL *s)
20374664626SKris Kennaway {
2046f9291ceSJung-uk Kim     if (!ssl3_new(s))
2056f9291ceSJung-uk Kim         return (0);
20674664626SKris Kennaway     s->method->ssl_clear(s);
20774664626SKris Kennaway     return (1);
20874664626SKris Kennaway }
20974664626SKris Kennaway 
21074664626SKris Kennaway void tls1_free(SSL *s)
21174664626SKris Kennaway {
2121f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
2136f9291ceSJung-uk Kim     if (s->tlsext_session_ticket) {
2141f13597dSJung-uk Kim         OPENSSL_free(s->tlsext_session_ticket);
2151f13597dSJung-uk Kim     }
2161f13597dSJung-uk Kim #endif                          /* OPENSSL_NO_TLSEXT */
21774664626SKris Kennaway     ssl3_free(s);
21874664626SKris Kennaway }
21974664626SKris Kennaway 
22074664626SKris Kennaway void tls1_clear(SSL *s)
22174664626SKris Kennaway {
22274664626SKris Kennaway     ssl3_clear(s);
2231f13597dSJung-uk Kim     s->version = s->method->version;
22474664626SKris Kennaway }
22574664626SKris Kennaway 
2261f13597dSJung-uk Kim #ifndef OPENSSL_NO_EC
2271f13597dSJung-uk Kim 
2286f9291ceSJung-uk Kim static int nid_list[] = {
2291f13597dSJung-uk Kim     NID_sect163k1,              /* sect163k1 (1) */
2301f13597dSJung-uk Kim     NID_sect163r1,              /* sect163r1 (2) */
2311f13597dSJung-uk Kim     NID_sect163r2,              /* sect163r2 (3) */
2321f13597dSJung-uk Kim     NID_sect193r1,              /* sect193r1 (4) */
2331f13597dSJung-uk Kim     NID_sect193r2,              /* sect193r2 (5) */
2341f13597dSJung-uk Kim     NID_sect233k1,              /* sect233k1 (6) */
2351f13597dSJung-uk Kim     NID_sect233r1,              /* sect233r1 (7) */
2361f13597dSJung-uk Kim     NID_sect239k1,              /* sect239k1 (8) */
2371f13597dSJung-uk Kim     NID_sect283k1,              /* sect283k1 (9) */
2381f13597dSJung-uk Kim     NID_sect283r1,              /* sect283r1 (10) */
2391f13597dSJung-uk Kim     NID_sect409k1,              /* sect409k1 (11) */
2401f13597dSJung-uk Kim     NID_sect409r1,              /* sect409r1 (12) */
2411f13597dSJung-uk Kim     NID_sect571k1,              /* sect571k1 (13) */
2421f13597dSJung-uk Kim     NID_sect571r1,              /* sect571r1 (14) */
2431f13597dSJung-uk Kim     NID_secp160k1,              /* secp160k1 (15) */
2441f13597dSJung-uk Kim     NID_secp160r1,              /* secp160r1 (16) */
2451f13597dSJung-uk Kim     NID_secp160r2,              /* secp160r2 (17) */
2461f13597dSJung-uk Kim     NID_secp192k1,              /* secp192k1 (18) */
2471f13597dSJung-uk Kim     NID_X9_62_prime192v1,       /* secp192r1 (19) */
2481f13597dSJung-uk Kim     NID_secp224k1,              /* secp224k1 (20) */
2491f13597dSJung-uk Kim     NID_secp224r1,              /* secp224r1 (21) */
2501f13597dSJung-uk Kim     NID_secp256k1,              /* secp256k1 (22) */
2511f13597dSJung-uk Kim     NID_X9_62_prime256v1,       /* secp256r1 (23) */
2521f13597dSJung-uk Kim     NID_secp384r1,              /* secp384r1 (24) */
2537bded2dbSJung-uk Kim     NID_secp521r1,              /* secp521r1 (25) */
2547bded2dbSJung-uk Kim     NID_brainpoolP256r1,        /* brainpoolP256r1 (26) */
2557bded2dbSJung-uk Kim     NID_brainpoolP384r1,        /* brainpoolP384r1 (27) */
2567bded2dbSJung-uk Kim     NID_brainpoolP512r1         /* brainpool512r1 (28) */
2571f13597dSJung-uk Kim };
2581f13597dSJung-uk Kim 
2597bded2dbSJung-uk Kim static const unsigned char ecformats_default[] = {
2607bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_uncompressed,
2617bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
2627bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
2631f13597dSJung-uk Kim };
2641f13597dSJung-uk Kim 
2657bded2dbSJung-uk Kim /* The client's default curves / the server's 'auto' curves. */
2667bded2dbSJung-uk Kim static const unsigned char eccurves_auto[] = {
2677bded2dbSJung-uk Kim     /* Prefer P-256 which has the fastest and most secure implementations. */
2687bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
2697bded2dbSJung-uk Kim     /* Other >= 256-bit prime curves. */
2707bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
2717bded2dbSJung-uk Kim     0, 28,                      /* brainpool512r1 (28) */
2727bded2dbSJung-uk Kim     0, 27,                      /* brainpoolP384r1 (27) */
2737bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
2747bded2dbSJung-uk Kim     0, 26,                      /* brainpoolP256r1 (26) */
2757bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
2767bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
2777bded2dbSJung-uk Kim     /* >= 256-bit binary curves. */
2787bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
2797bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
2807bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
2817bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
2827bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
2837bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
2847bded2dbSJung-uk Kim # endif
2857bded2dbSJung-uk Kim };
2867bded2dbSJung-uk Kim 
2877bded2dbSJung-uk Kim static const unsigned char eccurves_all[] = {
2887bded2dbSJung-uk Kim     /* Prefer P-256 which has the fastest and most secure implementations. */
2897bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
2907bded2dbSJung-uk Kim     /* Other >= 256-bit prime curves. */
2917bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
2927bded2dbSJung-uk Kim     0, 28,                      /* brainpool512r1 (28) */
2937bded2dbSJung-uk Kim     0, 27,                      /* brainpoolP384r1 (27) */
2947bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
2957bded2dbSJung-uk Kim     0, 26,                      /* brainpoolP256r1 (26) */
2967bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
2977bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
2987bded2dbSJung-uk Kim     /* >= 256-bit binary curves. */
2997bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
3007bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
3017bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
3027bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
3037bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
3047bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
3057bded2dbSJung-uk Kim # endif
3067bded2dbSJung-uk Kim     /*
3077bded2dbSJung-uk Kim      * Remaining curves disabled by default but still permitted if set
3087bded2dbSJung-uk Kim      * via an explicit callback or parameters.
3097bded2dbSJung-uk Kim      */
3107bded2dbSJung-uk Kim     0, 20,                      /* secp224k1 (20) */
3117bded2dbSJung-uk Kim     0, 21,                      /* secp224r1 (21) */
3127bded2dbSJung-uk Kim     0, 18,                      /* secp192k1 (18) */
3137bded2dbSJung-uk Kim     0, 19,                      /* secp192r1 (19) */
3147bded2dbSJung-uk Kim     0, 15,                      /* secp160k1 (15) */
3157bded2dbSJung-uk Kim     0, 16,                      /* secp160r1 (16) */
3167bded2dbSJung-uk Kim     0, 17,                      /* secp160r2 (17) */
3177bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
3187bded2dbSJung-uk Kim     0, 8,                       /* sect239k1 (8) */
3197bded2dbSJung-uk Kim     0, 6,                       /* sect233k1 (6) */
3207bded2dbSJung-uk Kim     0, 7,                       /* sect233r1 (7) */
3217bded2dbSJung-uk Kim     0, 4,                       /* sect193r1 (4) */
3227bded2dbSJung-uk Kim     0, 5,                       /* sect193r2 (5) */
3237bded2dbSJung-uk Kim     0, 1,                       /* sect163k1 (1) */
3247bded2dbSJung-uk Kim     0, 2,                       /* sect163r1 (2) */
3257bded2dbSJung-uk Kim     0, 3,                       /* sect163r2 (3) */
3267bded2dbSJung-uk Kim # endif
3277bded2dbSJung-uk Kim };
3287bded2dbSJung-uk Kim 
3297bded2dbSJung-uk Kim static const unsigned char suiteb_curves[] = {
3307bded2dbSJung-uk Kim     0, TLSEXT_curve_P_256,
3317bded2dbSJung-uk Kim     0, TLSEXT_curve_P_384
3327bded2dbSJung-uk Kim };
3337bded2dbSJung-uk Kim 
3347bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
3357bded2dbSJung-uk Kim /* Brainpool not allowed in FIPS mode */
3367bded2dbSJung-uk Kim static const unsigned char fips_curves_default[] = {
3377bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3387bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
3397bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
3407bded2dbSJung-uk Kim #  endif
3417bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
3427bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3437bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
3447bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
3457bded2dbSJung-uk Kim #  endif
3467bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
3477bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3487bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
3497bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
3507bded2dbSJung-uk Kim #  endif
3517bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
3527bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
3537bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3547bded2dbSJung-uk Kim     0, 8,                       /* sect239k1 (8) */
3557bded2dbSJung-uk Kim     0, 6,                       /* sect233k1 (6) */
3567bded2dbSJung-uk Kim     0, 7,                       /* sect233r1 (7) */
3577bded2dbSJung-uk Kim #  endif
3587bded2dbSJung-uk Kim     0, 20,                      /* secp224k1 (20) */
3597bded2dbSJung-uk Kim     0, 21,                      /* secp224r1 (21) */
3607bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3617bded2dbSJung-uk Kim     0, 4,                       /* sect193r1 (4) */
3627bded2dbSJung-uk Kim     0, 5,                       /* sect193r2 (5) */
3637bded2dbSJung-uk Kim #  endif
3647bded2dbSJung-uk Kim     0, 18,                      /* secp192k1 (18) */
3657bded2dbSJung-uk Kim     0, 19,                      /* secp192r1 (19) */
3667bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
3677bded2dbSJung-uk Kim     0, 1,                       /* sect163k1 (1) */
3687bded2dbSJung-uk Kim     0, 2,                       /* sect163r1 (2) */
3697bded2dbSJung-uk Kim     0, 3,                       /* sect163r2 (3) */
3707bded2dbSJung-uk Kim #  endif
3717bded2dbSJung-uk Kim     0, 15,                      /* secp160k1 (15) */
3727bded2dbSJung-uk Kim     0, 16,                      /* secp160r1 (16) */
3737bded2dbSJung-uk Kim     0, 17,                      /* secp160r2 (17) */
3747bded2dbSJung-uk Kim };
3757bded2dbSJung-uk Kim # endif
3767bded2dbSJung-uk Kim 
3771f13597dSJung-uk Kim int tls1_ec_curve_id2nid(int curve_id)
3781f13597dSJung-uk Kim {
3797bded2dbSJung-uk Kim     /* ECC curves from RFC 4492 and RFC 7027 */
3801f13597dSJung-uk Kim     if ((curve_id < 1) || ((unsigned int)curve_id >
3811f13597dSJung-uk Kim                            sizeof(nid_list) / sizeof(nid_list[0])))
3821f13597dSJung-uk Kim         return 0;
3831f13597dSJung-uk Kim     return nid_list[curve_id - 1];
38474664626SKris Kennaway }
385f579bf8eSKris Kennaway 
3861f13597dSJung-uk Kim int tls1_ec_nid2curve_id(int nid)
387f579bf8eSKris Kennaway {
3887bded2dbSJung-uk Kim     /* ECC curves from RFC 4492 and RFC 7027 */
3896f9291ceSJung-uk Kim     switch (nid) {
3901f13597dSJung-uk Kim     case NID_sect163k1:        /* sect163k1 (1) */
3911f13597dSJung-uk Kim         return 1;
3921f13597dSJung-uk Kim     case NID_sect163r1:        /* sect163r1 (2) */
3931f13597dSJung-uk Kim         return 2;
3941f13597dSJung-uk Kim     case NID_sect163r2:        /* sect163r2 (3) */
3951f13597dSJung-uk Kim         return 3;
3961f13597dSJung-uk Kim     case NID_sect193r1:        /* sect193r1 (4) */
3971f13597dSJung-uk Kim         return 4;
3981f13597dSJung-uk Kim     case NID_sect193r2:        /* sect193r2 (5) */
3991f13597dSJung-uk Kim         return 5;
4001f13597dSJung-uk Kim     case NID_sect233k1:        /* sect233k1 (6) */
4011f13597dSJung-uk Kim         return 6;
4021f13597dSJung-uk Kim     case NID_sect233r1:        /* sect233r1 (7) */
4031f13597dSJung-uk Kim         return 7;
4041f13597dSJung-uk Kim     case NID_sect239k1:        /* sect239k1 (8) */
4051f13597dSJung-uk Kim         return 8;
4061f13597dSJung-uk Kim     case NID_sect283k1:        /* sect283k1 (9) */
4071f13597dSJung-uk Kim         return 9;
4081f13597dSJung-uk Kim     case NID_sect283r1:        /* sect283r1 (10) */
4091f13597dSJung-uk Kim         return 10;
4101f13597dSJung-uk Kim     case NID_sect409k1:        /* sect409k1 (11) */
4111f13597dSJung-uk Kim         return 11;
4121f13597dSJung-uk Kim     case NID_sect409r1:        /* sect409r1 (12) */
4131f13597dSJung-uk Kim         return 12;
4141f13597dSJung-uk Kim     case NID_sect571k1:        /* sect571k1 (13) */
4151f13597dSJung-uk Kim         return 13;
4161f13597dSJung-uk Kim     case NID_sect571r1:        /* sect571r1 (14) */
4171f13597dSJung-uk Kim         return 14;
4181f13597dSJung-uk Kim     case NID_secp160k1:        /* secp160k1 (15) */
4191f13597dSJung-uk Kim         return 15;
4201f13597dSJung-uk Kim     case NID_secp160r1:        /* secp160r1 (16) */
4211f13597dSJung-uk Kim         return 16;
4221f13597dSJung-uk Kim     case NID_secp160r2:        /* secp160r2 (17) */
4231f13597dSJung-uk Kim         return 17;
4241f13597dSJung-uk Kim     case NID_secp192k1:        /* secp192k1 (18) */
4251f13597dSJung-uk Kim         return 18;
4261f13597dSJung-uk Kim     case NID_X9_62_prime192v1: /* secp192r1 (19) */
4271f13597dSJung-uk Kim         return 19;
4281f13597dSJung-uk Kim     case NID_secp224k1:        /* secp224k1 (20) */
4291f13597dSJung-uk Kim         return 20;
4301f13597dSJung-uk Kim     case NID_secp224r1:        /* secp224r1 (21) */
4311f13597dSJung-uk Kim         return 21;
4321f13597dSJung-uk Kim     case NID_secp256k1:        /* secp256k1 (22) */
4331f13597dSJung-uk Kim         return 22;
4341f13597dSJung-uk Kim     case NID_X9_62_prime256v1: /* secp256r1 (23) */
4351f13597dSJung-uk Kim         return 23;
4361f13597dSJung-uk Kim     case NID_secp384r1:        /* secp384r1 (24) */
4371f13597dSJung-uk Kim         return 24;
4381f13597dSJung-uk Kim     case NID_secp521r1:        /* secp521r1 (25) */
4391f13597dSJung-uk Kim         return 25;
4407bded2dbSJung-uk Kim     case NID_brainpoolP256r1:  /* brainpoolP256r1 (26) */
4417bded2dbSJung-uk Kim         return 26;
4427bded2dbSJung-uk Kim     case NID_brainpoolP384r1:  /* brainpoolP384r1 (27) */
4437bded2dbSJung-uk Kim         return 27;
4447bded2dbSJung-uk Kim     case NID_brainpoolP512r1:  /* brainpool512r1 (28) */
4457bded2dbSJung-uk Kim         return 28;
4461f13597dSJung-uk Kim     default:
4471f13597dSJung-uk Kim         return 0;
448f579bf8eSKris Kennaway     }
4491f13597dSJung-uk Kim }
4507bded2dbSJung-uk Kim 
4517bded2dbSJung-uk Kim /*
4527bded2dbSJung-uk Kim  * Get curves list, if "sess" is set return client curves otherwise
4537bded2dbSJung-uk Kim  * preferred list.
4547bded2dbSJung-uk Kim  * Sets |num_curves| to the number of curves in the list, i.e.,
4557bded2dbSJung-uk Kim  * the length of |pcurves| is 2 * num_curves.
4567bded2dbSJung-uk Kim  * Returns 1 on success and 0 if the client curves list has invalid format.
4577bded2dbSJung-uk Kim  * The latter indicates an internal error: we should not be accepting such
4587bded2dbSJung-uk Kim  * lists in the first place.
4597bded2dbSJung-uk Kim  * TODO(emilia): we should really be storing the curves list in explicitly
4607bded2dbSJung-uk Kim  * parsed form instead. (However, this would affect binary compatibility
4617bded2dbSJung-uk Kim  * so cannot happen in the 1.0.x series.)
4627bded2dbSJung-uk Kim  */
4637bded2dbSJung-uk Kim static int tls1_get_curvelist(SSL *s, int sess,
4647bded2dbSJung-uk Kim                               const unsigned char **pcurves,
4657bded2dbSJung-uk Kim                               size_t *num_curves)
4667bded2dbSJung-uk Kim {
4677bded2dbSJung-uk Kim     size_t pcurveslen = 0;
4687bded2dbSJung-uk Kim     if (sess) {
4697bded2dbSJung-uk Kim         *pcurves = s->session->tlsext_ellipticcurvelist;
4707bded2dbSJung-uk Kim         pcurveslen = s->session->tlsext_ellipticcurvelist_length;
4717bded2dbSJung-uk Kim     } else {
4727bded2dbSJung-uk Kim         /* For Suite B mode only include P-256, P-384 */
4737bded2dbSJung-uk Kim         switch (tls1_suiteb(s)) {
4747bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_128_LOS:
4757bded2dbSJung-uk Kim             *pcurves = suiteb_curves;
4767bded2dbSJung-uk Kim             pcurveslen = sizeof(suiteb_curves);
4777bded2dbSJung-uk Kim             break;
4787bded2dbSJung-uk Kim 
4797bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
4807bded2dbSJung-uk Kim             *pcurves = suiteb_curves;
4817bded2dbSJung-uk Kim             pcurveslen = 2;
4827bded2dbSJung-uk Kim             break;
4837bded2dbSJung-uk Kim 
4847bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_192_LOS:
4857bded2dbSJung-uk Kim             *pcurves = suiteb_curves + 2;
4867bded2dbSJung-uk Kim             pcurveslen = 2;
4877bded2dbSJung-uk Kim             break;
4887bded2dbSJung-uk Kim         default:
4897bded2dbSJung-uk Kim             *pcurves = s->tlsext_ellipticcurvelist;
4907bded2dbSJung-uk Kim             pcurveslen = s->tlsext_ellipticcurvelist_length;
4917bded2dbSJung-uk Kim         }
4927bded2dbSJung-uk Kim         if (!*pcurves) {
4937bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
4947bded2dbSJung-uk Kim             if (FIPS_mode()) {
4957bded2dbSJung-uk Kim                 *pcurves = fips_curves_default;
4967bded2dbSJung-uk Kim                 pcurveslen = sizeof(fips_curves_default);
4977bded2dbSJung-uk Kim             } else
4987bded2dbSJung-uk Kim # endif
4997bded2dbSJung-uk Kim             {
50080815a77SJung-uk Kim                 if (!s->server || s->cert->ecdh_tmp_auto) {
5017bded2dbSJung-uk Kim                     *pcurves = eccurves_auto;
5027bded2dbSJung-uk Kim                     pcurveslen = sizeof(eccurves_auto);
5037bded2dbSJung-uk Kim                 } else {
5047bded2dbSJung-uk Kim                     *pcurves = eccurves_all;
5057bded2dbSJung-uk Kim                     pcurveslen = sizeof(eccurves_all);
5067bded2dbSJung-uk Kim                 }
5077bded2dbSJung-uk Kim             }
5087bded2dbSJung-uk Kim         }
5097bded2dbSJung-uk Kim     }
5107bded2dbSJung-uk Kim     /* We do not allow odd length arrays to enter the system. */
5117bded2dbSJung-uk Kim     if (pcurveslen & 1) {
5127bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR);
5137bded2dbSJung-uk Kim         *num_curves = 0;
5147bded2dbSJung-uk Kim         return 0;
5157bded2dbSJung-uk Kim     } else {
5167bded2dbSJung-uk Kim         *num_curves = pcurveslen / 2;
5177bded2dbSJung-uk Kim         return 1;
5187bded2dbSJung-uk Kim     }
5197bded2dbSJung-uk Kim }
5207bded2dbSJung-uk Kim 
5217bded2dbSJung-uk Kim /* Check a curve is one of our preferences */
5227bded2dbSJung-uk Kim int tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
5237bded2dbSJung-uk Kim {
5247bded2dbSJung-uk Kim     const unsigned char *curves;
5257bded2dbSJung-uk Kim     size_t num_curves, i;
5267bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
5277bded2dbSJung-uk Kim     if (len != 3 || p[0] != NAMED_CURVE_TYPE)
5287bded2dbSJung-uk Kim         return 0;
5297bded2dbSJung-uk Kim     /* Check curve matches Suite B preferences */
5307bded2dbSJung-uk Kim     if (suiteb_flags) {
5317bded2dbSJung-uk Kim         unsigned long cid = s->s3->tmp.new_cipher->id;
5327bded2dbSJung-uk Kim         if (p[1])
5337bded2dbSJung-uk Kim             return 0;
5347bded2dbSJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) {
5357bded2dbSJung-uk Kim             if (p[2] != TLSEXT_curve_P_256)
5367bded2dbSJung-uk Kim                 return 0;
5377bded2dbSJung-uk Kim         } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) {
5387bded2dbSJung-uk Kim             if (p[2] != TLSEXT_curve_P_384)
5397bded2dbSJung-uk Kim                 return 0;
5407bded2dbSJung-uk Kim         } else                  /* Should never happen */
5417bded2dbSJung-uk Kim             return 0;
5427bded2dbSJung-uk Kim     }
5437bded2dbSJung-uk Kim     if (!tls1_get_curvelist(s, 0, &curves, &num_curves))
5447bded2dbSJung-uk Kim         return 0;
5457bded2dbSJung-uk Kim     for (i = 0; i < num_curves; i++, curves += 2) {
5467bded2dbSJung-uk Kim         if (p[1] == curves[0] && p[2] == curves[1])
5477bded2dbSJung-uk Kim             return 1;
5487bded2dbSJung-uk Kim     }
5497bded2dbSJung-uk Kim     return 0;
5507bded2dbSJung-uk Kim }
5517bded2dbSJung-uk Kim 
5527bded2dbSJung-uk Kim /*-
5537bded2dbSJung-uk Kim  * Return |nmatch|th shared curve or NID_undef if there is no match.
5547bded2dbSJung-uk Kim  * For nmatch == -1, return number of  matches
5557bded2dbSJung-uk Kim  * For nmatch == -2, return the NID of the curve to use for
5567bded2dbSJung-uk Kim  * an EC tmp key, or NID_undef if there is no match.
5577bded2dbSJung-uk Kim  */
5587bded2dbSJung-uk Kim int tls1_shared_curve(SSL *s, int nmatch)
5597bded2dbSJung-uk Kim {
5607bded2dbSJung-uk Kim     const unsigned char *pref, *supp;
5617bded2dbSJung-uk Kim     size_t num_pref, num_supp, i, j;
5627bded2dbSJung-uk Kim     int k;
5637bded2dbSJung-uk Kim     /* Can't do anything on client side */
5647bded2dbSJung-uk Kim     if (s->server == 0)
5657bded2dbSJung-uk Kim         return -1;
5667bded2dbSJung-uk Kim     if (nmatch == -2) {
5677bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
5687bded2dbSJung-uk Kim             /*
5697bded2dbSJung-uk Kim              * For Suite B ciphersuite determines curve: we already know
5707bded2dbSJung-uk Kim              * these are acceptable due to previous checks.
5717bded2dbSJung-uk Kim              */
5727bded2dbSJung-uk Kim             unsigned long cid = s->s3->tmp.new_cipher->id;
5737bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
5747bded2dbSJung-uk Kim                 return NID_X9_62_prime256v1; /* P-256 */
5757bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
5767bded2dbSJung-uk Kim                 return NID_secp384r1; /* P-384 */
5777bded2dbSJung-uk Kim             /* Should never happen */
5787bded2dbSJung-uk Kim             return NID_undef;
5797bded2dbSJung-uk Kim         }
5807bded2dbSJung-uk Kim         /* If not Suite B just return first preference shared curve */
5817bded2dbSJung-uk Kim         nmatch = 0;
5827bded2dbSJung-uk Kim     }
5837bded2dbSJung-uk Kim     /*
5847bded2dbSJung-uk Kim      * Avoid truncation. tls1_get_curvelist takes an int
5857bded2dbSJung-uk Kim      * but s->options is a long...
5867bded2dbSJung-uk Kim      */
5877bded2dbSJung-uk Kim     if (!tls1_get_curvelist
5887bded2dbSJung-uk Kim         (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp,
5897bded2dbSJung-uk Kim          &num_supp))
5907bded2dbSJung-uk Kim         /* In practice, NID_undef == 0 but let's be precise. */
5917bded2dbSJung-uk Kim         return nmatch == -1 ? 0 : NID_undef;
5927bded2dbSJung-uk Kim     if (!tls1_get_curvelist
5937bded2dbSJung-uk Kim         (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref,
5947bded2dbSJung-uk Kim          &num_pref))
5957bded2dbSJung-uk Kim         return nmatch == -1 ? 0 : NID_undef;
5967bded2dbSJung-uk Kim 
5977bded2dbSJung-uk Kim     /*
5987bded2dbSJung-uk Kim      * If the client didn't send the elliptic_curves extension all of them
5997bded2dbSJung-uk Kim      * are allowed.
6007bded2dbSJung-uk Kim      */
6017bded2dbSJung-uk Kim     if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) {
6027bded2dbSJung-uk Kim         supp = eccurves_all;
6037bded2dbSJung-uk Kim         num_supp = sizeof(eccurves_all) / 2;
6047bded2dbSJung-uk Kim     } else if (num_pref == 0 &&
6057bded2dbSJung-uk Kim         (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) {
6067bded2dbSJung-uk Kim         pref = eccurves_all;
6077bded2dbSJung-uk Kim         num_pref = sizeof(eccurves_all) / 2;
6087bded2dbSJung-uk Kim     }
6097bded2dbSJung-uk Kim 
6107bded2dbSJung-uk Kim     k = 0;
6117bded2dbSJung-uk Kim     for (i = 0; i < num_pref; i++, pref += 2) {
6127bded2dbSJung-uk Kim         const unsigned char *tsupp = supp;
6137bded2dbSJung-uk Kim         for (j = 0; j < num_supp; j++, tsupp += 2) {
6147bded2dbSJung-uk Kim             if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) {
6157bded2dbSJung-uk Kim                 if (nmatch == k) {
6167bded2dbSJung-uk Kim                     int id = (pref[0] << 8) | pref[1];
6177bded2dbSJung-uk Kim                     return tls1_ec_curve_id2nid(id);
6187bded2dbSJung-uk Kim                 }
6197bded2dbSJung-uk Kim                 k++;
6207bded2dbSJung-uk Kim             }
6217bded2dbSJung-uk Kim         }
6227bded2dbSJung-uk Kim     }
6237bded2dbSJung-uk Kim     if (nmatch == -1)
6247bded2dbSJung-uk Kim         return k;
6257bded2dbSJung-uk Kim     /* Out of range (nmatch > k). */
6267bded2dbSJung-uk Kim     return NID_undef;
6277bded2dbSJung-uk Kim }
6287bded2dbSJung-uk Kim 
6297bded2dbSJung-uk Kim int tls1_set_curves(unsigned char **pext, size_t *pextlen,
6307bded2dbSJung-uk Kim                     int *curves, size_t ncurves)
6317bded2dbSJung-uk Kim {
6327bded2dbSJung-uk Kim     unsigned char *clist, *p;
6337bded2dbSJung-uk Kim     size_t i;
6347bded2dbSJung-uk Kim     /*
6357bded2dbSJung-uk Kim      * Bitmap of curves included to detect duplicates: only works while curve
6367bded2dbSJung-uk Kim      * ids < 32
6377bded2dbSJung-uk Kim      */
6387bded2dbSJung-uk Kim     unsigned long dup_list = 0;
6397bded2dbSJung-uk Kim # ifdef OPENSSL_NO_EC2M
6407bded2dbSJung-uk Kim     EC_GROUP *curve;
6417bded2dbSJung-uk Kim # endif
6427bded2dbSJung-uk Kim 
6437bded2dbSJung-uk Kim     clist = OPENSSL_malloc(ncurves * 2);
6447bded2dbSJung-uk Kim     if (!clist)
6457bded2dbSJung-uk Kim         return 0;
6467bded2dbSJung-uk Kim     for (i = 0, p = clist; i < ncurves; i++) {
6477bded2dbSJung-uk Kim         unsigned long idmask;
6487bded2dbSJung-uk Kim         int id;
6497bded2dbSJung-uk Kim         id = tls1_ec_nid2curve_id(curves[i]);
6507bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
6517bded2dbSJung-uk Kim         /* NB: 25 is last curve ID supported by FIPS module */
6527bded2dbSJung-uk Kim         if (FIPS_mode() && id > 25) {
6537bded2dbSJung-uk Kim             OPENSSL_free(clist);
6547bded2dbSJung-uk Kim             return 0;
6557bded2dbSJung-uk Kim         }
6567bded2dbSJung-uk Kim # endif
6577bded2dbSJung-uk Kim # ifdef OPENSSL_NO_EC2M
6587bded2dbSJung-uk Kim         curve = EC_GROUP_new_by_curve_name(curves[i]);
6597bded2dbSJung-uk Kim         if (!curve || EC_METHOD_get_field_type(EC_GROUP_method_of(curve))
6607bded2dbSJung-uk Kim             == NID_X9_62_characteristic_two_field) {
6617bded2dbSJung-uk Kim             if (curve)
6627bded2dbSJung-uk Kim                 EC_GROUP_free(curve);
6637bded2dbSJung-uk Kim             OPENSSL_free(clist);
6647bded2dbSJung-uk Kim             return 0;
6657bded2dbSJung-uk Kim         } else
6667bded2dbSJung-uk Kim             EC_GROUP_free(curve);
6677bded2dbSJung-uk Kim # endif
6687bded2dbSJung-uk Kim         idmask = 1L << id;
6697bded2dbSJung-uk Kim         if (!id || (dup_list & idmask)) {
6707bded2dbSJung-uk Kim             OPENSSL_free(clist);
6717bded2dbSJung-uk Kim             return 0;
6727bded2dbSJung-uk Kim         }
6737bded2dbSJung-uk Kim         dup_list |= idmask;
6747bded2dbSJung-uk Kim         s2n(id, p);
6757bded2dbSJung-uk Kim     }
6767bded2dbSJung-uk Kim     if (*pext)
6777bded2dbSJung-uk Kim         OPENSSL_free(*pext);
6787bded2dbSJung-uk Kim     *pext = clist;
6797bded2dbSJung-uk Kim     *pextlen = ncurves * 2;
6807bded2dbSJung-uk Kim     return 1;
6817bded2dbSJung-uk Kim }
6827bded2dbSJung-uk Kim 
6837bded2dbSJung-uk Kim # define MAX_CURVELIST   28
6847bded2dbSJung-uk Kim 
6857bded2dbSJung-uk Kim typedef struct {
6867bded2dbSJung-uk Kim     size_t nidcnt;
6877bded2dbSJung-uk Kim     int nid_arr[MAX_CURVELIST];
6887bded2dbSJung-uk Kim } nid_cb_st;
6897bded2dbSJung-uk Kim 
6907bded2dbSJung-uk Kim static int nid_cb(const char *elem, int len, void *arg)
6917bded2dbSJung-uk Kim {
6927bded2dbSJung-uk Kim     nid_cb_st *narg = arg;
6937bded2dbSJung-uk Kim     size_t i;
6947bded2dbSJung-uk Kim     int nid;
6957bded2dbSJung-uk Kim     char etmp[20];
6967bded2dbSJung-uk Kim     if (elem == NULL)
6977bded2dbSJung-uk Kim         return 0;
6987bded2dbSJung-uk Kim     if (narg->nidcnt == MAX_CURVELIST)
6997bded2dbSJung-uk Kim         return 0;
7007bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
7017bded2dbSJung-uk Kim         return 0;
7027bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
7037bded2dbSJung-uk Kim     etmp[len] = 0;
7047bded2dbSJung-uk Kim     nid = EC_curve_nist2nid(etmp);
7057bded2dbSJung-uk Kim     if (nid == NID_undef)
7067bded2dbSJung-uk Kim         nid = OBJ_sn2nid(etmp);
7077bded2dbSJung-uk Kim     if (nid == NID_undef)
7087bded2dbSJung-uk Kim         nid = OBJ_ln2nid(etmp);
7097bded2dbSJung-uk Kim     if (nid == NID_undef)
7107bded2dbSJung-uk Kim         return 0;
7117bded2dbSJung-uk Kim     for (i = 0; i < narg->nidcnt; i++)
7127bded2dbSJung-uk Kim         if (narg->nid_arr[i] == nid)
7137bded2dbSJung-uk Kim             return 0;
7147bded2dbSJung-uk Kim     narg->nid_arr[narg->nidcnt++] = nid;
7157bded2dbSJung-uk Kim     return 1;
7167bded2dbSJung-uk Kim }
7177bded2dbSJung-uk Kim 
7187bded2dbSJung-uk Kim /* Set curves based on a colon separate list */
7197bded2dbSJung-uk Kim int tls1_set_curves_list(unsigned char **pext, size_t *pextlen,
7207bded2dbSJung-uk Kim                          const char *str)
7217bded2dbSJung-uk Kim {
7227bded2dbSJung-uk Kim     nid_cb_st ncb;
7237bded2dbSJung-uk Kim     ncb.nidcnt = 0;
7247bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb))
7257bded2dbSJung-uk Kim         return 0;
7267bded2dbSJung-uk Kim     if (pext == NULL)
7277bded2dbSJung-uk Kim         return 1;
7287bded2dbSJung-uk Kim     return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt);
7297bded2dbSJung-uk Kim }
7307bded2dbSJung-uk Kim 
7317bded2dbSJung-uk Kim /* For an EC key set TLS id and required compression based on parameters */
7327bded2dbSJung-uk Kim static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id,
7337bded2dbSJung-uk Kim                           EC_KEY *ec)
7347bded2dbSJung-uk Kim {
7357bded2dbSJung-uk Kim     int is_prime, id;
7367bded2dbSJung-uk Kim     const EC_GROUP *grp;
7377bded2dbSJung-uk Kim     const EC_METHOD *meth;
7387bded2dbSJung-uk Kim     if (!ec)
7397bded2dbSJung-uk Kim         return 0;
7407bded2dbSJung-uk Kim     /* Determine if it is a prime field */
7417bded2dbSJung-uk Kim     grp = EC_KEY_get0_group(ec);
7427bded2dbSJung-uk Kim     if (!grp)
7437bded2dbSJung-uk Kim         return 0;
7447bded2dbSJung-uk Kim     meth = EC_GROUP_method_of(grp);
7457bded2dbSJung-uk Kim     if (!meth)
7467bded2dbSJung-uk Kim         return 0;
7477bded2dbSJung-uk Kim     if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
7487bded2dbSJung-uk Kim         is_prime = 1;
7497bded2dbSJung-uk Kim     else
7507bded2dbSJung-uk Kim         is_prime = 0;
7517bded2dbSJung-uk Kim     /* Determine curve ID */
7527bded2dbSJung-uk Kim     id = EC_GROUP_get_curve_name(grp);
7537bded2dbSJung-uk Kim     id = tls1_ec_nid2curve_id(id);
7547bded2dbSJung-uk Kim     /* If we have an ID set it, otherwise set arbitrary explicit curve */
7557bded2dbSJung-uk Kim     if (id) {
7567bded2dbSJung-uk Kim         curve_id[0] = 0;
7577bded2dbSJung-uk Kim         curve_id[1] = (unsigned char)id;
7587bded2dbSJung-uk Kim     } else {
7597bded2dbSJung-uk Kim         curve_id[0] = 0xff;
7607bded2dbSJung-uk Kim         if (is_prime)
7617bded2dbSJung-uk Kim             curve_id[1] = 0x01;
7627bded2dbSJung-uk Kim         else
7637bded2dbSJung-uk Kim             curve_id[1] = 0x02;
7647bded2dbSJung-uk Kim     }
7657bded2dbSJung-uk Kim     if (comp_id) {
7667bded2dbSJung-uk Kim         if (EC_KEY_get0_public_key(ec) == NULL)
7677bded2dbSJung-uk Kim             return 0;
7687bded2dbSJung-uk Kim         if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
7697bded2dbSJung-uk Kim             if (is_prime)
7707bded2dbSJung-uk Kim                 *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
7717bded2dbSJung-uk Kim             else
7727bded2dbSJung-uk Kim                 *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
7737bded2dbSJung-uk Kim         } else
7747bded2dbSJung-uk Kim             *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
7757bded2dbSJung-uk Kim     }
7767bded2dbSJung-uk Kim     return 1;
7777bded2dbSJung-uk Kim }
7787bded2dbSJung-uk Kim 
7797bded2dbSJung-uk Kim /* Check an EC key is compatible with extensions */
7807bded2dbSJung-uk Kim static int tls1_check_ec_key(SSL *s,
7817bded2dbSJung-uk Kim                              unsigned char *curve_id, unsigned char *comp_id)
7827bded2dbSJung-uk Kim {
7837bded2dbSJung-uk Kim     const unsigned char *pformats, *pcurves;
7847bded2dbSJung-uk Kim     size_t num_formats, num_curves, i;
7857bded2dbSJung-uk Kim     int j;
7867bded2dbSJung-uk Kim     /*
7877bded2dbSJung-uk Kim      * If point formats extension present check it, otherwise everything is
7887bded2dbSJung-uk Kim      * supported (see RFC4492).
7897bded2dbSJung-uk Kim      */
7907bded2dbSJung-uk Kim     if (comp_id && s->session->tlsext_ecpointformatlist) {
7917bded2dbSJung-uk Kim         pformats = s->session->tlsext_ecpointformatlist;
7927bded2dbSJung-uk Kim         num_formats = s->session->tlsext_ecpointformatlist_length;
7937bded2dbSJung-uk Kim         for (i = 0; i < num_formats; i++, pformats++) {
7947bded2dbSJung-uk Kim             if (*comp_id == *pformats)
7957bded2dbSJung-uk Kim                 break;
7967bded2dbSJung-uk Kim         }
7977bded2dbSJung-uk Kim         if (i == num_formats)
7987bded2dbSJung-uk Kim             return 0;
7997bded2dbSJung-uk Kim     }
8007bded2dbSJung-uk Kim     if (!curve_id)
8017bded2dbSJung-uk Kim         return 1;
8027bded2dbSJung-uk Kim     /* Check curve is consistent with client and server preferences */
8037bded2dbSJung-uk Kim     for (j = 0; j <= 1; j++) {
8047bded2dbSJung-uk Kim         if (!tls1_get_curvelist(s, j, &pcurves, &num_curves))
8057bded2dbSJung-uk Kim             return 0;
8067bded2dbSJung-uk Kim         if (j == 1 && num_curves == 0) {
8077bded2dbSJung-uk Kim             /*
8087bded2dbSJung-uk Kim              * If we've not received any curves then skip this check.
8097bded2dbSJung-uk Kim              * RFC 4492 does not require the supported elliptic curves extension
8107bded2dbSJung-uk Kim              * so if it is not sent we can just choose any curve.
8117bded2dbSJung-uk Kim              * It is invalid to send an empty list in the elliptic curves
8127bded2dbSJung-uk Kim              * extension, so num_curves == 0 always means no extension.
8137bded2dbSJung-uk Kim              */
8147bded2dbSJung-uk Kim             break;
8157bded2dbSJung-uk Kim         }
8167bded2dbSJung-uk Kim         for (i = 0; i < num_curves; i++, pcurves += 2) {
8177bded2dbSJung-uk Kim             if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1])
8187bded2dbSJung-uk Kim                 break;
8197bded2dbSJung-uk Kim         }
8207bded2dbSJung-uk Kim         if (i == num_curves)
8217bded2dbSJung-uk Kim             return 0;
8227bded2dbSJung-uk Kim         /* For clients can only check sent curve list */
8237bded2dbSJung-uk Kim         if (!s->server)
8247bded2dbSJung-uk Kim             return 1;
8257bded2dbSJung-uk Kim     }
8267bded2dbSJung-uk Kim     return 1;
8277bded2dbSJung-uk Kim }
8287bded2dbSJung-uk Kim 
8297bded2dbSJung-uk Kim static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
8307bded2dbSJung-uk Kim                                 size_t *num_formats)
8317bded2dbSJung-uk Kim {
8327bded2dbSJung-uk Kim     /*
8337bded2dbSJung-uk Kim      * If we have a custom point format list use it otherwise use default
8347bded2dbSJung-uk Kim      */
8357bded2dbSJung-uk Kim     if (s->tlsext_ecpointformatlist) {
8367bded2dbSJung-uk Kim         *pformats = s->tlsext_ecpointformatlist;
8377bded2dbSJung-uk Kim         *num_formats = s->tlsext_ecpointformatlist_length;
8387bded2dbSJung-uk Kim     } else {
8397bded2dbSJung-uk Kim         *pformats = ecformats_default;
8407bded2dbSJung-uk Kim         /* For Suite B we don't support char2 fields */
8417bded2dbSJung-uk Kim         if (tls1_suiteb(s))
8427bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default) - 1;
8437bded2dbSJung-uk Kim         else
8447bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default);
8457bded2dbSJung-uk Kim     }
8467bded2dbSJung-uk Kim }
8477bded2dbSJung-uk Kim 
8487bded2dbSJung-uk Kim /*
8497bded2dbSJung-uk Kim  * Check cert parameters compatible with extensions: currently just checks EC
8507bded2dbSJung-uk Kim  * certificates have compatible curves and compression.
8517bded2dbSJung-uk Kim  */
8527bded2dbSJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
8537bded2dbSJung-uk Kim {
8547bded2dbSJung-uk Kim     unsigned char comp_id, curve_id[2];
8557bded2dbSJung-uk Kim     EVP_PKEY *pkey;
8567bded2dbSJung-uk Kim     int rv;
8577bded2dbSJung-uk Kim     pkey = X509_get_pubkey(x);
8587bded2dbSJung-uk Kim     if (!pkey)
8597bded2dbSJung-uk Kim         return 0;
8607bded2dbSJung-uk Kim     /* If not EC nothing to do */
8617bded2dbSJung-uk Kim     if (pkey->type != EVP_PKEY_EC) {
8627bded2dbSJung-uk Kim         EVP_PKEY_free(pkey);
8637bded2dbSJung-uk Kim         return 1;
8647bded2dbSJung-uk Kim     }
8657bded2dbSJung-uk Kim     rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec);
8667bded2dbSJung-uk Kim     EVP_PKEY_free(pkey);
8677bded2dbSJung-uk Kim     if (!rv)
8687bded2dbSJung-uk Kim         return 0;
8697bded2dbSJung-uk Kim     /*
8707bded2dbSJung-uk Kim      * Can't check curve_id for client certs as we don't have a supported
8717bded2dbSJung-uk Kim      * curves extension.
8727bded2dbSJung-uk Kim      */
8737bded2dbSJung-uk Kim     rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id);
8747bded2dbSJung-uk Kim     if (!rv)
8757bded2dbSJung-uk Kim         return 0;
8767bded2dbSJung-uk Kim     /*
8777bded2dbSJung-uk Kim      * Special case for suite B. We *MUST* sign using SHA256+P-256 or
8787bded2dbSJung-uk Kim      * SHA384+P-384, adjust digest if necessary.
8797bded2dbSJung-uk Kim      */
8807bded2dbSJung-uk Kim     if (set_ee_md && tls1_suiteb(s)) {
8817bded2dbSJung-uk Kim         int check_md;
8827bded2dbSJung-uk Kim         size_t i;
8837bded2dbSJung-uk Kim         CERT *c = s->cert;
8847bded2dbSJung-uk Kim         if (curve_id[0])
8857bded2dbSJung-uk Kim             return 0;
8867bded2dbSJung-uk Kim         /* Check to see we have necessary signing algorithm */
8877bded2dbSJung-uk Kim         if (curve_id[1] == TLSEXT_curve_P_256)
8887bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA256;
8897bded2dbSJung-uk Kim         else if (curve_id[1] == TLSEXT_curve_P_384)
8907bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA384;
8917bded2dbSJung-uk Kim         else
8927bded2dbSJung-uk Kim             return 0;           /* Should never happen */
8937bded2dbSJung-uk Kim         for (i = 0; i < c->shared_sigalgslen; i++)
8947bded2dbSJung-uk Kim             if (check_md == c->shared_sigalgs[i].signandhash_nid)
8957bded2dbSJung-uk Kim                 break;
8967bded2dbSJung-uk Kim         if (i == c->shared_sigalgslen)
8977bded2dbSJung-uk Kim             return 0;
8987bded2dbSJung-uk Kim         if (set_ee_md == 2) {
8997bded2dbSJung-uk Kim             if (check_md == NID_ecdsa_with_SHA256)
9007bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256();
9017bded2dbSJung-uk Kim             else
9027bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384();
9037bded2dbSJung-uk Kim         }
9047bded2dbSJung-uk Kim     }
9057bded2dbSJung-uk Kim     return rv;
9067bded2dbSJung-uk Kim }
9077bded2dbSJung-uk Kim 
9087bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDH
9097bded2dbSJung-uk Kim /* Check EC temporary key is compatible with client extensions */
9107bded2dbSJung-uk Kim int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
9117bded2dbSJung-uk Kim {
9127bded2dbSJung-uk Kim     unsigned char curve_id[2];
9137bded2dbSJung-uk Kim     EC_KEY *ec = s->cert->ecdh_tmp;
9147bded2dbSJung-uk Kim #  ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
9157bded2dbSJung-uk Kim     /* Allow any curve: not just those peer supports */
9167bded2dbSJung-uk Kim     if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
9177bded2dbSJung-uk Kim         return 1;
9187bded2dbSJung-uk Kim #  endif
9197bded2dbSJung-uk Kim     /*
9207bded2dbSJung-uk Kim      * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other
9217bded2dbSJung-uk Kim      * curves permitted.
9227bded2dbSJung-uk Kim      */
9237bded2dbSJung-uk Kim     if (tls1_suiteb(s)) {
9247bded2dbSJung-uk Kim         /* Curve to check determined by ciphersuite */
9257bded2dbSJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
9267bded2dbSJung-uk Kim             curve_id[1] = TLSEXT_curve_P_256;
9277bded2dbSJung-uk Kim         else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
9287bded2dbSJung-uk Kim             curve_id[1] = TLSEXT_curve_P_384;
9297bded2dbSJung-uk Kim         else
9307bded2dbSJung-uk Kim             return 0;
9317bded2dbSJung-uk Kim         curve_id[0] = 0;
9327bded2dbSJung-uk Kim         /* Check this curve is acceptable */
9337bded2dbSJung-uk Kim         if (!tls1_check_ec_key(s, curve_id, NULL))
9347bded2dbSJung-uk Kim             return 0;
9357bded2dbSJung-uk Kim         /* If auto or setting curve from callback assume OK */
9367bded2dbSJung-uk Kim         if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb)
9377bded2dbSJung-uk Kim             return 1;
9387bded2dbSJung-uk Kim         /* Otherwise check curve is acceptable */
9397bded2dbSJung-uk Kim         else {
9407bded2dbSJung-uk Kim             unsigned char curve_tmp[2];
9417bded2dbSJung-uk Kim             if (!ec)
9427bded2dbSJung-uk Kim                 return 0;
9437bded2dbSJung-uk Kim             if (!tls1_set_ec_id(curve_tmp, NULL, ec))
9447bded2dbSJung-uk Kim                 return 0;
9457bded2dbSJung-uk Kim             if (!curve_tmp[0] || curve_tmp[1] == curve_id[1])
9467bded2dbSJung-uk Kim                 return 1;
9477bded2dbSJung-uk Kim             return 0;
9487bded2dbSJung-uk Kim         }
9497bded2dbSJung-uk Kim 
9507bded2dbSJung-uk Kim     }
9517bded2dbSJung-uk Kim     if (s->cert->ecdh_tmp_auto) {
9527bded2dbSJung-uk Kim         /* Need a shared curve */
9537bded2dbSJung-uk Kim         if (tls1_shared_curve(s, 0))
9547bded2dbSJung-uk Kim             return 1;
9557bded2dbSJung-uk Kim         else
9567bded2dbSJung-uk Kim             return 0;
9577bded2dbSJung-uk Kim     }
9587bded2dbSJung-uk Kim     if (!ec) {
9597bded2dbSJung-uk Kim         if (s->cert->ecdh_tmp_cb)
9607bded2dbSJung-uk Kim             return 1;
9617bded2dbSJung-uk Kim         else
9627bded2dbSJung-uk Kim             return 0;
9637bded2dbSJung-uk Kim     }
9647bded2dbSJung-uk Kim     if (!tls1_set_ec_id(curve_id, NULL, ec))
9657bded2dbSJung-uk Kim         return 0;
9667bded2dbSJung-uk Kim /* Set this to allow use of invalid curves for testing */
9677bded2dbSJung-uk Kim #  if 0
9687bded2dbSJung-uk Kim     return 1;
9697bded2dbSJung-uk Kim #  else
9707bded2dbSJung-uk Kim     return tls1_check_ec_key(s, curve_id, NULL);
9717bded2dbSJung-uk Kim #  endif
9727bded2dbSJung-uk Kim }
9737bded2dbSJung-uk Kim # endif                         /* OPENSSL_NO_ECDH */
9747bded2dbSJung-uk Kim 
9757bded2dbSJung-uk Kim #else
9767bded2dbSJung-uk Kim 
9777bded2dbSJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
9787bded2dbSJung-uk Kim {
9797bded2dbSJung-uk Kim     return 1;
9807bded2dbSJung-uk Kim }
9817bded2dbSJung-uk Kim 
9821f13597dSJung-uk Kim #endif                          /* OPENSSL_NO_EC */
983db522d3aSSimon L. B. Nielsen 
984db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
9851f13597dSJung-uk Kim 
9866f9291ceSJung-uk Kim /*
9876f9291ceSJung-uk Kim  * List of supported signature algorithms and hashes. Should make this
9881f13597dSJung-uk Kim  * customisable at some point, for now include everything we support.
9891f13597dSJung-uk Kim  */
9901f13597dSJung-uk Kim 
9911f13597dSJung-uk Kim # ifdef OPENSSL_NO_RSA
9921f13597dSJung-uk Kim #  define tlsext_sigalg_rsa(md) /* */
9931f13597dSJung-uk Kim # else
9941f13597dSJung-uk Kim #  define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
9951f13597dSJung-uk Kim # endif
9961f13597dSJung-uk Kim 
9971f13597dSJung-uk Kim # ifdef OPENSSL_NO_DSA
9981f13597dSJung-uk Kim #  define tlsext_sigalg_dsa(md) /* */
9991f13597dSJung-uk Kim # else
10001f13597dSJung-uk Kim #  define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
10011f13597dSJung-uk Kim # endif
10021f13597dSJung-uk Kim 
10031f13597dSJung-uk Kim # ifdef OPENSSL_NO_ECDSA
10046f9291ceSJung-uk Kim #  define tlsext_sigalg_ecdsa(md)
10056f9291ceSJung-uk Kim                                 /* */
10061f13597dSJung-uk Kim # else
10071f13597dSJung-uk Kim #  define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
10081f13597dSJung-uk Kim # endif
10091f13597dSJung-uk Kim 
10101f13597dSJung-uk Kim # define tlsext_sigalg(md) \
10111f13597dSJung-uk Kim                 tlsext_sigalg_rsa(md) \
10121f13597dSJung-uk Kim                 tlsext_sigalg_dsa(md) \
10131f13597dSJung-uk Kim                 tlsext_sigalg_ecdsa(md)
10141f13597dSJung-uk Kim 
10151f13597dSJung-uk Kim static unsigned char tls12_sigalgs[] = {
10161f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
10171f13597dSJung-uk Kim     tlsext_sigalg(TLSEXT_hash_sha512)
10181f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha384)
10191f13597dSJung-uk Kim # endif
10201f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
10211f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha256)
10221f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha224)
10231f13597dSJung-uk Kim # endif
10241f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
10251f13597dSJung-uk Kim         tlsext_sigalg(TLSEXT_hash_sha1)
10261f13597dSJung-uk Kim # endif
10271f13597dSJung-uk Kim };
10281f13597dSJung-uk Kim 
10297bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
10307bded2dbSJung-uk Kim static unsigned char suiteb_sigalgs[] = {
10317bded2dbSJung-uk Kim     tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
10327bded2dbSJung-uk Kim         tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
10337bded2dbSJung-uk Kim };
10347bded2dbSJung-uk Kim # endif
10357bded2dbSJung-uk Kim size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
10361f13597dSJung-uk Kim {
10377bded2dbSJung-uk Kim     /*
10387bded2dbSJung-uk Kim      * If Suite B mode use Suite B sigalgs only, ignore any other
10397bded2dbSJung-uk Kim      * preferences.
10407bded2dbSJung-uk Kim      */
10417bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
10427bded2dbSJung-uk Kim     switch (tls1_suiteb(s)) {
10437bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
10447bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
10457bded2dbSJung-uk Kim         return sizeof(suiteb_sigalgs);
10467bded2dbSJung-uk Kim 
10477bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
10487bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
10497bded2dbSJung-uk Kim         return 2;
10507bded2dbSJung-uk Kim 
10517bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
10527bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs + 2;
10537bded2dbSJung-uk Kim         return 2;
10547bded2dbSJung-uk Kim     }
10557bded2dbSJung-uk Kim # endif
10567bded2dbSJung-uk Kim     /* If server use client authentication sigalgs if not NULL */
10577bded2dbSJung-uk Kim     if (s->server && s->cert->client_sigalgs) {
10587bded2dbSJung-uk Kim         *psigs = s->cert->client_sigalgs;
10597bded2dbSJung-uk Kim         return s->cert->client_sigalgslen;
10607bded2dbSJung-uk Kim     } else if (s->cert->conf_sigalgs) {
10617bded2dbSJung-uk Kim         *psigs = s->cert->conf_sigalgs;
10627bded2dbSJung-uk Kim         return s->cert->conf_sigalgslen;
10637bded2dbSJung-uk Kim     } else {
10647bded2dbSJung-uk Kim         *psigs = tls12_sigalgs;
10657bded2dbSJung-uk Kim         return sizeof(tls12_sigalgs);
10667bded2dbSJung-uk Kim     }
10677bded2dbSJung-uk Kim }
10687bded2dbSJung-uk Kim 
10697bded2dbSJung-uk Kim /*
10707bded2dbSJung-uk Kim  * Check signature algorithm is consistent with sent supported signature
10717bded2dbSJung-uk Kim  * algorithms and if so return relevant digest.
10727bded2dbSJung-uk Kim  */
10737bded2dbSJung-uk Kim int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
10747bded2dbSJung-uk Kim                             const unsigned char *sig, EVP_PKEY *pkey)
10757bded2dbSJung-uk Kim {
10767bded2dbSJung-uk Kim     const unsigned char *sent_sigs;
10777bded2dbSJung-uk Kim     size_t sent_sigslen, i;
10787bded2dbSJung-uk Kim     int sigalg = tls12_get_sigid(pkey);
10797bded2dbSJung-uk Kim     /* Should never happen */
10807bded2dbSJung-uk Kim     if (sigalg == -1)
10817bded2dbSJung-uk Kim         return -1;
10827bded2dbSJung-uk Kim     /* Check key type is consistent with signature */
10837bded2dbSJung-uk Kim     if (sigalg != (int)sig[1]) {
10847bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
10857bded2dbSJung-uk Kim         return 0;
10867bded2dbSJung-uk Kim     }
10877bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
10887bded2dbSJung-uk Kim     if (pkey->type == EVP_PKEY_EC) {
10897bded2dbSJung-uk Kim         unsigned char curve_id[2], comp_id;
10907bded2dbSJung-uk Kim         /* Check compression and curve matches extensions */
10917bded2dbSJung-uk Kim         if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec))
10927bded2dbSJung-uk Kim             return 0;
10937bded2dbSJung-uk Kim         if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
10947bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
10957bded2dbSJung-uk Kim             return 0;
10967bded2dbSJung-uk Kim         }
10977bded2dbSJung-uk Kim         /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
10987bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
10997bded2dbSJung-uk Kim             if (curve_id[0])
11007bded2dbSJung-uk Kim                 return 0;
11017bded2dbSJung-uk Kim             if (curve_id[1] == TLSEXT_curve_P_256) {
11027bded2dbSJung-uk Kim                 if (sig[0] != TLSEXT_hash_sha256) {
11037bded2dbSJung-uk Kim                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
11047bded2dbSJung-uk Kim                            SSL_R_ILLEGAL_SUITEB_DIGEST);
11057bded2dbSJung-uk Kim                     return 0;
11067bded2dbSJung-uk Kim                 }
11077bded2dbSJung-uk Kim             } else if (curve_id[1] == TLSEXT_curve_P_384) {
11087bded2dbSJung-uk Kim                 if (sig[0] != TLSEXT_hash_sha384) {
11097bded2dbSJung-uk Kim                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
11107bded2dbSJung-uk Kim                            SSL_R_ILLEGAL_SUITEB_DIGEST);
11117bded2dbSJung-uk Kim                     return 0;
11127bded2dbSJung-uk Kim                 }
11137bded2dbSJung-uk Kim             } else
11147bded2dbSJung-uk Kim                 return 0;
11157bded2dbSJung-uk Kim         }
11167bded2dbSJung-uk Kim     } else if (tls1_suiteb(s))
11177bded2dbSJung-uk Kim         return 0;
11187bded2dbSJung-uk Kim # endif
11197bded2dbSJung-uk Kim 
11207bded2dbSJung-uk Kim     /* Check signature matches a type we sent */
11217bded2dbSJung-uk Kim     sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
11227bded2dbSJung-uk Kim     for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
11237bded2dbSJung-uk Kim         if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1])
11247bded2dbSJung-uk Kim             break;
11257bded2dbSJung-uk Kim     }
11267bded2dbSJung-uk Kim     /* Allow fallback to SHA1 if not strict mode */
11277bded2dbSJung-uk Kim     if (i == sent_sigslen
11287bded2dbSJung-uk Kim         && (sig[0] != TLSEXT_hash_sha1
11297bded2dbSJung-uk Kim             || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
11307bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
11317bded2dbSJung-uk Kim         return 0;
11327bded2dbSJung-uk Kim     }
11337bded2dbSJung-uk Kim     *pmd = tls12_get_hash(sig[0]);
11347bded2dbSJung-uk Kim     if (*pmd == NULL) {
11357bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
11367bded2dbSJung-uk Kim         return 0;
11377bded2dbSJung-uk Kim     }
11387bded2dbSJung-uk Kim     /*
11397bded2dbSJung-uk Kim      * Store the digest used so applications can retrieve it if they wish.
11407bded2dbSJung-uk Kim      */
11417bded2dbSJung-uk Kim     if (s->session && s->session->sess_cert)
11427bded2dbSJung-uk Kim         s->session->sess_cert->peer_key->digest = *pmd;
11437bded2dbSJung-uk Kim     return 1;
11447bded2dbSJung-uk Kim }
11457bded2dbSJung-uk Kim 
11467bded2dbSJung-uk Kim /*
11477bded2dbSJung-uk Kim  * Get a mask of disabled algorithms: an algorithm is disabled if it isn't
11487bded2dbSJung-uk Kim  * supported or doesn't appear in supported signature algorithms. Unlike
11497bded2dbSJung-uk Kim  * ssl_cipher_get_disabled this applies to a specific session and not global
11507bded2dbSJung-uk Kim  * settings.
11517bded2dbSJung-uk Kim  */
11527bded2dbSJung-uk Kim void ssl_set_client_disabled(SSL *s)
11537bded2dbSJung-uk Kim {
11547bded2dbSJung-uk Kim     CERT *c = s->cert;
11557bded2dbSJung-uk Kim     const unsigned char *sigalgs;
11567bded2dbSJung-uk Kim     size_t i, sigalgslen;
11577bded2dbSJung-uk Kim     int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
11587bded2dbSJung-uk Kim     c->mask_a = 0;
11597bded2dbSJung-uk Kim     c->mask_k = 0;
11607bded2dbSJung-uk Kim     /* Don't allow TLS 1.2 only ciphers if we don't suppport them */
11617bded2dbSJung-uk Kim     if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s))
11627bded2dbSJung-uk Kim         c->mask_ssl = SSL_TLSV1_2;
11637bded2dbSJung-uk Kim     else
11647bded2dbSJung-uk Kim         c->mask_ssl = 0;
11657bded2dbSJung-uk Kim     /*
11667bded2dbSJung-uk Kim      * Now go through all signature algorithms seeing if we support any for
11677bded2dbSJung-uk Kim      * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2.
11687bded2dbSJung-uk Kim      */
11697bded2dbSJung-uk Kim     sigalgslen = tls12_get_psigalgs(s, &sigalgs);
11707bded2dbSJung-uk Kim     for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
11717bded2dbSJung-uk Kim         switch (sigalgs[1]) {
11727bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA
11737bded2dbSJung-uk Kim         case TLSEXT_signature_rsa:
11747bded2dbSJung-uk Kim             have_rsa = 1;
11757bded2dbSJung-uk Kim             break;
11767bded2dbSJung-uk Kim # endif
11777bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA
11787bded2dbSJung-uk Kim         case TLSEXT_signature_dsa:
11797bded2dbSJung-uk Kim             have_dsa = 1;
11807bded2dbSJung-uk Kim             break;
11817bded2dbSJung-uk Kim # endif
11827bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
11837bded2dbSJung-uk Kim         case TLSEXT_signature_ecdsa:
11847bded2dbSJung-uk Kim             have_ecdsa = 1;
11857bded2dbSJung-uk Kim             break;
11867bded2dbSJung-uk Kim # endif
11877bded2dbSJung-uk Kim         }
11887bded2dbSJung-uk Kim     }
11897bded2dbSJung-uk Kim     /*
11907bded2dbSJung-uk Kim      * Disable auth and static DH if we don't include any appropriate
11917bded2dbSJung-uk Kim      * signature algorithms.
11927bded2dbSJung-uk Kim      */
11937bded2dbSJung-uk Kim     if (!have_rsa) {
11947bded2dbSJung-uk Kim         c->mask_a |= SSL_aRSA;
11957bded2dbSJung-uk Kim         c->mask_k |= SSL_kDHr | SSL_kECDHr;
11967bded2dbSJung-uk Kim     }
11977bded2dbSJung-uk Kim     if (!have_dsa) {
11987bded2dbSJung-uk Kim         c->mask_a |= SSL_aDSS;
11997bded2dbSJung-uk Kim         c->mask_k |= SSL_kDHd;
12007bded2dbSJung-uk Kim     }
12017bded2dbSJung-uk Kim     if (!have_ecdsa) {
12027bded2dbSJung-uk Kim         c->mask_a |= SSL_aECDSA;
12037bded2dbSJung-uk Kim         c->mask_k |= SSL_kECDHe;
12047bded2dbSJung-uk Kim     }
12057bded2dbSJung-uk Kim # ifndef OPENSSL_NO_KRB5
12067bded2dbSJung-uk Kim     if (!kssl_tgt_is_available(s->kssl_ctx)) {
12077bded2dbSJung-uk Kim         c->mask_a |= SSL_aKRB5;
12087bded2dbSJung-uk Kim         c->mask_k |= SSL_kKRB5;
12097bded2dbSJung-uk Kim     }
12107bded2dbSJung-uk Kim # endif
12117bded2dbSJung-uk Kim # ifndef OPENSSL_NO_PSK
12127bded2dbSJung-uk Kim     /* with PSK there must be client callback set */
12137bded2dbSJung-uk Kim     if (!s->psk_client_callback) {
12147bded2dbSJung-uk Kim         c->mask_a |= SSL_aPSK;
12157bded2dbSJung-uk Kim         c->mask_k |= SSL_kPSK;
12167bded2dbSJung-uk Kim     }
12177bded2dbSJung-uk Kim # endif                         /* OPENSSL_NO_PSK */
12187bded2dbSJung-uk Kim # ifndef OPENSSL_NO_SRP
12197bded2dbSJung-uk Kim     if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
12207bded2dbSJung-uk Kim         c->mask_a |= SSL_aSRP;
12217bded2dbSJung-uk Kim         c->mask_k |= SSL_kSRP;
12227bded2dbSJung-uk Kim     }
12237bded2dbSJung-uk Kim # endif
12247bded2dbSJung-uk Kim     c->valid = 1;
12251f13597dSJung-uk Kim }
12261f13597dSJung-uk Kim 
12276f9291ceSJung-uk Kim unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
12287bded2dbSJung-uk Kim                                           unsigned char *limit, int *al)
1229db522d3aSSimon L. B. Nielsen {
1230db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
1231a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
1232a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
12337bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
12347bded2dbSJung-uk Kim     /* See if we support any ECC ciphersuites */
12357bded2dbSJung-uk Kim     int using_ecc = 0;
12367bded2dbSJung-uk Kim     if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
12377bded2dbSJung-uk Kim         int i;
12387bded2dbSJung-uk Kim         unsigned long alg_k, alg_a;
12397bded2dbSJung-uk Kim         STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
12407bded2dbSJung-uk Kim 
12417bded2dbSJung-uk Kim         for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
12427bded2dbSJung-uk Kim             SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
12437bded2dbSJung-uk Kim 
12447bded2dbSJung-uk Kim             alg_k = c->algorithm_mkey;
12457bded2dbSJung-uk Kim             alg_a = c->algorithm_auth;
12467bded2dbSJung-uk Kim             if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)
12477bded2dbSJung-uk Kim                  || (alg_a & SSL_aECDSA))) {
12487bded2dbSJung-uk Kim                 using_ecc = 1;
12497bded2dbSJung-uk Kim                 break;
12507bded2dbSJung-uk Kim             }
12517bded2dbSJung-uk Kim         }
12527bded2dbSJung-uk Kim     }
12537bded2dbSJung-uk Kim # endif
1254db522d3aSSimon L. B. Nielsen 
12556a599222SSimon L. B. Nielsen     /* don't add extensions for SSLv3 unless doing secure renegotiation */
12566f9291ceSJung-uk Kim     if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding)
1257a93cbc2bSJung-uk Kim         return orig;
12586a599222SSimon L. B. Nielsen 
1259db522d3aSSimon L. B. Nielsen     ret += 2;
1260db522d3aSSimon L. B. Nielsen 
12616f9291ceSJung-uk Kim     if (ret >= limit)
12626f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
1263db522d3aSSimon L. B. Nielsen 
12646f9291ceSJung-uk Kim     if (s->tlsext_hostname != NULL) {
1265db522d3aSSimon L. B. Nielsen         /* Add TLS extension servername to the Client Hello message */
1266db522d3aSSimon L. B. Nielsen         unsigned long size_str;
1267db522d3aSSimon L. B. Nielsen         long lenmax;
1268db522d3aSSimon L. B. Nielsen 
12696f9291ceSJung-uk Kim         /*-
12706f9291ceSJung-uk Kim          * check for enough space.
12716f9291ceSJung-uk Kim          * 4 for the servername type and entension length
12726f9291ceSJung-uk Kim          * 2 for servernamelist length
12736f9291ceSJung-uk Kim          * 1 for the hostname type
12746f9291ceSJung-uk Kim          * 2 for hostname length
12756f9291ceSJung-uk Kim          * + hostname length
1276db522d3aSSimon L. B. Nielsen          */
1277db522d3aSSimon L. B. Nielsen 
1278db522d3aSSimon L. B. Nielsen         if ((lenmax = limit - ret - 9) < 0
12796f9291ceSJung-uk Kim             || (size_str =
12806f9291ceSJung-uk Kim                 strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
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 
13241f13597dSJung-uk Kim         int 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          */
13366f9291ceSJung-uk Kim         if ((limit - ret - 5 - login_len) < 0)
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          */
13531f13597dSJung-uk Kim         long lenmax;
13547bded2dbSJung-uk Kim         const unsigned char *pcurves, *pformats;
13557bded2dbSJung-uk Kim         size_t num_curves, num_formats, curves_list_len;
13567bded2dbSJung-uk Kim 
13577bded2dbSJung-uk Kim         tls1_get_formatlist(s, &pformats, &num_formats);
13581f13597dSJung-uk Kim 
13596f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 5) < 0)
13606f9291ceSJung-uk Kim             return NULL;
13617bded2dbSJung-uk Kim         if (num_formats > (size_t)lenmax)
13626f9291ceSJung-uk Kim             return NULL;
13637bded2dbSJung-uk Kim         if (num_formats > 255) {
13641f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13651f13597dSJung-uk Kim             return NULL;
13661f13597dSJung-uk Kim         }
13671f13597dSJung-uk Kim 
13681f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
13697bded2dbSJung-uk Kim         /* The point format list has 1-byte length. */
13707bded2dbSJung-uk Kim         s2n(num_formats + 1, ret);
13717bded2dbSJung-uk Kim         *(ret++) = (unsigned char)num_formats;
13727bded2dbSJung-uk Kim         memcpy(ret, pformats, num_formats);
13737bded2dbSJung-uk Kim         ret += num_formats;
13747bded2dbSJung-uk Kim 
13756f9291ceSJung-uk Kim         /*
13766f9291ceSJung-uk Kim          * Add TLS extension EllipticCurves to the ClientHello message
13776f9291ceSJung-uk Kim          */
13787bded2dbSJung-uk Kim         pcurves = s->tlsext_ellipticcurvelist;
13797bded2dbSJung-uk Kim         if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
13807bded2dbSJung-uk Kim             return NULL;
13811f13597dSJung-uk Kim 
13826f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 6) < 0)
13836f9291ceSJung-uk Kim             return NULL;
13847bded2dbSJung-uk Kim         if (num_curves > (size_t)lenmax / 2)
13856f9291ceSJung-uk Kim             return NULL;
13867bded2dbSJung-uk Kim         if (num_curves > 65532 / 2) {
13871f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
13881f13597dSJung-uk Kim             return NULL;
13891f13597dSJung-uk Kim         }
13907bded2dbSJung-uk Kim         curves_list_len = 2 * num_curves;
13911f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_elliptic_curves, ret);
13927bded2dbSJung-uk Kim         s2n(curves_list_len + 2, ret);
13937bded2dbSJung-uk Kim         s2n(curves_list_len, ret);
13947bded2dbSJung-uk Kim         memcpy(ret, pcurves, curves_list_len);
13957bded2dbSJung-uk Kim         ret += curves_list_len;
13961f13597dSJung-uk Kim     }
13971f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
13986a599222SSimon L. B. Nielsen 
13996f9291ceSJung-uk Kim     if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
1400db522d3aSSimon L. B. Nielsen         int ticklen;
14016a599222SSimon L. B. Nielsen         if (!s->new_session && s->session && s->session->tlsext_tick)
1402db522d3aSSimon L. B. Nielsen             ticklen = s->session->tlsext_ticklen;
14031f13597dSJung-uk Kim         else if (s->session && s->tlsext_session_ticket &&
14046f9291ceSJung-uk Kim                  s->tlsext_session_ticket->data) {
14051f13597dSJung-uk Kim             ticklen = s->tlsext_session_ticket->length;
14061f13597dSJung-uk Kim             s->session->tlsext_tick = OPENSSL_malloc(ticklen);
14071f13597dSJung-uk Kim             if (!s->session->tlsext_tick)
14081f13597dSJung-uk Kim                 return NULL;
14091f13597dSJung-uk Kim             memcpy(s->session->tlsext_tick,
14106f9291ceSJung-uk Kim                    s->tlsext_session_ticket->data, ticklen);
14111f13597dSJung-uk Kim             s->session->tlsext_ticklen = ticklen;
14126f9291ceSJung-uk Kim         } else
1413db522d3aSSimon L. B. Nielsen             ticklen = 0;
14141f13597dSJung-uk Kim         if (ticklen == 0 && s->tlsext_session_ticket &&
14151f13597dSJung-uk Kim             s->tlsext_session_ticket->data == NULL)
14161f13597dSJung-uk Kim             goto skip_ext;
14176f9291ceSJung-uk Kim         /*
14186f9291ceSJung-uk Kim          * Check for enough room 2 for extension type, 2 for len rest for
14196f9291ceSJung-uk Kim          * ticket
1420db522d3aSSimon L. B. Nielsen          */
14216f9291ceSJung-uk Kim         if ((long)(limit - ret - 4 - ticklen) < 0)
14226f9291ceSJung-uk Kim             return NULL;
1423db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
1424db522d3aSSimon L. B. Nielsen         s2n(ticklen, ret);
14256f9291ceSJung-uk Kim         if (ticklen) {
1426db522d3aSSimon L. B. Nielsen             memcpy(ret, s->session->tlsext_tick, ticklen);
1427db522d3aSSimon L. B. Nielsen             ret += ticklen;
1428db522d3aSSimon L. B. Nielsen         }
1429db522d3aSSimon L. B. Nielsen     }
14301f13597dSJung-uk Kim  skip_ext:
14311f13597dSJung-uk Kim 
1432*aeb5019cSJung-uk Kim     if (SSL_CLIENT_USE_SIGALGS(s)) {
14337bded2dbSJung-uk Kim         size_t salglen;
14347bded2dbSJung-uk Kim         const unsigned char *salg;
14357bded2dbSJung-uk Kim         salglen = tls12_get_psigalgs(s, &salg);
14367bded2dbSJung-uk Kim         if ((size_t)(limit - ret) < salglen + 6)
14371f13597dSJung-uk Kim             return NULL;
14381f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_signature_algorithms, ret);
14397bded2dbSJung-uk Kim         s2n(salglen + 2, ret);
14407bded2dbSJung-uk Kim         s2n(salglen, ret);
14417bded2dbSJung-uk Kim         memcpy(ret, salg, salglen);
14427bded2dbSJung-uk Kim         ret += salglen;
14431f13597dSJung-uk Kim     }
14441f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
14457bded2dbSJung-uk Kim     if (s->s3->client_opaque_prf_input != NULL) {
14461f13597dSJung-uk Kim         size_t col = s->s3->client_opaque_prf_input_len;
14471f13597dSJung-uk Kim 
14481f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - col < 0))
14491f13597dSJung-uk Kim             return NULL;
14501f13597dSJung-uk Kim         if (col > 0xFFFD)       /* can't happen */
14511f13597dSJung-uk Kim             return NULL;
14521f13597dSJung-uk Kim 
14531f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
14541f13597dSJung-uk Kim         s2n(col + 2, ret);
14551f13597dSJung-uk Kim         s2n(col, ret);
14561f13597dSJung-uk Kim         memcpy(ret, s->s3->client_opaque_prf_input, col);
14571f13597dSJung-uk Kim         ret += col;
14581f13597dSJung-uk Kim     }
14591f13597dSJung-uk Kim # endif
1460db522d3aSSimon L. B. Nielsen 
14617bded2dbSJung-uk Kim     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
1462db522d3aSSimon L. B. Nielsen         int i;
1463db522d3aSSimon L. B. Nielsen         long extlen, idlen, itmp;
1464db522d3aSSimon L. B. Nielsen         OCSP_RESPID *id;
1465db522d3aSSimon L. B. Nielsen 
1466db522d3aSSimon L. B. Nielsen         idlen = 0;
14676f9291ceSJung-uk Kim         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
1468db522d3aSSimon L. B. Nielsen             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
1469db522d3aSSimon L. B. Nielsen             itmp = i2d_OCSP_RESPID(id, NULL);
1470db522d3aSSimon L. B. Nielsen             if (itmp <= 0)
1471db522d3aSSimon L. B. Nielsen                 return NULL;
1472db522d3aSSimon L. B. Nielsen             idlen += itmp + 2;
1473db522d3aSSimon L. B. Nielsen         }
1474db522d3aSSimon L. B. Nielsen 
14756f9291ceSJung-uk Kim         if (s->tlsext_ocsp_exts) {
1476db522d3aSSimon L. B. Nielsen             extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
1477db522d3aSSimon L. B. Nielsen             if (extlen < 0)
1478db522d3aSSimon L. B. Nielsen                 return NULL;
14796f9291ceSJung-uk Kim         } else
1480db522d3aSSimon L. B. Nielsen             extlen = 0;
1481db522d3aSSimon L. B. Nielsen 
14826f9291ceSJung-uk Kim         if ((long)(limit - ret - 7 - extlen - idlen) < 0)
14836f9291ceSJung-uk Kim             return NULL;
1484db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_status_request, ret);
1485db522d3aSSimon L. B. Nielsen         if (extlen + idlen > 0xFFF0)
1486db522d3aSSimon L. B. Nielsen             return NULL;
1487db522d3aSSimon L. B. Nielsen         s2n(extlen + idlen + 5, ret);
1488db522d3aSSimon L. B. Nielsen         *(ret++) = TLSEXT_STATUSTYPE_ocsp;
1489db522d3aSSimon L. B. Nielsen         s2n(idlen, ret);
14906f9291ceSJung-uk Kim         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
1491db522d3aSSimon L. B. Nielsen             /* save position of id len */
1492db522d3aSSimon L. B. Nielsen             unsigned char *q = ret;
1493db522d3aSSimon L. B. Nielsen             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
1494db522d3aSSimon L. B. Nielsen             /* skip over id len */
1495db522d3aSSimon L. B. Nielsen             ret += 2;
1496db522d3aSSimon L. B. Nielsen             itmp = i2d_OCSP_RESPID(id, &ret);
1497db522d3aSSimon L. B. Nielsen             /* write id len */
1498db522d3aSSimon L. B. Nielsen             s2n(itmp, q);
1499db522d3aSSimon L. B. Nielsen         }
1500db522d3aSSimon L. B. Nielsen         s2n(extlen, ret);
1501db522d3aSSimon L. B. Nielsen         if (extlen > 0)
1502db522d3aSSimon L. B. Nielsen             i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
1503db522d3aSSimon L. B. Nielsen     }
15041f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
15051f13597dSJung-uk Kim     /* Add Heartbeat extension */
150694ad176cSJung-uk Kim     if ((limit - ret - 4 - 1) < 0)
150794ad176cSJung-uk Kim         return NULL;
15081f13597dSJung-uk Kim     s2n(TLSEXT_TYPE_heartbeat, ret);
15091f13597dSJung-uk Kim     s2n(1, ret);
15106f9291ceSJung-uk Kim     /*-
15116f9291ceSJung-uk Kim      * Set mode:
15121f13597dSJung-uk Kim      * 1: peer may send requests
15131f13597dSJung-uk Kim      * 2: peer not allowed to send requests
15141f13597dSJung-uk Kim      */
15151f13597dSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
15161f13597dSJung-uk Kim         *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
15171f13597dSJung-uk Kim     else
15181f13597dSJung-uk Kim         *(ret++) = SSL_TLSEXT_HB_ENABLED;
15191f13597dSJung-uk Kim # endif
15201f13597dSJung-uk Kim 
15211f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
15226f9291ceSJung-uk Kim     if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
15236f9291ceSJung-uk Kim         /*
15246f9291ceSJung-uk Kim          * The client advertises an emtpy extension to indicate its support
15256f9291ceSJung-uk Kim          * for Next Protocol Negotiation
15266f9291ceSJung-uk Kim          */
15271f13597dSJung-uk Kim         if (limit - ret - 4 < 0)
15281f13597dSJung-uk Kim             return NULL;
15291f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_next_proto_neg, ret);
15301f13597dSJung-uk Kim         s2n(0, ret);
15311f13597dSJung-uk Kim     }
15321f13597dSJung-uk Kim # endif
15331f13597dSJung-uk Kim 
15347bded2dbSJung-uk Kim     if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
15357bded2dbSJung-uk Kim         if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
15367bded2dbSJung-uk Kim             return NULL;
15377bded2dbSJung-uk Kim         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
15387bded2dbSJung-uk Kim         s2n(2 + s->alpn_client_proto_list_len, ret);
15397bded2dbSJung-uk Kim         s2n(s->alpn_client_proto_list_len, ret);
15407bded2dbSJung-uk Kim         memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
15417bded2dbSJung-uk Kim         ret += s->alpn_client_proto_list_len;
1542b8721c16SJung-uk Kim         s->cert->alpn_sent = 1;
15437bded2dbSJung-uk Kim     }
154409286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
15456f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
15461f13597dSJung-uk Kim         int el;
15471f13597dSJung-uk Kim 
15481f13597dSJung-uk Kim         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
15491f13597dSJung-uk Kim 
15506f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
15516f9291ceSJung-uk Kim             return NULL;
15521f13597dSJung-uk Kim 
15531f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
15541f13597dSJung-uk Kim         s2n(el, ret);
15551f13597dSJung-uk Kim 
15566f9291ceSJung-uk Kim         if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
15571f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
15581f13597dSJung-uk Kim             return NULL;
15591f13597dSJung-uk Kim         }
15601f13597dSJung-uk Kim         ret += el;
15611f13597dSJung-uk Kim     }
156209286989SJung-uk Kim # endif
15637bded2dbSJung-uk Kim     custom_ext_init(&s->cert->cli_ext);
15647bded2dbSJung-uk Kim     /* Add custom TLS Extensions to ClientHello */
15657bded2dbSJung-uk Kim     if (!custom_ext_add(s, 0, &ret, limit, al))
15667bded2dbSJung-uk Kim         return NULL;
15677bded2dbSJung-uk Kim 
15686f9291ceSJung-uk Kim     /*
15696f9291ceSJung-uk Kim      * Add padding to workaround bugs in F5 terminators. See
15706f9291ceSJung-uk Kim      * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
15716f9291ceSJung-uk Kim      * code works out the length of all existing extensions it MUST always
15726f9291ceSJung-uk Kim      * appear last.
1573560ede85SJung-uk Kim      */
15746f9291ceSJung-uk Kim     if (s->options & SSL_OP_TLSEXT_PADDING) {
1575560ede85SJung-uk Kim         int hlen = ret - (unsigned char *)s->init_buf->data;
15766f9291ceSJung-uk Kim         /*
15776f9291ceSJung-uk Kim          * The code in s23_clnt.c to build ClientHello messages includes the
15786f9291ceSJung-uk Kim          * 5-byte record header in the buffer, while the code in s3_clnt.c
15796f9291ceSJung-uk Kim          * does not.
158094ad176cSJung-uk Kim          */
1581560ede85SJung-uk Kim         if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
1582560ede85SJung-uk Kim             hlen -= 5;
15836f9291ceSJung-uk Kim         if (hlen > 0xff && hlen < 0x200) {
1584560ede85SJung-uk Kim             hlen = 0x200 - hlen;
1585560ede85SJung-uk Kim             if (hlen >= 4)
1586560ede85SJung-uk Kim                 hlen -= 4;
1587560ede85SJung-uk Kim             else
1588560ede85SJung-uk Kim                 hlen = 0;
1589560ede85SJung-uk Kim 
1590560ede85SJung-uk Kim             s2n(TLSEXT_TYPE_padding, ret);
1591560ede85SJung-uk Kim             s2n(hlen, ret);
1592560ede85SJung-uk Kim             memset(ret, 0, hlen);
1593560ede85SJung-uk Kim             ret += hlen;
1594560ede85SJung-uk Kim         }
1595560ede85SJung-uk Kim     }
1596560ede85SJung-uk Kim 
1597a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
1598a93cbc2bSJung-uk Kim         return orig;
1599db522d3aSSimon L. B. Nielsen 
1600a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
1601db522d3aSSimon L. B. Nielsen     return ret;
1602db522d3aSSimon L. B. Nielsen }
1603db522d3aSSimon L. B. Nielsen 
16046f9291ceSJung-uk Kim unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
16057bded2dbSJung-uk Kim                                           unsigned char *limit, int *al)
1606db522d3aSSimon L. B. Nielsen {
1607db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
1608a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
1609a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
16101f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
16111f13597dSJung-uk Kim     int next_proto_neg_seen;
16121f13597dSJung-uk Kim # endif
16137bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
16147bded2dbSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
16157bded2dbSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
16167bded2dbSJung-uk Kim     int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
16177bded2dbSJung-uk Kim         || (alg_a & SSL_aECDSA);
16187bded2dbSJung-uk Kim     using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
16197bded2dbSJung-uk Kim # endif
16206f9291ceSJung-uk Kim     /*
16216f9291ceSJung-uk Kim      * don't add extensions for SSLv3, unless doing secure renegotiation
16226f9291ceSJung-uk Kim      */
16236a599222SSimon L. B. Nielsen     if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
1624a93cbc2bSJung-uk Kim         return orig;
16256a599222SSimon L. B. Nielsen 
1626db522d3aSSimon L. B. Nielsen     ret += 2;
16276f9291ceSJung-uk Kim     if (ret >= limit)
16286f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
1629db522d3aSSimon L. B. Nielsen 
16306f9291ceSJung-uk Kim     if (!s->hit && s->servername_done == 1
16316f9291ceSJung-uk Kim         && s->session->tlsext_hostname != NULL) {
16326f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
16336f9291ceSJung-uk Kim             return NULL;
1634db522d3aSSimon L. B. Nielsen 
1635db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_server_name, ret);
1636db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1637db522d3aSSimon L. B. Nielsen     }
1638db522d3aSSimon L. B. Nielsen 
16396f9291ceSJung-uk Kim     if (s->s3->send_connection_binding) {
16406a599222SSimon L. B. Nielsen         int el;
16416a599222SSimon L. B. Nielsen 
16426f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
16436a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16446a599222SSimon L. B. Nielsen             return NULL;
16456a599222SSimon L. B. Nielsen         }
16466a599222SSimon L. B. Nielsen 
16476f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
16486f9291ceSJung-uk Kim             return NULL;
16496a599222SSimon L. B. Nielsen 
16506a599222SSimon L. B. Nielsen         s2n(TLSEXT_TYPE_renegotiate, ret);
16516a599222SSimon L. B. Nielsen         s2n(el, ret);
16526a599222SSimon L. B. Nielsen 
16536f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
16546a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16556a599222SSimon L. B. Nielsen             return NULL;
16566a599222SSimon L. B. Nielsen         }
16576a599222SSimon L. B. Nielsen 
16586a599222SSimon L. B. Nielsen         ret += el;
16596a599222SSimon L. B. Nielsen     }
16601f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
16617bded2dbSJung-uk Kim     if (using_ecc) {
16627bded2dbSJung-uk Kim         const unsigned char *plist;
16637bded2dbSJung-uk Kim         size_t plistlen;
16646f9291ceSJung-uk Kim         /*
16656f9291ceSJung-uk Kim          * Add TLS extension ECPointFormats to the ServerHello message
16666f9291ceSJung-uk Kim          */
16671f13597dSJung-uk Kim         long lenmax;
16681f13597dSJung-uk Kim 
16697bded2dbSJung-uk Kim         tls1_get_formatlist(s, &plist, &plistlen);
16707bded2dbSJung-uk Kim 
16716f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 5) < 0)
16726f9291ceSJung-uk Kim             return NULL;
16737bded2dbSJung-uk Kim         if (plistlen > (size_t)lenmax)
16746f9291ceSJung-uk Kim             return NULL;
16757bded2dbSJung-uk Kim         if (plistlen > 255) {
16761f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16771f13597dSJung-uk Kim             return NULL;
16781f13597dSJung-uk Kim         }
16791f13597dSJung-uk Kim 
16801f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
16817bded2dbSJung-uk Kim         s2n(plistlen + 1, ret);
16827bded2dbSJung-uk Kim         *(ret++) = (unsigned char)plistlen;
16837bded2dbSJung-uk Kim         memcpy(ret, plist, plistlen);
16847bded2dbSJung-uk Kim         ret += plistlen;
16851f13597dSJung-uk Kim 
16861f13597dSJung-uk Kim     }
16876f9291ceSJung-uk Kim     /*
16886f9291ceSJung-uk Kim      * Currently the server should not respond with a SupportedCurves
16896f9291ceSJung-uk Kim      * extension
16906f9291ceSJung-uk Kim      */
16911f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
16921f13597dSJung-uk Kim 
16936f9291ceSJung-uk Kim     if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
16946f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
16956f9291ceSJung-uk Kim             return NULL;
1696db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
1697db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1698db522d3aSSimon L. B. Nielsen     }
1699db522d3aSSimon L. B. Nielsen 
17006f9291ceSJung-uk Kim     if (s->tlsext_status_expected) {
17016f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
17026f9291ceSJung-uk Kim             return NULL;
1703db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_status_request, ret);
1704db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1705db522d3aSSimon L. B. Nielsen     }
17061f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
17077bded2dbSJung-uk Kim     if (s->s3->server_opaque_prf_input != NULL) {
17081f13597dSJung-uk Kim         size_t sol = s->s3->server_opaque_prf_input_len;
17091f13597dSJung-uk Kim 
17101f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - sol) < 0)
17111f13597dSJung-uk Kim             return NULL;
17121f13597dSJung-uk Kim         if (sol > 0xFFFD)       /* can't happen */
17131f13597dSJung-uk Kim             return NULL;
17141f13597dSJung-uk Kim 
17151f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
17161f13597dSJung-uk Kim         s2n(sol + 2, ret);
17171f13597dSJung-uk Kim         s2n(sol, ret);
17181f13597dSJung-uk Kim         memcpy(ret, s->s3->server_opaque_prf_input, sol);
17191f13597dSJung-uk Kim         ret += sol;
17201f13597dSJung-uk Kim     }
17211f13597dSJung-uk Kim # endif
17221f13597dSJung-uk Kim 
172309286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
17246f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && s->srtp_profile) {
17251f13597dSJung-uk Kim         int el;
17261f13597dSJung-uk Kim 
17271f13597dSJung-uk Kim         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
17281f13597dSJung-uk Kim 
17296f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
17306f9291ceSJung-uk Kim             return NULL;
17311f13597dSJung-uk Kim 
17321f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
17331f13597dSJung-uk Kim         s2n(el, ret);
17341f13597dSJung-uk Kim 
17356f9291ceSJung-uk Kim         if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
17361f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
17371f13597dSJung-uk Kim             return NULL;
17381f13597dSJung-uk Kim         }
17391f13597dSJung-uk Kim         ret += el;
17401f13597dSJung-uk Kim     }
174109286989SJung-uk Kim # endif
17421f13597dSJung-uk Kim 
17436f9291ceSJung-uk Kim     if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
17446f9291ceSJung-uk Kim          || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
17456f9291ceSJung-uk Kim         && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
17466f9291ceSJung-uk Kim         const unsigned char cryptopro_ext[36] = {
17471f13597dSJung-uk Kim             0xfd, 0xe8,         /* 65000 */
17481f13597dSJung-uk Kim             0x00, 0x20,         /* 32 bytes length */
17491f13597dSJung-uk Kim             0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
17501f13597dSJung-uk Kim             0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
17511f13597dSJung-uk Kim             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
17526f9291ceSJung-uk Kim             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
17536f9291ceSJung-uk Kim         };
17546f9291ceSJung-uk Kim         if (limit - ret < 36)
17556f9291ceSJung-uk Kim             return NULL;
17561f13597dSJung-uk Kim         memcpy(ret, cryptopro_ext, 36);
17571f13597dSJung-uk Kim         ret += 36;
17581f13597dSJung-uk Kim 
17591f13597dSJung-uk Kim     }
17601f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
17611f13597dSJung-uk Kim     /* Add Heartbeat extension if we've received one */
17626f9291ceSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
176394ad176cSJung-uk Kim         if ((limit - ret - 4 - 1) < 0)
176494ad176cSJung-uk Kim             return NULL;
17651f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_heartbeat, ret);
17661f13597dSJung-uk Kim         s2n(1, ret);
17676f9291ceSJung-uk Kim         /*-
17686f9291ceSJung-uk Kim          * Set mode:
17691f13597dSJung-uk Kim          * 1: peer may send requests
17701f13597dSJung-uk Kim          * 2: peer not allowed to send requests
17711f13597dSJung-uk Kim          */
17721f13597dSJung-uk Kim         if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
17731f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
17741f13597dSJung-uk Kim         else
17751f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_ENABLED;
17761f13597dSJung-uk Kim 
17771f13597dSJung-uk Kim     }
17781f13597dSJung-uk Kim # endif
17791f13597dSJung-uk Kim 
17801f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
17811f13597dSJung-uk Kim     next_proto_neg_seen = s->s3->next_proto_neg_seen;
17821f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
17836f9291ceSJung-uk Kim     if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
17841f13597dSJung-uk Kim         const unsigned char *npa;
17851f13597dSJung-uk Kim         unsigned int npalen;
17861f13597dSJung-uk Kim         int r;
17871f13597dSJung-uk Kim 
17886f9291ceSJung-uk Kim         r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
17896f9291ceSJung-uk Kim                                               s->
17906f9291ceSJung-uk Kim                                               ctx->next_protos_advertised_cb_arg);
17916f9291ceSJung-uk Kim         if (r == SSL_TLSEXT_ERR_OK) {
17926f9291ceSJung-uk Kim             if ((long)(limit - ret - 4 - npalen) < 0)
17936f9291ceSJung-uk Kim                 return NULL;
17941f13597dSJung-uk Kim             s2n(TLSEXT_TYPE_next_proto_neg, ret);
17951f13597dSJung-uk Kim             s2n(npalen, ret);
17961f13597dSJung-uk Kim             memcpy(ret, npa, npalen);
17971f13597dSJung-uk Kim             ret += npalen;
17981f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
17991f13597dSJung-uk Kim         }
18001f13597dSJung-uk Kim     }
18011f13597dSJung-uk Kim # endif
18027bded2dbSJung-uk Kim     if (!custom_ext_add(s, 1, &ret, limit, al))
18037bded2dbSJung-uk Kim         return NULL;
18047bded2dbSJung-uk Kim 
18057bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
18067bded2dbSJung-uk Kim         const unsigned char *selected = s->s3->alpn_selected;
18077bded2dbSJung-uk Kim         unsigned len = s->s3->alpn_selected_len;
18087bded2dbSJung-uk Kim 
18097bded2dbSJung-uk Kim         if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
18107bded2dbSJung-uk Kim             return NULL;
18117bded2dbSJung-uk Kim         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
18127bded2dbSJung-uk Kim         s2n(3 + len, ret);
18137bded2dbSJung-uk Kim         s2n(1 + len, ret);
18147bded2dbSJung-uk Kim         *ret++ = len;
18157bded2dbSJung-uk Kim         memcpy(ret, selected, len);
18167bded2dbSJung-uk Kim         ret += len;
18177bded2dbSJung-uk Kim     }
18181f13597dSJung-uk Kim 
1819a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
1820a93cbc2bSJung-uk Kim         return orig;
1821db522d3aSSimon L. B. Nielsen 
1822a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
1823db522d3aSSimon L. B. Nielsen     return ret;
1824db522d3aSSimon L. B. Nielsen }
1825db522d3aSSimon L. B. Nielsen 
1826de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
18276f9291ceSJung-uk Kim /*-
18286f9291ceSJung-uk Kim  * ssl_check_for_safari attempts to fingerprint Safari using OS X
1829de78d5d8SJung-uk Kim  * SecureTransport using the TLS extension block in |d|, of length |n|.
1830de78d5d8SJung-uk Kim  * Safari, since 10.6, sends exactly these extensions, in this order:
1831de78d5d8SJung-uk Kim  *   SNI,
1832de78d5d8SJung-uk Kim  *   elliptic_curves
1833de78d5d8SJung-uk Kim  *   ec_point_formats
1834de78d5d8SJung-uk Kim  *
1835de78d5d8SJung-uk Kim  * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
1836de78d5d8SJung-uk Kim  * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
1837de78d5d8SJung-uk Kim  * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
1838de78d5d8SJung-uk Kim  * 10.8..10.8.3 (which don't work).
1839de78d5d8SJung-uk Kim  */
18406f9291ceSJung-uk Kim static void ssl_check_for_safari(SSL *s, const unsigned char *data,
184180815a77SJung-uk Kim                                  const unsigned char *limit)
18426f9291ceSJung-uk Kim {
1843de78d5d8SJung-uk Kim     unsigned short type, size;
1844de78d5d8SJung-uk Kim     static const unsigned char kSafariExtensionsBlock[] = {
1845de78d5d8SJung-uk Kim         0x00, 0x0a,             /* elliptic_curves extension */
1846de78d5d8SJung-uk Kim         0x00, 0x08,             /* 8 bytes */
1847de78d5d8SJung-uk Kim         0x00, 0x06,             /* 6 bytes of curve ids */
1848de78d5d8SJung-uk Kim         0x00, 0x17,             /* P-256 */
1849de78d5d8SJung-uk Kim         0x00, 0x18,             /* P-384 */
1850de78d5d8SJung-uk Kim         0x00, 0x19,             /* P-521 */
1851de78d5d8SJung-uk Kim 
1852de78d5d8SJung-uk Kim         0x00, 0x0b,             /* ec_point_formats */
1853de78d5d8SJung-uk Kim         0x00, 0x02,             /* 2 bytes */
1854de78d5d8SJung-uk Kim         0x01,                   /* 1 point format */
1855de78d5d8SJung-uk Kim         0x00,                   /* uncompressed */
1856de78d5d8SJung-uk Kim     };
1857de78d5d8SJung-uk Kim 
1858de78d5d8SJung-uk Kim     /* The following is only present in TLS 1.2 */
1859de78d5d8SJung-uk Kim     static const unsigned char kSafariTLS12ExtensionsBlock[] = {
1860de78d5d8SJung-uk Kim         0x00, 0x0d,             /* signature_algorithms */
1861de78d5d8SJung-uk Kim         0x00, 0x0c,             /* 12 bytes */
1862de78d5d8SJung-uk Kim         0x00, 0x0a,             /* 10 bytes */
1863de78d5d8SJung-uk Kim         0x05, 0x01,             /* SHA-384/RSA */
1864de78d5d8SJung-uk Kim         0x04, 0x01,             /* SHA-256/RSA */
1865de78d5d8SJung-uk Kim         0x02, 0x01,             /* SHA-1/RSA */
1866de78d5d8SJung-uk Kim         0x04, 0x03,             /* SHA-256/ECDSA */
1867de78d5d8SJung-uk Kim         0x02, 0x03,             /* SHA-1/ECDSA */
1868de78d5d8SJung-uk Kim     };
1869de78d5d8SJung-uk Kim 
1870*aeb5019cSJung-uk Kim     if (limit - data <= 2)
1871de78d5d8SJung-uk Kim         return;
1872de78d5d8SJung-uk Kim     data += 2;
1873de78d5d8SJung-uk Kim 
1874*aeb5019cSJung-uk Kim     if (limit - data < 4)
1875de78d5d8SJung-uk Kim         return;
1876de78d5d8SJung-uk Kim     n2s(data, type);
1877de78d5d8SJung-uk Kim     n2s(data, size);
1878de78d5d8SJung-uk Kim 
1879de78d5d8SJung-uk Kim     if (type != TLSEXT_TYPE_server_name)
1880de78d5d8SJung-uk Kim         return;
1881de78d5d8SJung-uk Kim 
1882*aeb5019cSJung-uk Kim     if (limit - data < size)
1883de78d5d8SJung-uk Kim         return;
1884de78d5d8SJung-uk Kim     data += size;
1885de78d5d8SJung-uk Kim 
18866f9291ceSJung-uk Kim     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
1887de78d5d8SJung-uk Kim         const size_t len1 = sizeof(kSafariExtensionsBlock);
1888de78d5d8SJung-uk Kim         const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
1889de78d5d8SJung-uk Kim 
1890*aeb5019cSJung-uk Kim         if (limit - data != (int)(len1 + len2))
1891de78d5d8SJung-uk Kim             return;
1892de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
1893de78d5d8SJung-uk Kim             return;
1894de78d5d8SJung-uk Kim         if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
1895de78d5d8SJung-uk Kim             return;
18966f9291ceSJung-uk Kim     } else {
1897de78d5d8SJung-uk Kim         const size_t len = sizeof(kSafariExtensionsBlock);
1898de78d5d8SJung-uk Kim 
1899*aeb5019cSJung-uk Kim         if (limit - data != (int)(len))
1900de78d5d8SJung-uk Kim             return;
1901de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len) != 0)
1902de78d5d8SJung-uk Kim             return;
1903de78d5d8SJung-uk Kim     }
1904de78d5d8SJung-uk Kim 
1905de78d5d8SJung-uk Kim     s->s3->is_probably_safari = 1;
1906de78d5d8SJung-uk Kim }
1907de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
1908de78d5d8SJung-uk Kim 
19097bded2dbSJung-uk Kim /*
1910b8721c16SJung-uk Kim  * tls1_alpn_handle_client_hello is called to save the ALPN extension in a
19117bded2dbSJung-uk Kim  * ClientHello.  data: the contents of the extension, not including the type
19127bded2dbSJung-uk Kim  * and length.  data_len: the number of bytes in |data| al: a pointer to the
19137bded2dbSJung-uk Kim  * alert value to send in the event of a non-zero return.  returns: 0 on
19147bded2dbSJung-uk Kim  * success.
19157bded2dbSJung-uk Kim  */
19167bded2dbSJung-uk Kim static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
19177bded2dbSJung-uk Kim                                          unsigned data_len, int *al)
19187bded2dbSJung-uk Kim {
19197bded2dbSJung-uk Kim     unsigned i;
19207bded2dbSJung-uk Kim     unsigned proto_len;
19217bded2dbSJung-uk Kim 
19227bded2dbSJung-uk Kim     if (data_len < 2)
19237bded2dbSJung-uk Kim         goto parse_error;
19247bded2dbSJung-uk Kim 
19257bded2dbSJung-uk Kim     /*
19267bded2dbSJung-uk Kim      * data should contain a uint16 length followed by a series of 8-bit,
19277bded2dbSJung-uk Kim      * length-prefixed strings.
19287bded2dbSJung-uk Kim      */
19297bded2dbSJung-uk Kim     i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]);
19307bded2dbSJung-uk Kim     data_len -= 2;
19317bded2dbSJung-uk Kim     data += 2;
19327bded2dbSJung-uk Kim     if (data_len != i)
19337bded2dbSJung-uk Kim         goto parse_error;
19347bded2dbSJung-uk Kim 
19357bded2dbSJung-uk Kim     if (data_len < 2)
19367bded2dbSJung-uk Kim         goto parse_error;
19377bded2dbSJung-uk Kim 
19387bded2dbSJung-uk Kim     for (i = 0; i < data_len;) {
19397bded2dbSJung-uk Kim         proto_len = data[i];
19407bded2dbSJung-uk Kim         i++;
19417bded2dbSJung-uk Kim 
19427bded2dbSJung-uk Kim         if (proto_len == 0)
19437bded2dbSJung-uk Kim             goto parse_error;
19447bded2dbSJung-uk Kim 
19457bded2dbSJung-uk Kim         if (i + proto_len < i || i + proto_len > data_len)
19467bded2dbSJung-uk Kim             goto parse_error;
19477bded2dbSJung-uk Kim 
19487bded2dbSJung-uk Kim         i += proto_len;
19497bded2dbSJung-uk Kim     }
19507bded2dbSJung-uk Kim 
1951b8721c16SJung-uk Kim     if (s->cert->alpn_proposed != NULL)
1952b8721c16SJung-uk Kim         OPENSSL_free(s->cert->alpn_proposed);
1953b8721c16SJung-uk Kim     s->cert->alpn_proposed = OPENSSL_malloc(data_len);
1954b8721c16SJung-uk Kim     if (s->cert->alpn_proposed == NULL) {
19557bded2dbSJung-uk Kim         *al = SSL_AD_INTERNAL_ERROR;
19567bded2dbSJung-uk Kim         return -1;
19577bded2dbSJung-uk Kim     }
1958b8721c16SJung-uk Kim     memcpy(s->cert->alpn_proposed, data, data_len);
1959b8721c16SJung-uk Kim     s->cert->alpn_proposed_len = data_len;
19607bded2dbSJung-uk Kim     return 0;
19617bded2dbSJung-uk Kim 
19627bded2dbSJung-uk Kim  parse_error:
19637bded2dbSJung-uk Kim     *al = SSL_AD_DECODE_ERROR;
19647bded2dbSJung-uk Kim     return -1;
19657bded2dbSJung-uk Kim }
19667bded2dbSJung-uk Kim 
1967b8721c16SJung-uk Kim /*
1968b8721c16SJung-uk Kim  * Process the ALPN extension in a ClientHello.
1969b8721c16SJung-uk Kim  * ret: a pointer to the TLSEXT return value: SSL_TLSEXT_ERR_*
1970b8721c16SJung-uk Kim  * al: a pointer to the alert value to send in the event of a failure.
1971b8721c16SJung-uk Kim  * returns 1 on success, 0 on failure: al/ret set only on failure
1972b8721c16SJung-uk Kim  */
1973b8721c16SJung-uk Kim static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
1974b8721c16SJung-uk Kim {
1975b8721c16SJung-uk Kim     const unsigned char *selected = NULL;
1976b8721c16SJung-uk Kim     unsigned char selected_len = 0;
1977b8721c16SJung-uk Kim 
1978b8721c16SJung-uk Kim     if (s->ctx->alpn_select_cb != NULL && s->cert->alpn_proposed != NULL) {
1979b8721c16SJung-uk Kim         int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
1980b8721c16SJung-uk Kim                                        s->cert->alpn_proposed,
1981b8721c16SJung-uk Kim                                        s->cert->alpn_proposed_len,
1982b8721c16SJung-uk Kim                                        s->ctx->alpn_select_cb_arg);
1983b8721c16SJung-uk Kim 
1984b8721c16SJung-uk Kim         if (r == SSL_TLSEXT_ERR_OK) {
1985b8721c16SJung-uk Kim             OPENSSL_free(s->s3->alpn_selected);
1986b8721c16SJung-uk Kim             s->s3->alpn_selected = OPENSSL_malloc(selected_len);
1987b8721c16SJung-uk Kim             if (s->s3->alpn_selected == NULL) {
1988b8721c16SJung-uk Kim                 *al = SSL_AD_INTERNAL_ERROR;
1989b8721c16SJung-uk Kim                 *ret = SSL_TLSEXT_ERR_ALERT_FATAL;
1990b8721c16SJung-uk Kim                 return 0;
1991b8721c16SJung-uk Kim             }
1992b8721c16SJung-uk Kim             memcpy(s->s3->alpn_selected, selected, selected_len);
1993b8721c16SJung-uk Kim             s->s3->alpn_selected_len = selected_len;
1994b8721c16SJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
1995b8721c16SJung-uk Kim             /* ALPN takes precedence over NPN. */
1996b8721c16SJung-uk Kim             s->s3->next_proto_neg_seen = 0;
1997b8721c16SJung-uk Kim # endif
1998b8721c16SJung-uk Kim         }
1999b8721c16SJung-uk Kim     }
2000b8721c16SJung-uk Kim 
2001b8721c16SJung-uk Kim     return 1;
2002b8721c16SJung-uk Kim }
2003b8721c16SJung-uk Kim 
20047bded2dbSJung-uk Kim static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
200580815a77SJung-uk Kim                                        unsigned char *limit, int *al)
2006db522d3aSSimon L. B. Nielsen {
2007db522d3aSSimon L. B. Nielsen     unsigned short type;
2008db522d3aSSimon L. B. Nielsen     unsigned short size;
2009db522d3aSSimon L. B. Nielsen     unsigned short len;
2010db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
20116a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
20126a599222SSimon L. B. Nielsen 
2013db522d3aSSimon L. B. Nielsen     s->servername_done = 0;
2014db522d3aSSimon L. B. Nielsen     s->tlsext_status_type = -1;
20151f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
20161f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
20171f13597dSJung-uk Kim # endif
20181f13597dSJung-uk Kim 
20197bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
20207bded2dbSJung-uk Kim         OPENSSL_free(s->s3->alpn_selected);
20217bded2dbSJung-uk Kim         s->s3->alpn_selected = NULL;
20227bded2dbSJung-uk Kim     }
2023b8721c16SJung-uk Kim     s->s3->alpn_selected_len = 0;
2024b8721c16SJung-uk Kim     if (s->cert->alpn_proposed) {
2025b8721c16SJung-uk Kim         OPENSSL_free(s->cert->alpn_proposed);
2026b8721c16SJung-uk Kim         s->cert->alpn_proposed = NULL;
2027b8721c16SJung-uk Kim     }
2028b8721c16SJung-uk Kim     s->cert->alpn_proposed_len = 0;
20291f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
20301f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
20311f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
20321f13597dSJung-uk Kim # endif
2033db522d3aSSimon L. B. Nielsen 
2034de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
2035de78d5d8SJung-uk Kim     if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
203680815a77SJung-uk Kim         ssl_check_for_safari(s, data, limit);
2037de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
2038de78d5d8SJung-uk Kim 
20397bded2dbSJung-uk Kim     /* Clear any signature algorithms extension received */
20407bded2dbSJung-uk Kim     if (s->cert->peer_sigalgs) {
20417bded2dbSJung-uk Kim         OPENSSL_free(s->cert->peer_sigalgs);
20427bded2dbSJung-uk Kim         s->cert->peer_sigalgs = NULL;
20437bded2dbSJung-uk Kim     }
2044751d2991SJung-uk Kim # ifndef OPENSSL_NO_SRP
20456f9291ceSJung-uk Kim     if (s->srp_ctx.login != NULL) {
2046751d2991SJung-uk Kim         OPENSSL_free(s->srp_ctx.login);
2047751d2991SJung-uk Kim         s->srp_ctx.login = NULL;
2048751d2991SJung-uk Kim     }
2049751d2991SJung-uk Kim # endif
2050751d2991SJung-uk Kim 
2051751d2991SJung-uk Kim     s->srtp_profile = NULL;
2052751d2991SJung-uk Kim 
205380815a77SJung-uk Kim     if (data == limit)
20546a599222SSimon L. B. Nielsen         goto ri_check;
2055d47910c6SJung-uk Kim 
2056*aeb5019cSJung-uk Kim     if (limit - data < 2)
2057d47910c6SJung-uk Kim         goto err;
2058d47910c6SJung-uk Kim 
2059db522d3aSSimon L. B. Nielsen     n2s(data, len);
2060db522d3aSSimon L. B. Nielsen 
2061*aeb5019cSJung-uk Kim     if (limit - data != len)
2062ed6b93beSJung-uk Kim         goto err;
2063db522d3aSSimon L. B. Nielsen 
2064*aeb5019cSJung-uk Kim     while (limit - data >= 4) {
2065db522d3aSSimon L. B. Nielsen         n2s(data, type);
2066db522d3aSSimon L. B. Nielsen         n2s(data, size);
2067db522d3aSSimon L. B. Nielsen 
2068*aeb5019cSJung-uk Kim         if (limit - data < size)
2069ed6b93beSJung-uk Kim             goto err;
20701f13597dSJung-uk Kim # if 0
20711f13597dSJung-uk Kim         fprintf(stderr, "Received extension type %d size %d\n", type, size);
20721f13597dSJung-uk Kim # endif
2073db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
20746f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
20756f9291ceSJung-uk Kim /*-
20766f9291ceSJung-uk Kim  * The servername extension is treated as follows:
20776f9291ceSJung-uk Kim  *
20786f9291ceSJung-uk Kim  * - Only the hostname type is supported with a maximum length of 255.
20796f9291ceSJung-uk Kim  * - The servername is rejected if too long or if it contains zeros,
20806f9291ceSJung-uk Kim  *   in which case an fatal alert is generated.
20816f9291ceSJung-uk Kim  * - The servername field is maintained together with the session cache.
20826f9291ceSJung-uk Kim  * - When a session is resumed, the servername call back invoked in order
20836f9291ceSJung-uk Kim  *   to allow the application to position itself to the right context.
20846f9291ceSJung-uk Kim  * - The servername is acknowledged if it is new for a session or when
20856f9291ceSJung-uk Kim  *   it is identical to a previously used for the same session.
20866f9291ceSJung-uk Kim  *   Applications can control the behaviour.  They can at any time
20876f9291ceSJung-uk Kim  *   set a 'desirable' servername for a new SSL object. This can be the
20886f9291ceSJung-uk Kim  *   case for example with HTTPS when a Host: header field is received and
20896f9291ceSJung-uk Kim  *   a renegotiation is requested. In this case, a possible servername
20906f9291ceSJung-uk Kim  *   presented in the new client hello is only acknowledged if it matches
20916f9291ceSJung-uk Kim  *   the value of the Host: field.
20926f9291ceSJung-uk Kim  * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
20936f9291ceSJung-uk Kim  *   if they provide for changing an explicit servername context for the
20946f9291ceSJung-uk Kim  *   session, i.e. when the session has been established with a servername
20956f9291ceSJung-uk Kim  *   extension.
20966f9291ceSJung-uk Kim  * - On session reconnect, the servername extension may be absent.
20976f9291ceSJung-uk Kim  *
2098db522d3aSSimon L. B. Nielsen  */
2099db522d3aSSimon L. B. Nielsen 
21006f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
2101db522d3aSSimon L. B. Nielsen             unsigned char *sdata;
2102db522d3aSSimon L. B. Nielsen             int servname_type;
2103db522d3aSSimon L. B. Nielsen             int dsize;
2104db522d3aSSimon L. B. Nielsen 
2105ed6b93beSJung-uk Kim             if (size < 2)
2106ed6b93beSJung-uk Kim                 goto err;
2107db522d3aSSimon L. B. Nielsen             n2s(data, dsize);
2108db522d3aSSimon L. B. Nielsen             size -= 2;
2109ed6b93beSJung-uk Kim             if (dsize > size)
2110ed6b93beSJung-uk Kim                 goto err;
2111db522d3aSSimon L. B. Nielsen 
2112db522d3aSSimon L. B. Nielsen             sdata = data;
21136f9291ceSJung-uk Kim             while (dsize > 3) {
2114db522d3aSSimon L. B. Nielsen                 servname_type = *(sdata++);
2115db522d3aSSimon L. B. Nielsen                 n2s(sdata, len);
2116db522d3aSSimon L. B. Nielsen                 dsize -= 3;
2117db522d3aSSimon L. B. Nielsen 
2118ed6b93beSJung-uk Kim                 if (len > dsize)
2119ed6b93beSJung-uk Kim                     goto err;
2120ed6b93beSJung-uk Kim 
2121db522d3aSSimon L. B. Nielsen                 if (s->servername_done == 0)
21226f9291ceSJung-uk Kim                     switch (servname_type) {
2123db522d3aSSimon L. B. Nielsen                     case TLSEXT_NAMETYPE_host_name:
21246f9291ceSJung-uk Kim                         if (!s->hit) {
2125ed6b93beSJung-uk Kim                             if (s->session->tlsext_hostname)
2126ed6b93beSJung-uk Kim                                 goto err;
2127ed6b93beSJung-uk Kim 
21286f9291ceSJung-uk Kim                             if (len > TLSEXT_MAXLEN_host_name) {
2129db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2130db522d3aSSimon L. B. Nielsen                                 return 0;
2131db522d3aSSimon L. B. Nielsen                             }
21326f9291ceSJung-uk Kim                             if ((s->session->tlsext_hostname =
21336f9291ceSJung-uk Kim                                  OPENSSL_malloc(len + 1)) == NULL) {
2134a3ddd25aSSimon L. B. Nielsen                                 *al = TLS1_AD_INTERNAL_ERROR;
2135a3ddd25aSSimon L. B. Nielsen                                 return 0;
2136a3ddd25aSSimon L. B. Nielsen                             }
2137db522d3aSSimon L. B. Nielsen                             memcpy(s->session->tlsext_hostname, sdata, len);
2138db522d3aSSimon L. B. Nielsen                             s->session->tlsext_hostname[len] = '\0';
2139db522d3aSSimon L. B. Nielsen                             if (strlen(s->session->tlsext_hostname) != len) {
2140db522d3aSSimon L. B. Nielsen                                 OPENSSL_free(s->session->tlsext_hostname);
2141db522d3aSSimon L. B. Nielsen                                 s->session->tlsext_hostname = NULL;
2142db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2143db522d3aSSimon L. B. Nielsen                                 return 0;
2144db522d3aSSimon L. B. Nielsen                             }
2145db522d3aSSimon L. B. Nielsen                             s->servername_done = 1;
2146db522d3aSSimon L. B. Nielsen 
21476f9291ceSJung-uk Kim                         } else
2148a3ddd25aSSimon L. B. Nielsen                             s->servername_done = s->session->tlsext_hostname
2149a3ddd25aSSimon L. B. Nielsen                                 && strlen(s->session->tlsext_hostname) == len
21506f9291ceSJung-uk Kim                                 && strncmp(s->session->tlsext_hostname,
21516f9291ceSJung-uk Kim                                            (char *)sdata, len) == 0;
2152db522d3aSSimon L. B. Nielsen 
2153db522d3aSSimon L. B. Nielsen                         break;
2154db522d3aSSimon L. B. Nielsen 
2155db522d3aSSimon L. B. Nielsen                     default:
2156db522d3aSSimon L. B. Nielsen                         break;
2157db522d3aSSimon L. B. Nielsen                     }
2158db522d3aSSimon L. B. Nielsen 
2159db522d3aSSimon L. B. Nielsen                 dsize -= len;
2160db522d3aSSimon L. B. Nielsen             }
2161ed6b93beSJung-uk Kim             if (dsize != 0)
2162ed6b93beSJung-uk Kim                 goto err;
2163db522d3aSSimon L. B. Nielsen 
2164db522d3aSSimon L. B. Nielsen         }
21651f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP
21666f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_srp) {
2167ed6b93beSJung-uk Kim             if (size == 0 || ((len = data[0])) != (size - 1))
2168ed6b93beSJung-uk Kim                 goto err;
2169ed6b93beSJung-uk Kim             if (s->srp_ctx.login != NULL)
2170ed6b93beSJung-uk Kim                 goto err;
21711f13597dSJung-uk Kim             if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
21721f13597dSJung-uk Kim                 return -1;
21731f13597dSJung-uk Kim             memcpy(s->srp_ctx.login, &data[1], len);
21741f13597dSJung-uk Kim             s->srp_ctx.login[len] = '\0';
21751f13597dSJung-uk Kim 
2176ed6b93beSJung-uk Kim             if (strlen(s->srp_ctx.login) != len)
2177ed6b93beSJung-uk Kim                 goto err;
21781f13597dSJung-uk Kim         }
21791f13597dSJung-uk Kim # endif
21801f13597dSJung-uk Kim 
21811f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
21826f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
21831f13597dSJung-uk Kim             unsigned char *sdata = data;
21841f13597dSJung-uk Kim             int ecpointformatlist_length = *(sdata++);
21851f13597dSJung-uk Kim 
21867bded2dbSJung-uk Kim             if (ecpointformatlist_length != size - 1 ||
21877bded2dbSJung-uk Kim                 ecpointformatlist_length < 1)
2188ed6b93beSJung-uk Kim                 goto err;
21896f9291ceSJung-uk Kim             if (!s->hit) {
21906f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist) {
21911f13597dSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
21921f13597dSJung-uk Kim                     s->session->tlsext_ecpointformatlist = NULL;
21931f13597dSJung-uk Kim                 }
21941f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
21956f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
21966f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
21971f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
21981f13597dSJung-uk Kim                     return 0;
21991f13597dSJung-uk Kim                 }
22006f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
22016f9291ceSJung-uk Kim                     ecpointformatlist_length;
22026f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
22036f9291ceSJung-uk Kim                        ecpointformatlist_length);
22041f13597dSJung-uk Kim             }
22051f13597dSJung-uk Kim #  if 0
22066f9291ceSJung-uk Kim             fprintf(stderr,
22076f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ",
22086f9291ceSJung-uk Kim                     s->session->tlsext_ecpointformatlist_length);
22091f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
22101f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
22111f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
22121f13597dSJung-uk Kim             fprintf(stderr, "\n");
22131f13597dSJung-uk Kim #  endif
22146f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_elliptic_curves) {
22151f13597dSJung-uk Kim             unsigned char *sdata = data;
22161f13597dSJung-uk Kim             int ellipticcurvelist_length = (*(sdata++) << 8);
22171f13597dSJung-uk Kim             ellipticcurvelist_length += (*(sdata++));
22181f13597dSJung-uk Kim 
221909286989SJung-uk Kim             if (ellipticcurvelist_length != size - 2 ||
2220751d2991SJung-uk Kim                 ellipticcurvelist_length < 1 ||
2221751d2991SJung-uk Kim                 /* Each NamedCurve is 2 bytes. */
2222ed6b93beSJung-uk Kim                 ellipticcurvelist_length & 1)
2223ed6b93beSJung-uk Kim                     goto err;
2224ed6b93beSJung-uk Kim 
22256f9291ceSJung-uk Kim             if (!s->hit) {
2226ed6b93beSJung-uk Kim                 if (s->session->tlsext_ellipticcurvelist)
2227ed6b93beSJung-uk Kim                     goto err;
2228ed6b93beSJung-uk Kim 
22291f13597dSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length = 0;
22306f9291ceSJung-uk Kim                 if ((s->session->tlsext_ellipticcurvelist =
22316f9291ceSJung-uk Kim                      OPENSSL_malloc(ellipticcurvelist_length)) == NULL) {
22321f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
22331f13597dSJung-uk Kim                     return 0;
22341f13597dSJung-uk Kim                 }
22356f9291ceSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length =
22366f9291ceSJung-uk Kim                     ellipticcurvelist_length;
22376f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ellipticcurvelist, sdata,
22386f9291ceSJung-uk Kim                        ellipticcurvelist_length);
22391f13597dSJung-uk Kim             }
22401f13597dSJung-uk Kim #  if 0
22416f9291ceSJung-uk Kim             fprintf(stderr,
22426f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ",
22436f9291ceSJung-uk Kim                     s->session->tlsext_ellipticcurvelist_length);
22441f13597dSJung-uk Kim             sdata = s->session->tlsext_ellipticcurvelist;
22451f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
22461f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
22471f13597dSJung-uk Kim             fprintf(stderr, "\n");
22481f13597dSJung-uk Kim #  endif
22491f13597dSJung-uk Kim         }
22501f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
22511f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
22527bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input) {
22531f13597dSJung-uk Kim             unsigned char *sdata = data;
22541f13597dSJung-uk Kim 
22556f9291ceSJung-uk Kim             if (size < 2) {
22561f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
22571f13597dSJung-uk Kim                 return 0;
22581f13597dSJung-uk Kim             }
22591f13597dSJung-uk Kim             n2s(sdata, s->s3->client_opaque_prf_input_len);
22606f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input_len != size - 2) {
22611f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
22621f13597dSJung-uk Kim                 return 0;
22631f13597dSJung-uk Kim             }
22641f13597dSJung-uk Kim 
22656f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
22666f9291ceSJung-uk Kim                 /* shouldn't really happen */
22671f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
22686f9291ceSJung-uk Kim             }
22696f9291ceSJung-uk Kim 
22706f9291ceSJung-uk Kim             /* dummy byte just to get non-NULL */
22711f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input_len == 0)
22726f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
22731f13597dSJung-uk Kim             else
22746f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
22756f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
22766f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
22771f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
22781f13597dSJung-uk Kim                 return 0;
22791f13597dSJung-uk Kim             }
22801f13597dSJung-uk Kim         }
22811f13597dSJung-uk Kim # endif
22826f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
22831f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
22846f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
22856f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
22861f13597dSJung-uk Kim             {
22871f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
22881f13597dSJung-uk Kim                 return 0;
22891f13597dSJung-uk Kim             }
22906f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_renegotiate) {
22916a599222SSimon L. B. Nielsen             if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
22926a599222SSimon L. B. Nielsen                 return 0;
22936a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
22946f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_signature_algorithms) {
22951f13597dSJung-uk Kim             int dsize;
22967bded2dbSJung-uk Kim             if (s->cert->peer_sigalgs || size < 2)
2297ed6b93beSJung-uk Kim                 goto err;
22981f13597dSJung-uk Kim             n2s(data, dsize);
22991f13597dSJung-uk Kim             size -= 2;
23007bded2dbSJung-uk Kim             if (dsize != size || dsize & 1 || !dsize)
2301ed6b93beSJung-uk Kim                 goto err;
23027bded2dbSJung-uk Kim             if (!tls1_save_sigalgs(s, data, dsize))
2303ed6b93beSJung-uk Kim                 goto err;
23047bded2dbSJung-uk Kim         } else if (type == TLSEXT_TYPE_status_request) {
2305db522d3aSSimon L. B. Nielsen 
2306ed6b93beSJung-uk Kim             if (size < 5)
2307ed6b93beSJung-uk Kim                 goto err;
2308db522d3aSSimon L. B. Nielsen 
2309db522d3aSSimon L. B. Nielsen             s->tlsext_status_type = *data++;
2310db522d3aSSimon L. B. Nielsen             size--;
23116f9291ceSJung-uk Kim             if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
2312db522d3aSSimon L. B. Nielsen                 const unsigned char *sdata;
2313db522d3aSSimon L. B. Nielsen                 int dsize;
2314db522d3aSSimon L. B. Nielsen                 /* Read in responder_id_list */
2315db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
2316db522d3aSSimon L. B. Nielsen                 size -= 2;
2317ed6b93beSJung-uk Kim                 if (dsize > size)
2318ed6b93beSJung-uk Kim                     goto err;
2319*aeb5019cSJung-uk Kim 
2320*aeb5019cSJung-uk Kim                 /*
2321*aeb5019cSJung-uk Kim                  * We remove any OCSP_RESPIDs from a previous handshake
2322*aeb5019cSJung-uk Kim                  * to prevent unbounded memory growth - CVE-2016-6304
2323*aeb5019cSJung-uk Kim                  */
2324*aeb5019cSJung-uk Kim                 sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
2325*aeb5019cSJung-uk Kim                                         OCSP_RESPID_free);
2326*aeb5019cSJung-uk Kim                 if (dsize > 0) {
2327*aeb5019cSJung-uk Kim                     s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
2328*aeb5019cSJung-uk Kim                     if (s->tlsext_ocsp_ids == NULL) {
2329*aeb5019cSJung-uk Kim                         *al = SSL_AD_INTERNAL_ERROR;
2330*aeb5019cSJung-uk Kim                         return 0;
2331*aeb5019cSJung-uk Kim                     }
2332*aeb5019cSJung-uk Kim                 } else {
2333*aeb5019cSJung-uk Kim                     s->tlsext_ocsp_ids = NULL;
2334*aeb5019cSJung-uk Kim                 }
2335*aeb5019cSJung-uk Kim 
23366f9291ceSJung-uk Kim                 while (dsize > 0) {
2337db522d3aSSimon L. B. Nielsen                     OCSP_RESPID *id;
2338db522d3aSSimon L. B. Nielsen                     int idsize;
2339ed6b93beSJung-uk Kim                     if (dsize < 4)
2340ed6b93beSJung-uk Kim                         goto err;
2341db522d3aSSimon L. B. Nielsen                     n2s(data, idsize);
2342db522d3aSSimon L. B. Nielsen                     dsize -= 2 + idsize;
23430a704568SSimon L. B. Nielsen                     size -= 2 + idsize;
2344ed6b93beSJung-uk Kim                     if (dsize < 0)
2345ed6b93beSJung-uk Kim                         goto err;
2346db522d3aSSimon L. B. Nielsen                     sdata = data;
2347db522d3aSSimon L. B. Nielsen                     data += idsize;
23486f9291ceSJung-uk Kim                     id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
2349ed6b93beSJung-uk Kim                     if (!id)
2350ed6b93beSJung-uk Kim                         goto err;
23516f9291ceSJung-uk Kim                     if (data != sdata) {
2352db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2353ed6b93beSJung-uk Kim                         goto err;
2354db522d3aSSimon L. B. Nielsen                     }
23556f9291ceSJung-uk Kim                     if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
2356db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2357db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_INTERNAL_ERROR;
2358db522d3aSSimon L. B. Nielsen                         return 0;
2359db522d3aSSimon L. B. Nielsen                     }
2360db522d3aSSimon L. B. Nielsen                 }
2361db522d3aSSimon L. B. Nielsen 
2362db522d3aSSimon L. B. Nielsen                 /* Read in request_extensions */
2363ed6b93beSJung-uk Kim                 if (size < 2)
2364ed6b93beSJung-uk Kim                     goto err;
2365db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
2366db522d3aSSimon L. B. Nielsen                 size -= 2;
2367ed6b93beSJung-uk Kim                 if (dsize != size)
2368ed6b93beSJung-uk Kim                     goto err;
2369db522d3aSSimon L. B. Nielsen                 sdata = data;
23706f9291ceSJung-uk Kim                 if (dsize > 0) {
23716f9291ceSJung-uk Kim                     if (s->tlsext_ocsp_exts) {
237212de4ed2SJung-uk Kim                         sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
237312de4ed2SJung-uk Kim                                                    X509_EXTENSION_free);
237412de4ed2SJung-uk Kim                     }
237512de4ed2SJung-uk Kim 
2376db522d3aSSimon L. B. Nielsen                     s->tlsext_ocsp_exts =
23776f9291ceSJung-uk Kim                         d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
2378ed6b93beSJung-uk Kim                     if (!s->tlsext_ocsp_exts || (data + dsize != sdata))
2379ed6b93beSJung-uk Kim                         goto err;
2380db522d3aSSimon L. B. Nielsen                 }
2381db522d3aSSimon L. B. Nielsen             }
23826f9291ceSJung-uk Kim             /*
23836f9291ceSJung-uk Kim              * We don't know what to do with any other type * so ignore it.
2384db522d3aSSimon L. B. Nielsen              */
2385db522d3aSSimon L. B. Nielsen             else
2386db522d3aSSimon L. B. Nielsen                 s->tlsext_status_type = -1;
2387db522d3aSSimon L. B. Nielsen         }
23881f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
23896f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
23906f9291ceSJung-uk Kim             switch (data[0]) {
23911f13597dSJung-uk Kim             case 0x01:         /* Client allows us to send HB requests */
23921f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
23931f13597dSJung-uk Kim                 break;
23941f13597dSJung-uk Kim             case 0x02:         /* Client doesn't accept HB requests */
23951f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
23961f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
23971f13597dSJung-uk Kim                 break;
23986f9291ceSJung-uk Kim             default:
23996f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
24001f13597dSJung-uk Kim                 return 0;
24011f13597dSJung-uk Kim             }
24021f13597dSJung-uk Kim         }
24031f13597dSJung-uk Kim # endif
24041f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
24051f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
2406b8721c16SJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
24076f9291ceSJung-uk Kim             /*-
24086f9291ceSJung-uk Kim              * We shouldn't accept this extension on a
24091f13597dSJung-uk Kim              * renegotiation.
24101f13597dSJung-uk Kim              *
24111f13597dSJung-uk Kim              * s->new_session will be set on renegotiation, but we
24121f13597dSJung-uk Kim              * probably shouldn't rely that it couldn't be set on
24131f13597dSJung-uk Kim              * the initial renegotation too in certain cases (when
24141f13597dSJung-uk Kim              * there's some other reason to disallow resuming an
24151f13597dSJung-uk Kim              * earlier session -- the current code won't be doing
24161f13597dSJung-uk Kim              * anything like that, but this might change).
24176f9291ceSJung-uk Kim              *
24181f13597dSJung-uk Kim              * A valid sign that there's been a previous handshake
24191f13597dSJung-uk Kim              * in this connection is if s->s3->tmp.finish_md_len >
24201f13597dSJung-uk Kim              * 0.  (We are talking about a check that will happen
24211f13597dSJung-uk Kim              * in the Hello protocol round, well before a new
24226f9291ceSJung-uk Kim              * Finished message could have been computed.)
24236f9291ceSJung-uk Kim              */
24241f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
24251f13597dSJung-uk Kim         }
24261f13597dSJung-uk Kim # endif
24276a599222SSimon L. B. Nielsen 
24287bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
2429b8721c16SJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
24307bded2dbSJung-uk Kim             if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
24317bded2dbSJung-uk Kim                 return 0;
24327bded2dbSJung-uk Kim         }
24337bded2dbSJung-uk Kim 
2434db522d3aSSimon L. B. Nielsen         /* session ticket processed earlier */
243509286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
2436fa5fddf1SJung-uk Kim         else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
24376f9291ceSJung-uk Kim                  && type == TLSEXT_TYPE_use_srtp) {
24386f9291ceSJung-uk Kim             if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al))
24391f13597dSJung-uk Kim                 return 0;
24401f13597dSJung-uk Kim         }
244109286989SJung-uk Kim # endif
2442db522d3aSSimon L. B. Nielsen 
2443db522d3aSSimon L. B. Nielsen         data += size;
2444db522d3aSSimon L. B. Nielsen     }
24451f13597dSJung-uk Kim 
2446ed6b93beSJung-uk Kim     /* Spurious data on the end */
244780815a77SJung-uk Kim     if (data != limit)
2448ed6b93beSJung-uk Kim         goto err;
2449ed6b93beSJung-uk Kim 
2450db522d3aSSimon L. B. Nielsen     *p = data;
24516a599222SSimon L. B. Nielsen 
24526a599222SSimon L. B. Nielsen  ri_check:
24536a599222SSimon L. B. Nielsen 
24546a599222SSimon L. B. Nielsen     /* Need RI if renegotiating */
24556a599222SSimon L. B. Nielsen 
24561f13597dSJung-uk Kim     if (!renegotiate_seen && s->renegotiate &&
24576f9291ceSJung-uk Kim         !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
24586a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
24597bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
24606a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
24616a599222SSimon L. B. Nielsen         return 0;
24626a599222SSimon L. B. Nielsen     }
24636a599222SSimon L. B. Nielsen 
2464db522d3aSSimon L. B. Nielsen     return 1;
2465ed6b93beSJung-uk Kim err:
2466ed6b93beSJung-uk Kim     *al = SSL_AD_DECODE_ERROR;
2467ed6b93beSJung-uk Kim     return 0;
2468db522d3aSSimon L. B. Nielsen }
2469db522d3aSSimon L. B. Nielsen 
24707bded2dbSJung-uk Kim /*
24717bded2dbSJung-uk Kim  * Parse any custom extensions found.  "data" is the start of the extension data
24727bded2dbSJung-uk Kim  * and "limit" is the end of the record. TODO: add strict syntax checking.
24737bded2dbSJung-uk Kim  */
24747bded2dbSJung-uk Kim 
24757bded2dbSJung-uk Kim static int ssl_scan_clienthello_custom_tlsext(SSL *s,
24767bded2dbSJung-uk Kim                                               const unsigned char *data,
24777bded2dbSJung-uk Kim                                               const unsigned char *limit,
24787bded2dbSJung-uk Kim                                               int *al)
24797bded2dbSJung-uk Kim {
24807bded2dbSJung-uk Kim     unsigned short type, size, len;
24817bded2dbSJung-uk Kim     /* If resumed session or no custom extensions nothing to do */
24827bded2dbSJung-uk Kim     if (s->hit || s->cert->srv_ext.meths_count == 0)
24837bded2dbSJung-uk Kim         return 1;
24847bded2dbSJung-uk Kim 
2485*aeb5019cSJung-uk Kim     if (limit - data <= 2)
24867bded2dbSJung-uk Kim         return 1;
24877bded2dbSJung-uk Kim     n2s(data, len);
24887bded2dbSJung-uk Kim 
2489*aeb5019cSJung-uk Kim     if (limit - data < len)
24907bded2dbSJung-uk Kim         return 1;
24917bded2dbSJung-uk Kim 
2492*aeb5019cSJung-uk Kim     while (limit - data >= 4) {
24937bded2dbSJung-uk Kim         n2s(data, type);
24947bded2dbSJung-uk Kim         n2s(data, size);
24957bded2dbSJung-uk Kim 
2496*aeb5019cSJung-uk Kim         if (limit - data < size)
24977bded2dbSJung-uk Kim             return 1;
24987bded2dbSJung-uk Kim         if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0)
24997bded2dbSJung-uk Kim             return 0;
25007bded2dbSJung-uk Kim 
25017bded2dbSJung-uk Kim         data += size;
25027bded2dbSJung-uk Kim     }
25037bded2dbSJung-uk Kim 
25047bded2dbSJung-uk Kim     return 1;
25057bded2dbSJung-uk Kim }
25067bded2dbSJung-uk Kim 
250780815a77SJung-uk Kim int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
250880815a77SJung-uk Kim                                  unsigned char *limit)
25097bded2dbSJung-uk Kim {
25107bded2dbSJung-uk Kim     int al = -1;
25117bded2dbSJung-uk Kim     unsigned char *ptmp = *p;
25127bded2dbSJung-uk Kim     /*
25137bded2dbSJung-uk Kim      * Internally supported extensions are parsed first so SNI can be handled
25147bded2dbSJung-uk Kim      * before custom extensions. An application processing SNI will typically
25157bded2dbSJung-uk Kim      * switch the parent context using SSL_set_SSL_CTX and custom extensions
25167bded2dbSJung-uk Kim      * need to be handled by the new SSL_CTX structure.
25177bded2dbSJung-uk Kim      */
251880815a77SJung-uk Kim     if (ssl_scan_clienthello_tlsext(s, p, limit, &al) <= 0) {
25197bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
25207bded2dbSJung-uk Kim         return 0;
25217bded2dbSJung-uk Kim     }
25227bded2dbSJung-uk Kim 
25237bded2dbSJung-uk Kim     if (ssl_check_clienthello_tlsext_early(s) <= 0) {
25247bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT);
25257bded2dbSJung-uk Kim         return 0;
25267bded2dbSJung-uk Kim     }
25277bded2dbSJung-uk Kim 
25287bded2dbSJung-uk Kim     custom_ext_init(&s->cert->srv_ext);
252980815a77SJung-uk Kim     if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) {
25307bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
25317bded2dbSJung-uk Kim         return 0;
25327bded2dbSJung-uk Kim     }
25337bded2dbSJung-uk Kim 
25347bded2dbSJung-uk Kim     return 1;
25357bded2dbSJung-uk Kim }
25367bded2dbSJung-uk Kim 
25371f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
25386f9291ceSJung-uk Kim /*
25396f9291ceSJung-uk Kim  * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
25406f9291ceSJung-uk Kim  * elements of zero length are allowed and the set of elements must exactly
25416f9291ceSJung-uk Kim  * fill the length of the block.
25426f9291ceSJung-uk Kim  */
25431f13597dSJung-uk Kim static char ssl_next_proto_validate(unsigned char *d, unsigned len)
25441f13597dSJung-uk Kim {
25451f13597dSJung-uk Kim     unsigned int off = 0;
25461f13597dSJung-uk Kim 
25476f9291ceSJung-uk Kim     while (off < len) {
25481f13597dSJung-uk Kim         if (d[off] == 0)
25491f13597dSJung-uk Kim             return 0;
25501f13597dSJung-uk Kim         off += d[off];
25511f13597dSJung-uk Kim         off++;
25521f13597dSJung-uk Kim     }
25531f13597dSJung-uk Kim 
25541f13597dSJung-uk Kim     return off == len;
25551f13597dSJung-uk Kim }
25561f13597dSJung-uk Kim # endif
25571f13597dSJung-uk Kim 
25587bded2dbSJung-uk Kim static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
25597bded2dbSJung-uk Kim                                        unsigned char *d, int n, int *al)
2560db522d3aSSimon L. B. Nielsen {
2561a3ddd25aSSimon L. B. Nielsen     unsigned short length;
2562db522d3aSSimon L. B. Nielsen     unsigned short type;
2563db522d3aSSimon L. B. Nielsen     unsigned short size;
2564db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
2565db522d3aSSimon L. B. Nielsen     int tlsext_servername = 0;
25666a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
2567db522d3aSSimon L. B. Nielsen 
25681f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
25691f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
25701f13597dSJung-uk Kim # endif
2571751d2991SJung-uk Kim     s->tlsext_ticket_expected = 0;
25721f13597dSJung-uk Kim 
25737bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
25747bded2dbSJung-uk Kim         OPENSSL_free(s->s3->alpn_selected);
25757bded2dbSJung-uk Kim         s->s3->alpn_selected = NULL;
25767bded2dbSJung-uk Kim     }
25771f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
25781f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
25791f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
25801f13597dSJung-uk Kim # endif
25811f13597dSJung-uk Kim 
2582*aeb5019cSJung-uk Kim     if ((d + n) - data <= 2)
25836a599222SSimon L. B. Nielsen         goto ri_check;
2584db522d3aSSimon L. B. Nielsen 
2585a3ddd25aSSimon L. B. Nielsen     n2s(data, length);
2586*aeb5019cSJung-uk Kim     if ((d + n) - data != length) {
2587a3ddd25aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
2588a3ddd25aSSimon L. B. Nielsen         return 0;
2589a3ddd25aSSimon L. B. Nielsen     }
2590db522d3aSSimon L. B. Nielsen 
2591*aeb5019cSJung-uk Kim     while ((d + n) - data >= 4) {
2592db522d3aSSimon L. B. Nielsen         n2s(data, type);
2593db522d3aSSimon L. B. Nielsen         n2s(data, size);
2594db522d3aSSimon L. B. Nielsen 
2595*aeb5019cSJung-uk Kim         if ((d + n) - data < size)
25966a599222SSimon L. B. Nielsen             goto ri_check;
2597db522d3aSSimon L. B. Nielsen 
2598db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
25996f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
2600db522d3aSSimon L. B. Nielsen 
26016f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
26026f9291ceSJung-uk Kim             if (s->tlsext_hostname == NULL || size > 0) {
2603db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2604db522d3aSSimon L. B. Nielsen                 return 0;
2605db522d3aSSimon L. B. Nielsen             }
2606db522d3aSSimon L. B. Nielsen             tlsext_servername = 1;
2607db522d3aSSimon L. B. Nielsen         }
26081f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
26096f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
26101f13597dSJung-uk Kim             unsigned char *sdata = data;
26111f13597dSJung-uk Kim             int ecpointformatlist_length = *(sdata++);
26121f13597dSJung-uk Kim 
26137bded2dbSJung-uk Kim             if (ecpointformatlist_length != size - 1) {
26141f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
26151f13597dSJung-uk Kim                 return 0;
26161f13597dSJung-uk Kim             }
26176f9291ceSJung-uk Kim             if (!s->hit) {
26181f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
26196f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist != NULL)
26206f9291ceSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
26216f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
26226f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
26231f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
26241f13597dSJung-uk Kim                     return 0;
26251f13597dSJung-uk Kim                 }
26266f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
26276f9291ceSJung-uk Kim                     ecpointformatlist_length;
26286f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
26296f9291ceSJung-uk Kim                        ecpointformatlist_length);
2630a93cbc2bSJung-uk Kim             }
26311f13597dSJung-uk Kim #  if 0
26326f9291ceSJung-uk Kim             fprintf(stderr,
26336f9291ceSJung-uk Kim                     "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
26341f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
26351f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
26361f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
26371f13597dSJung-uk Kim             fprintf(stderr, "\n");
26381f13597dSJung-uk Kim #  endif
26391f13597dSJung-uk Kim         }
26401f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
26411f13597dSJung-uk Kim 
26426f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
26431f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
26446f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
26456f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
26461f13597dSJung-uk Kim             {
26471f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
26481f13597dSJung-uk Kim                 return 0;
26491f13597dSJung-uk Kim             }
2650db522d3aSSimon L. B. Nielsen             if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
26516f9291ceSJung-uk Kim                 || (size > 0)) {
2652db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2653db522d3aSSimon L. B. Nielsen                 return 0;
2654db522d3aSSimon L. B. Nielsen             }
2655db522d3aSSimon L. B. Nielsen             s->tlsext_ticket_expected = 1;
2656db522d3aSSimon L. B. Nielsen         }
26571f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
26587bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input) {
26591f13597dSJung-uk Kim             unsigned char *sdata = data;
26601f13597dSJung-uk Kim 
26616f9291ceSJung-uk Kim             if (size < 2) {
26621f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
26631f13597dSJung-uk Kim                 return 0;
26641f13597dSJung-uk Kim             }
26651f13597dSJung-uk Kim             n2s(sdata, s->s3->server_opaque_prf_input_len);
26666f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len != size - 2) {
26671f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
26681f13597dSJung-uk Kim                 return 0;
26691f13597dSJung-uk Kim             }
26701f13597dSJung-uk Kim 
26716f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input != NULL) {
26726f9291ceSJung-uk Kim                 /* shouldn't really happen */
26731f13597dSJung-uk Kim                 OPENSSL_free(s->s3->server_opaque_prf_input);
26746f9291ceSJung-uk Kim             }
26756f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len == 0) {
26766f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
26776f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
26786f9291ceSJung-uk Kim             } else {
26796f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input =
26806f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
26816f9291ceSJung-uk Kim             }
26821f13597dSJung-uk Kim 
26836f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input == NULL) {
26841f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
26851f13597dSJung-uk Kim                 return 0;
26861f13597dSJung-uk Kim             }
26871f13597dSJung-uk Kim         }
26881f13597dSJung-uk Kim # endif
26897bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_status_request) {
26906f9291ceSJung-uk Kim             /*
26916f9291ceSJung-uk Kim              * MUST be empty and only sent if we've requested a status
26926f9291ceSJung-uk Kim              * request message.
2693db522d3aSSimon L. B. Nielsen              */
26946f9291ceSJung-uk Kim             if ((s->tlsext_status_type == -1) || (size > 0)) {
2695db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2696db522d3aSSimon L. B. Nielsen                 return 0;
2697db522d3aSSimon L. B. Nielsen             }
2698db522d3aSSimon L. B. Nielsen             /* Set flag to expect CertificateStatus message */
2699db522d3aSSimon L. B. Nielsen             s->tlsext_status_expected = 1;
2700db522d3aSSimon L. B. Nielsen         }
27011f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
27021f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
27036f9291ceSJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
27041f13597dSJung-uk Kim             unsigned char *selected;
27051f13597dSJung-uk Kim             unsigned char selected_len;
27061f13597dSJung-uk Kim 
27071f13597dSJung-uk Kim             /* We must have requested it. */
27086f9291ceSJung-uk Kim             if (s->ctx->next_proto_select_cb == NULL) {
27091f13597dSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
27101f13597dSJung-uk Kim                 return 0;
27111f13597dSJung-uk Kim             }
27121f13597dSJung-uk Kim             /* The data must be valid */
27136f9291ceSJung-uk Kim             if (!ssl_next_proto_validate(data, size)) {
27141f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
27151f13597dSJung-uk Kim                 return 0;
27161f13597dSJung-uk Kim             }
27176f9291ceSJung-uk Kim             if (s->
27186f9291ceSJung-uk Kim                 ctx->next_proto_select_cb(s, &selected, &selected_len, data,
27196f9291ceSJung-uk Kim                                           size,
27206f9291ceSJung-uk Kim                                           s->ctx->next_proto_select_cb_arg) !=
27216f9291ceSJung-uk Kim                 SSL_TLSEXT_ERR_OK) {
27221f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
27231f13597dSJung-uk Kim                 return 0;
27241f13597dSJung-uk Kim             }
2725*aeb5019cSJung-uk Kim             /*
2726*aeb5019cSJung-uk Kim              * Could be non-NULL if server has sent multiple NPN extensions in
2727*aeb5019cSJung-uk Kim              * a single Serverhello
2728*aeb5019cSJung-uk Kim              */
2729*aeb5019cSJung-uk Kim             OPENSSL_free(s->next_proto_negotiated);
27301f13597dSJung-uk Kim             s->next_proto_negotiated = OPENSSL_malloc(selected_len);
27316f9291ceSJung-uk Kim             if (!s->next_proto_negotiated) {
27321f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
27331f13597dSJung-uk Kim                 return 0;
27341f13597dSJung-uk Kim             }
27351f13597dSJung-uk Kim             memcpy(s->next_proto_negotiated, selected, selected_len);
27361f13597dSJung-uk Kim             s->next_proto_negotiated_len = selected_len;
27371f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
27381f13597dSJung-uk Kim         }
27391f13597dSJung-uk Kim # endif
27407bded2dbSJung-uk Kim 
27417bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
27427bded2dbSJung-uk Kim             unsigned len;
27437bded2dbSJung-uk Kim 
27447bded2dbSJung-uk Kim             /* We must have requested it. */
2745b8721c16SJung-uk Kim             if (!s->cert->alpn_sent) {
27467bded2dbSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
27477bded2dbSJung-uk Kim                 return 0;
27487bded2dbSJung-uk Kim             }
27497bded2dbSJung-uk Kim             if (size < 4) {
27507bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
27517bded2dbSJung-uk Kim                 return 0;
27527bded2dbSJung-uk Kim             }
27537bded2dbSJung-uk Kim             /*-
27547bded2dbSJung-uk Kim              * The extension data consists of:
27557bded2dbSJung-uk Kim              *   uint16 list_length
27567bded2dbSJung-uk Kim              *   uint8 proto_length;
27577bded2dbSJung-uk Kim              *   uint8 proto[proto_length];
27587bded2dbSJung-uk Kim              */
27597bded2dbSJung-uk Kim             len = data[0];
27607bded2dbSJung-uk Kim             len <<= 8;
27617bded2dbSJung-uk Kim             len |= data[1];
27627bded2dbSJung-uk Kim             if (len != (unsigned)size - 2) {
27637bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
27647bded2dbSJung-uk Kim                 return 0;
27657bded2dbSJung-uk Kim             }
27667bded2dbSJung-uk Kim             len = data[2];
27677bded2dbSJung-uk Kim             if (len != (unsigned)size - 3) {
27687bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
27697bded2dbSJung-uk Kim                 return 0;
27707bded2dbSJung-uk Kim             }
27717bded2dbSJung-uk Kim             if (s->s3->alpn_selected)
27727bded2dbSJung-uk Kim                 OPENSSL_free(s->s3->alpn_selected);
27737bded2dbSJung-uk Kim             s->s3->alpn_selected = OPENSSL_malloc(len);
27747bded2dbSJung-uk Kim             if (!s->s3->alpn_selected) {
27757bded2dbSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
27767bded2dbSJung-uk Kim                 return 0;
27777bded2dbSJung-uk Kim             }
27787bded2dbSJung-uk Kim             memcpy(s->s3->alpn_selected, data + 3, len);
27797bded2dbSJung-uk Kim             s->s3->alpn_selected_len = len;
27807bded2dbSJung-uk Kim         }
27817bded2dbSJung-uk Kim 
27826f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_renegotiate) {
27836a599222SSimon L. B. Nielsen             if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
27846a599222SSimon L. B. Nielsen                 return 0;
27856a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
27866a599222SSimon L. B. Nielsen         }
27871f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
27886f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
27896f9291ceSJung-uk Kim             switch (data[0]) {
27901f13597dSJung-uk Kim             case 0x01:         /* Server allows us to send HB requests */
27911f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
27921f13597dSJung-uk Kim                 break;
27931f13597dSJung-uk Kim             case 0x02:         /* Server doesn't accept HB requests */
27941f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
27951f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
27961f13597dSJung-uk Kim                 break;
27976f9291ceSJung-uk Kim             default:
27986f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
27991f13597dSJung-uk Kim                 return 0;
28001f13597dSJung-uk Kim             }
28011f13597dSJung-uk Kim         }
28021f13597dSJung-uk Kim # endif
280309286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
28046f9291ceSJung-uk Kim         else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
28056f9291ceSJung-uk Kim             if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al))
28061f13597dSJung-uk Kim                 return 0;
28071f13597dSJung-uk Kim         }
280809286989SJung-uk Kim # endif
28097bded2dbSJung-uk Kim         /*
28107bded2dbSJung-uk Kim          * If this extension type was not otherwise handled, but matches a
28117bded2dbSJung-uk Kim          * custom_cli_ext_record, then send it to the c callback
28127bded2dbSJung-uk Kim          */
28137bded2dbSJung-uk Kim         else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
28147bded2dbSJung-uk Kim             return 0;
28151f13597dSJung-uk Kim 
2816db522d3aSSimon L. B. Nielsen         data += size;
2817db522d3aSSimon L. B. Nielsen     }
2818db522d3aSSimon L. B. Nielsen 
28196f9291ceSJung-uk Kim     if (data != d + n) {
2820db522d3aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
2821db522d3aSSimon L. B. Nielsen         return 0;
2822db522d3aSSimon L. B. Nielsen     }
2823db522d3aSSimon L. B. Nielsen 
28246f9291ceSJung-uk Kim     if (!s->hit && tlsext_servername == 1) {
28256f9291ceSJung-uk Kim         if (s->tlsext_hostname) {
28266f9291ceSJung-uk Kim             if (s->session->tlsext_hostname == NULL) {
2827db522d3aSSimon L. B. Nielsen                 s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
28286f9291ceSJung-uk Kim                 if (!s->session->tlsext_hostname) {
2829db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_UNRECOGNIZED_NAME;
2830db522d3aSSimon L. B. Nielsen                     return 0;
2831db522d3aSSimon L. B. Nielsen                 }
28326f9291ceSJung-uk Kim             } else {
2833db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
2834db522d3aSSimon L. B. Nielsen                 return 0;
2835db522d3aSSimon L. B. Nielsen             }
2836db522d3aSSimon L. B. Nielsen         }
2837db522d3aSSimon L. B. Nielsen     }
2838db522d3aSSimon L. B. Nielsen 
2839db522d3aSSimon L. B. Nielsen     *p = data;
28406a599222SSimon L. B. Nielsen 
28416a599222SSimon L. B. Nielsen  ri_check:
28426a599222SSimon L. B. Nielsen 
28436f9291ceSJung-uk Kim     /*
28446f9291ceSJung-uk Kim      * Determine if we need to see RI. Strictly speaking if we want to avoid
28456f9291ceSJung-uk Kim      * an attack we should *always* see RI even on initial server hello
28466f9291ceSJung-uk Kim      * because the client doesn't see any renegotiation during an attack.
28476f9291ceSJung-uk Kim      * However this would mean we could not connect to any server which
28486f9291ceSJung-uk Kim      * doesn't support RI so for the immediate future tolerate RI absence on
28496f9291ceSJung-uk Kim      * initial connect only.
28506a599222SSimon L. B. Nielsen      */
28516f9291ceSJung-uk Kim     if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
28526f9291ceSJung-uk Kim         && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
28536a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
28547bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
28556a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
28566a599222SSimon L. B. Nielsen         return 0;
28576a599222SSimon L. B. Nielsen     }
28586a599222SSimon L. B. Nielsen 
2859db522d3aSSimon L. B. Nielsen     return 1;
2860db522d3aSSimon L. B. Nielsen }
2861db522d3aSSimon L. B. Nielsen 
28621f13597dSJung-uk Kim int ssl_prepare_clienthello_tlsext(SSL *s)
28631f13597dSJung-uk Kim {
28641f13597dSJung-uk Kim 
28651f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
28661f13597dSJung-uk Kim     {
28671f13597dSJung-uk Kim         int r = 1;
28681f13597dSJung-uk Kim 
28696f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
28706f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
28716f9291ceSJung-uk Kim                                                          s->
28726f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
28731f13597dSJung-uk Kim             if (!r)
28741f13597dSJung-uk Kim                 return -1;
28751f13597dSJung-uk Kim         }
28761f13597dSJung-uk Kim 
28776f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
28786f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
28796f9291ceSJung-uk Kim                 /* shouldn't really happen */
28801f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
28816f9291ceSJung-uk Kim             }
28821f13597dSJung-uk Kim 
28836f9291ceSJung-uk Kim             if (s->tlsext_opaque_prf_input_len == 0) {
28846f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
28856f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
28866f9291ceSJung-uk Kim             } else {
28876f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
28886f9291ceSJung-uk Kim                     BUF_memdup(s->tlsext_opaque_prf_input,
28896f9291ceSJung-uk Kim                                s->tlsext_opaque_prf_input_len);
28906f9291ceSJung-uk Kim             }
28916f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
28926f9291ceSJung-uk Kim                 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
28936f9291ceSJung-uk Kim                        ERR_R_MALLOC_FAILURE);
28941f13597dSJung-uk Kim                 return -1;
28951f13597dSJung-uk Kim             }
28966f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len =
28976f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
28981f13597dSJung-uk Kim         }
28991f13597dSJung-uk Kim 
29001f13597dSJung-uk Kim         if (r == 2)
29016f9291ceSJung-uk Kim             /*
29026f9291ceSJung-uk Kim              * at callback's request, insist on receiving an appropriate
29036f9291ceSJung-uk Kim              * server opaque PRF input
29046f9291ceSJung-uk Kim              */
29056f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len =
29066f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
29071f13597dSJung-uk Kim     }
29081f13597dSJung-uk Kim # endif
29091f13597dSJung-uk Kim 
2910b8721c16SJung-uk Kim     s->cert->alpn_sent = 0;
29111f13597dSJung-uk Kim     return 1;
29121f13597dSJung-uk Kim }
29131f13597dSJung-uk Kim 
29141f13597dSJung-uk Kim int ssl_prepare_serverhello_tlsext(SSL *s)
29151f13597dSJung-uk Kim {
29161f13597dSJung-uk Kim     return 1;
29171f13597dSJung-uk Kim }
29181f13597dSJung-uk Kim 
29197bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s)
2920db522d3aSSimon L. B. Nielsen {
2921db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
2922db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
2923db522d3aSSimon L. B. Nielsen 
29241f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
29256f9291ceSJung-uk Kim     /*
29266f9291ceSJung-uk Kim      * The handling of the ECPointFormats extension is done elsewhere, namely
29276f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
29281f13597dSJung-uk Kim      */
29296f9291ceSJung-uk Kim     /*
29306f9291ceSJung-uk Kim      * The handling of the EllipticCurves extension is done elsewhere, namely
29316f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
29321f13597dSJung-uk Kim      */
29331f13597dSJung-uk Kim # endif
29341f13597dSJung-uk Kim 
2935db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
29366f9291ceSJung-uk Kim         ret =
29376f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
29386f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
29396f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
29406f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
29416f9291ceSJung-uk Kim         ret =
29426f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
29436f9291ceSJung-uk Kim                                                        s->
29446f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
2945db522d3aSSimon L. B. Nielsen 
29461f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
29471f13597dSJung-uk Kim     {
29486f9291ceSJung-uk Kim         /*
29496f9291ceSJung-uk Kim          * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we
29506f9291ceSJung-uk Kim          * might be sending an alert in response to the client hello, so this
29516f9291ceSJung-uk Kim          * has to happen here in ssl_check_clienthello_tlsext_early().
29526f9291ceSJung-uk Kim          */
29531f13597dSJung-uk Kim 
29541f13597dSJung-uk Kim         int r = 1;
29551f13597dSJung-uk Kim 
29566f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
29576f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
29586f9291ceSJung-uk Kim                                                          s->
29596f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
29606f9291ceSJung-uk Kim             if (!r) {
29611f13597dSJung-uk Kim                 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
29621f13597dSJung-uk Kim                 al = SSL_AD_INTERNAL_ERROR;
29631f13597dSJung-uk Kim                 goto err;
29641f13597dSJung-uk Kim             }
29651f13597dSJung-uk Kim         }
29661f13597dSJung-uk Kim 
29676f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input != NULL) {
29686f9291ceSJung-uk Kim             /* shouldn't really happen */
29691f13597dSJung-uk Kim             OPENSSL_free(s->s3->server_opaque_prf_input);
29706f9291ceSJung-uk Kim         }
29711f13597dSJung-uk Kim         s->s3->server_opaque_prf_input = NULL;
29721f13597dSJung-uk Kim 
29736f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
29741f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL &&
29756f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input_len ==
29766f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len) {
29776f9291ceSJung-uk Kim                 /*
29786f9291ceSJung-uk Kim                  * can only use this extension if we have a server opaque PRF
29796f9291ceSJung-uk Kim                  * input of the same length as the client opaque PRF input!
29806f9291ceSJung-uk Kim                  */
29811f13597dSJung-uk Kim 
29826f9291ceSJung-uk Kim                 if (s->tlsext_opaque_prf_input_len == 0) {
29836f9291ceSJung-uk Kim                     /* dummy byte just to get non-NULL */
29846f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
29856f9291ceSJung-uk Kim                 } else {
29866f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input =
29876f9291ceSJung-uk Kim                         BUF_memdup(s->tlsext_opaque_prf_input,
29886f9291ceSJung-uk Kim                                    s->tlsext_opaque_prf_input_len);
29896f9291ceSJung-uk Kim                 }
29906f9291ceSJung-uk Kim                 if (s->s3->server_opaque_prf_input == NULL) {
29911f13597dSJung-uk Kim                     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
29921f13597dSJung-uk Kim                     al = SSL_AD_INTERNAL_ERROR;
29931f13597dSJung-uk Kim                     goto err;
29941f13597dSJung-uk Kim                 }
29956f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input_len =
29966f9291ceSJung-uk Kim                     s->tlsext_opaque_prf_input_len;
29971f13597dSJung-uk Kim             }
29981f13597dSJung-uk Kim         }
29991f13597dSJung-uk Kim 
30006f9291ceSJung-uk Kim         if (r == 2 && s->s3->server_opaque_prf_input == NULL) {
30016f9291ceSJung-uk Kim             /*
30026f9291ceSJung-uk Kim              * The callback wants to enforce use of the extension, but we
30036f9291ceSJung-uk Kim              * can't do that with the client opaque PRF input; abort the
30046f9291ceSJung-uk Kim              * handshake.
30051f13597dSJung-uk Kim              */
30061f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
30071f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
30081f13597dSJung-uk Kim         }
30091f13597dSJung-uk Kim     }
30101f13597dSJung-uk Kim 
3011db522d3aSSimon L. B. Nielsen  err:
301209286989SJung-uk Kim # endif
30136f9291ceSJung-uk Kim     switch (ret) {
3014db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
3015db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
3016db522d3aSSimon L. B. Nielsen         return -1;
3017db522d3aSSimon L. B. Nielsen 
3018db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
3019db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
3020db522d3aSSimon L. B. Nielsen         return 1;
3021db522d3aSSimon L. B. Nielsen 
3022db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
3023db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
3024db522d3aSSimon L. B. Nielsen     default:
3025db522d3aSSimon L. B. Nielsen         return 1;
3026db522d3aSSimon L. B. Nielsen     }
3027db522d3aSSimon L. B. Nielsen }
3028db522d3aSSimon L. B. Nielsen 
30297bded2dbSJung-uk Kim int tls1_set_server_sigalgs(SSL *s)
30307bded2dbSJung-uk Kim {
30317bded2dbSJung-uk Kim     int al;
30327bded2dbSJung-uk Kim     size_t i;
30337bded2dbSJung-uk Kim     /* Clear any shared sigtnature algorithms */
30347bded2dbSJung-uk Kim     if (s->cert->shared_sigalgs) {
30357bded2dbSJung-uk Kim         OPENSSL_free(s->cert->shared_sigalgs);
30367bded2dbSJung-uk Kim         s->cert->shared_sigalgs = NULL;
30377bded2dbSJung-uk Kim         s->cert->shared_sigalgslen = 0;
30387bded2dbSJung-uk Kim     }
30397bded2dbSJung-uk Kim     /* Clear certificate digests and validity flags */
30407bded2dbSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
30417bded2dbSJung-uk Kim         s->cert->pkeys[i].digest = NULL;
30427bded2dbSJung-uk Kim         s->cert->pkeys[i].valid_flags = 0;
30437bded2dbSJung-uk Kim     }
30447bded2dbSJung-uk Kim 
30457bded2dbSJung-uk Kim     /* If sigalgs received process it. */
30467bded2dbSJung-uk Kim     if (s->cert->peer_sigalgs) {
30477bded2dbSJung-uk Kim         if (!tls1_process_sigalgs(s)) {
30487bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
30497bded2dbSJung-uk Kim             al = SSL_AD_INTERNAL_ERROR;
30507bded2dbSJung-uk Kim             goto err;
30517bded2dbSJung-uk Kim         }
30527bded2dbSJung-uk Kim         /* Fatal error is no shared signature algorithms */
30537bded2dbSJung-uk Kim         if (!s->cert->shared_sigalgs) {
30547bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
30557bded2dbSJung-uk Kim                    SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
30567bded2dbSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
30577bded2dbSJung-uk Kim             goto err;
30587bded2dbSJung-uk Kim         }
30597bded2dbSJung-uk Kim     } else
30607bded2dbSJung-uk Kim         ssl_cert_set_default_md(s->cert);
30617bded2dbSJung-uk Kim     return 1;
30627bded2dbSJung-uk Kim  err:
30637bded2dbSJung-uk Kim     ssl3_send_alert(s, SSL3_AL_FATAL, al);
30647bded2dbSJung-uk Kim     return 0;
30657bded2dbSJung-uk Kim }
30667bded2dbSJung-uk Kim 
306709286989SJung-uk Kim int ssl_check_clienthello_tlsext_late(SSL *s)
306809286989SJung-uk Kim {
306909286989SJung-uk Kim     int ret = SSL_TLSEXT_ERR_OK;
307009286989SJung-uk Kim     int al;
307109286989SJung-uk Kim 
30726f9291ceSJung-uk Kim     /*
30736f9291ceSJung-uk Kim      * If status request then ask callback what to do. Note: this must be
30747bded2dbSJung-uk Kim      * called after servername callbacks in case the certificate has changed,
30757bded2dbSJung-uk Kim      * and must be called after the cipher has been chosen because this may
30767bded2dbSJung-uk Kim      * influence which certificate is sent
307709286989SJung-uk Kim      */
30786f9291ceSJung-uk Kim     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
307909286989SJung-uk Kim         int r;
308009286989SJung-uk Kim         CERT_PKEY *certpkey;
308109286989SJung-uk Kim         certpkey = ssl_get_server_send_pkey(s);
308209286989SJung-uk Kim         /* If no certificate can't return certificate status */
30836f9291ceSJung-uk Kim         if (certpkey == NULL) {
308409286989SJung-uk Kim             s->tlsext_status_expected = 0;
308509286989SJung-uk Kim             return 1;
308609286989SJung-uk Kim         }
30876f9291ceSJung-uk Kim         /*
30886f9291ceSJung-uk Kim          * Set current certificate to one we will use so SSL_get_certificate
30896f9291ceSJung-uk Kim          * et al can pick it up.
309009286989SJung-uk Kim          */
309109286989SJung-uk Kim         s->cert->key = certpkey;
309209286989SJung-uk Kim         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
30936f9291ceSJung-uk Kim         switch (r) {
309409286989SJung-uk Kim             /* We don't want to send a status request response */
309509286989SJung-uk Kim         case SSL_TLSEXT_ERR_NOACK:
309609286989SJung-uk Kim             s->tlsext_status_expected = 0;
309709286989SJung-uk Kim             break;
309809286989SJung-uk Kim             /* status request response should be sent */
309909286989SJung-uk Kim         case SSL_TLSEXT_ERR_OK:
310009286989SJung-uk Kim             if (s->tlsext_ocsp_resp)
310109286989SJung-uk Kim                 s->tlsext_status_expected = 1;
310209286989SJung-uk Kim             else
310309286989SJung-uk Kim                 s->tlsext_status_expected = 0;
310409286989SJung-uk Kim             break;
310509286989SJung-uk Kim             /* something bad happened */
310609286989SJung-uk Kim         case SSL_TLSEXT_ERR_ALERT_FATAL:
310709286989SJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
310809286989SJung-uk Kim             al = SSL_AD_INTERNAL_ERROR;
310909286989SJung-uk Kim             goto err;
311009286989SJung-uk Kim         }
31116f9291ceSJung-uk Kim     } else
311209286989SJung-uk Kim         s->tlsext_status_expected = 0;
311309286989SJung-uk Kim 
3114b8721c16SJung-uk Kim     if (!tls1_alpn_handle_client_hello_late(s, &ret, &al)) {
3115b8721c16SJung-uk Kim         goto err;
3116b8721c16SJung-uk Kim     }
3117b8721c16SJung-uk Kim 
311809286989SJung-uk Kim  err:
31196f9291ceSJung-uk Kim     switch (ret) {
312009286989SJung-uk Kim     case SSL_TLSEXT_ERR_ALERT_FATAL:
312109286989SJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
312209286989SJung-uk Kim         return -1;
312309286989SJung-uk Kim 
312409286989SJung-uk Kim     case SSL_TLSEXT_ERR_ALERT_WARNING:
312509286989SJung-uk Kim         ssl3_send_alert(s, SSL3_AL_WARNING, al);
312609286989SJung-uk Kim         return 1;
312709286989SJung-uk Kim 
312809286989SJung-uk Kim     default:
312909286989SJung-uk Kim         return 1;
313009286989SJung-uk Kim     }
313109286989SJung-uk Kim }
313209286989SJung-uk Kim 
3133db522d3aSSimon L. B. Nielsen int ssl_check_serverhello_tlsext(SSL *s)
3134db522d3aSSimon L. B. Nielsen {
3135db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
3136db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
3137db522d3aSSimon L. B. Nielsen 
31381f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
31396f9291ceSJung-uk Kim     /*
31406f9291ceSJung-uk Kim      * If we are client and using an elliptic curve cryptography cipher
31416f9291ceSJung-uk Kim      * suite, then if server returns an EC point formats lists extension it
31426f9291ceSJung-uk Kim      * must contain uncompressed.
31431f13597dSJung-uk Kim      */
31441f13597dSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
31451f13597dSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
31466f9291ceSJung-uk Kim     if ((s->tlsext_ecpointformatlist != NULL)
31476f9291ceSJung-uk Kim         && (s->tlsext_ecpointformatlist_length > 0)
31486f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist != NULL)
31496f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist_length > 0)
31506f9291ceSJung-uk Kim         && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
31516f9291ceSJung-uk Kim             || (alg_a & SSL_aECDSA))) {
31521f13597dSJung-uk Kim         /* we are using an ECC cipher */
31531f13597dSJung-uk Kim         size_t i;
31541f13597dSJung-uk Kim         unsigned char *list;
31551f13597dSJung-uk Kim         int found_uncompressed = 0;
31561f13597dSJung-uk Kim         list = s->session->tlsext_ecpointformatlist;
31576f9291ceSJung-uk Kim         for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
31586f9291ceSJung-uk Kim             if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
31591f13597dSJung-uk Kim                 found_uncompressed = 1;
31601f13597dSJung-uk Kim                 break;
31611f13597dSJung-uk Kim             }
31621f13597dSJung-uk Kim         }
31636f9291ceSJung-uk Kim         if (!found_uncompressed) {
31646f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
31656f9291ceSJung-uk Kim                    SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
31661f13597dSJung-uk Kim             return -1;
31671f13597dSJung-uk Kim         }
31681f13597dSJung-uk Kim     }
31691f13597dSJung-uk Kim     ret = SSL_TLSEXT_ERR_OK;
31701f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
31711f13597dSJung-uk Kim 
3172db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
31736f9291ceSJung-uk Kim         ret =
31746f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
31756f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
31766f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
31776f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
31786f9291ceSJung-uk Kim         ret =
31796f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
31806f9291ceSJung-uk Kim                                                        s->
31816f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
3182db522d3aSSimon L. B. Nielsen 
31831f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
31846f9291ceSJung-uk Kim     if (s->s3->server_opaque_prf_input_len > 0) {
31856f9291ceSJung-uk Kim         /*
31866f9291ceSJung-uk Kim          * This case may indicate that we, as a client, want to insist on
31876f9291ceSJung-uk Kim          * using opaque PRF inputs. So first verify that we really have a
31886f9291ceSJung-uk Kim          * value from the server too.
31896f9291ceSJung-uk Kim          */
31901f13597dSJung-uk Kim 
31916f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input == NULL) {
31921f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
31931f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
31941f13597dSJung-uk Kim         }
31951f13597dSJung-uk Kim 
31966f9291ceSJung-uk Kim         /*
31976f9291ceSJung-uk Kim          * Anytime the server *has* sent an opaque PRF input, we need to
31986f9291ceSJung-uk Kim          * check that we have a client opaque PRF input of the same size.
31996f9291ceSJung-uk Kim          */
32001f13597dSJung-uk Kim         if (s->s3->client_opaque_prf_input == NULL ||
32016f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len !=
32026f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len) {
32031f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
32041f13597dSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
32051f13597dSJung-uk Kim         }
32061f13597dSJung-uk Kim     }
32071f13597dSJung-uk Kim # endif
32081f13597dSJung-uk Kim 
32098180e704SJung-uk Kim     OPENSSL_free(s->tlsext_ocsp_resp);
32108180e704SJung-uk Kim     s->tlsext_ocsp_resp = NULL;
32118180e704SJung-uk Kim     s->tlsext_ocsp_resplen = -1;
32126f9291ceSJung-uk Kim     /*
32136f9291ceSJung-uk Kim      * If we've requested certificate status and we wont get one tell the
32146f9291ceSJung-uk Kim      * callback
3215db522d3aSSimon L. B. Nielsen      */
3216db522d3aSSimon L. B. Nielsen     if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
32178180e704SJung-uk Kim         && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) {
3218db522d3aSSimon L. B. Nielsen         int r;
32196f9291ceSJung-uk Kim         /*
32208180e704SJung-uk Kim          * Call callback with resp == NULL and resplen == -1 so callback
32218180e704SJung-uk Kim          * knows there is no response
3222db522d3aSSimon L. B. Nielsen          */
3223db522d3aSSimon L. B. Nielsen         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
32246f9291ceSJung-uk Kim         if (r == 0) {
3225db522d3aSSimon L. B. Nielsen             al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
3226db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
3227db522d3aSSimon L. B. Nielsen         }
32286f9291ceSJung-uk Kim         if (r < 0) {
3229db522d3aSSimon L. B. Nielsen             al = SSL_AD_INTERNAL_ERROR;
3230db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
3231db522d3aSSimon L. B. Nielsen         }
3232db522d3aSSimon L. B. Nielsen     }
3233db522d3aSSimon L. B. Nielsen 
32346f9291ceSJung-uk Kim     switch (ret) {
3235db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
3236db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
3237db522d3aSSimon L. B. Nielsen         return -1;
3238db522d3aSSimon L. B. Nielsen 
3239db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
3240db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
3241db522d3aSSimon L. B. Nielsen         return 1;
3242db522d3aSSimon L. B. Nielsen 
3243db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
3244db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
3245db522d3aSSimon L. B. Nielsen     default:
3246db522d3aSSimon L. B. Nielsen         return 1;
3247db522d3aSSimon L. B. Nielsen     }
3248db522d3aSSimon L. B. Nielsen }
3249db522d3aSSimon L. B. Nielsen 
32507bded2dbSJung-uk Kim int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
32517bded2dbSJung-uk Kim                                  int n)
32527bded2dbSJung-uk Kim {
32537bded2dbSJung-uk Kim     int al = -1;
32547bded2dbSJung-uk Kim     if (s->version < SSL3_VERSION)
32557bded2dbSJung-uk Kim         return 1;
32567bded2dbSJung-uk Kim     if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) {
32577bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
32587bded2dbSJung-uk Kim         return 0;
32597bded2dbSJung-uk Kim     }
32607bded2dbSJung-uk Kim 
32617bded2dbSJung-uk Kim     if (ssl_check_serverhello_tlsext(s) <= 0) {
32627bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
32637bded2dbSJung-uk Kim         return 0;
32647bded2dbSJung-uk Kim     }
32657bded2dbSJung-uk Kim     return 1;
32667bded2dbSJung-uk Kim }
32677bded2dbSJung-uk Kim 
32686f9291ceSJung-uk Kim /*-
32696f9291ceSJung-uk Kim  * Since the server cache lookup is done early on in the processing of the
32701f13597dSJung-uk Kim  * ClientHello, and other operations depend on the result, we need to handle
32711f13597dSJung-uk Kim  * any TLS session ticket extension at the same time.
32721f13597dSJung-uk Kim  *
32731f13597dSJung-uk Kim  *   session_id: points at the session ID in the ClientHello. This code will
32741f13597dSJung-uk Kim  *       read past the end of this in order to parse out the session ticket
32751f13597dSJung-uk Kim  *       extension, if any.
32761f13597dSJung-uk Kim  *   len: the length of the session ID.
32771f13597dSJung-uk Kim  *   limit: a pointer to the first byte after the ClientHello.
32781f13597dSJung-uk Kim  *   ret: (output) on return, if a ticket was decrypted, then this is set to
32791f13597dSJung-uk Kim  *       point to the resulting session.
32801f13597dSJung-uk Kim  *
32811f13597dSJung-uk Kim  * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
32821f13597dSJung-uk Kim  * ciphersuite, in which case we have no use for session tickets and one will
32831f13597dSJung-uk Kim  * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
32841f13597dSJung-uk Kim  *
32851f13597dSJung-uk Kim  * Returns:
32861f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
32871f13597dSJung-uk Kim  *    0: no ticket was found (or was ignored, based on settings).
32881f13597dSJung-uk Kim  *    1: a zero length extension was found, indicating that the client supports
32891f13597dSJung-uk Kim  *       session tickets but doesn't currently have one to offer.
32901f13597dSJung-uk Kim  *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
32911f13597dSJung-uk Kim  *       couldn't be decrypted because of a non-fatal error.
32921f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *ret was set.
32931f13597dSJung-uk Kim  *
32941f13597dSJung-uk Kim  * Side effects:
32951f13597dSJung-uk Kim  *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
32961f13597dSJung-uk Kim  *   a new session ticket to the client because the client indicated support
32971f13597dSJung-uk Kim  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
32981f13597dSJung-uk Kim  *   a session ticket or we couldn't use the one it gave us, or if
32991f13597dSJung-uk Kim  *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
33001f13597dSJung-uk Kim  *   Otherwise, s->tlsext_ticket_expected is set to 0.
3301db522d3aSSimon L. B. Nielsen  */
3302db522d3aSSimon L. B. Nielsen int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
3303db522d3aSSimon L. B. Nielsen                         const unsigned char *limit, SSL_SESSION **ret)
3304db522d3aSSimon L. B. Nielsen {
3305db522d3aSSimon L. B. Nielsen     /* Point after session ID in client hello */
3306db522d3aSSimon L. B. Nielsen     const unsigned char *p = session_id + len;
3307db522d3aSSimon L. B. Nielsen     unsigned short i;
3308db522d3aSSimon L. B. Nielsen 
33091f13597dSJung-uk Kim     *ret = NULL;
33101f13597dSJung-uk Kim     s->tlsext_ticket_expected = 0;
33111f13597dSJung-uk Kim 
33126f9291ceSJung-uk Kim     /*
33136f9291ceSJung-uk Kim      * If tickets disabled behave as if no ticket present to permit stateful
33146f9291ceSJung-uk Kim      * resumption.
3315db522d3aSSimon L. B. Nielsen      */
3316db522d3aSSimon L. B. Nielsen     if (SSL_get_options(s) & SSL_OP_NO_TICKET)
33171f13597dSJung-uk Kim         return 0;
3318db522d3aSSimon L. B. Nielsen     if ((s->version <= SSL3_VERSION) || !limit)
33191f13597dSJung-uk Kim         return 0;
3320db522d3aSSimon L. B. Nielsen     if (p >= limit)
3321db522d3aSSimon L. B. Nielsen         return -1;
33226a599222SSimon L. B. Nielsen     /* Skip past DTLS cookie */
33237bded2dbSJung-uk Kim     if (SSL_IS_DTLS(s)) {
33246a599222SSimon L. B. Nielsen         i = *(p++);
3325*aeb5019cSJung-uk Kim 
3326*aeb5019cSJung-uk Kim         if (limit - p <= i)
33276a599222SSimon L. B. Nielsen             return -1;
3328*aeb5019cSJung-uk Kim 
3329*aeb5019cSJung-uk Kim         p += i;
33306a599222SSimon L. B. Nielsen     }
3331db522d3aSSimon L. B. Nielsen     /* Skip past cipher list */
3332db522d3aSSimon L. B. Nielsen     n2s(p, i);
3333*aeb5019cSJung-uk Kim     if (limit - p <= i)
3334db522d3aSSimon L. B. Nielsen         return -1;
3335*aeb5019cSJung-uk Kim     p += i;
3336*aeb5019cSJung-uk Kim 
3337db522d3aSSimon L. B. Nielsen     /* Skip past compression algorithm list */
3338db522d3aSSimon L. B. Nielsen     i = *(p++);
3339*aeb5019cSJung-uk Kim     if (limit - p < i)
3340db522d3aSSimon L. B. Nielsen         return -1;
3341*aeb5019cSJung-uk Kim     p += i;
3342*aeb5019cSJung-uk Kim 
3343db522d3aSSimon L. B. Nielsen     /* Now at start of extensions */
3344*aeb5019cSJung-uk Kim     if (limit - p <= 2)
33451f13597dSJung-uk Kim         return 0;
3346db522d3aSSimon L. B. Nielsen     n2s(p, i);
3347*aeb5019cSJung-uk Kim     while (limit - p >= 4) {
3348db522d3aSSimon L. B. Nielsen         unsigned short type, size;
3349db522d3aSSimon L. B. Nielsen         n2s(p, type);
3350db522d3aSSimon L. B. Nielsen         n2s(p, size);
3351*aeb5019cSJung-uk Kim         if (limit - p < size)
33521f13597dSJung-uk Kim             return 0;
33536f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_session_ticket) {
33541f13597dSJung-uk Kim             int r;
33556f9291ceSJung-uk Kim             if (size == 0) {
33566f9291ceSJung-uk Kim                 /*
33576f9291ceSJung-uk Kim                  * The client will accept a ticket but doesn't currently have
33586f9291ceSJung-uk Kim                  * one.
33596f9291ceSJung-uk Kim                  */
3360db522d3aSSimon L. B. Nielsen                 s->tlsext_ticket_expected = 1;
33611f13597dSJung-uk Kim                 return 1;
3362db522d3aSSimon L. B. Nielsen             }
33636f9291ceSJung-uk Kim             if (s->tls_session_secret_cb) {
33646f9291ceSJung-uk Kim                 /*
33656f9291ceSJung-uk Kim                  * Indicate that the ticket couldn't be decrypted rather than
33666f9291ceSJung-uk Kim                  * generating the session from ticket now, trigger
33676f9291ceSJung-uk Kim                  * abbreviated handshake based on external mechanism to
33686f9291ceSJung-uk Kim                  * calculate the master secret later.
33696f9291ceSJung-uk Kim                  */
33701f13597dSJung-uk Kim                 return 2;
33711f13597dSJung-uk Kim             }
33721f13597dSJung-uk Kim             r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
33736f9291ceSJung-uk Kim             switch (r) {
33741f13597dSJung-uk Kim             case 2:            /* ticket couldn't be decrypted */
33751f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
33761f13597dSJung-uk Kim                 return 2;
33771f13597dSJung-uk Kim             case 3:            /* ticket was decrypted */
33781f13597dSJung-uk Kim                 return r;
33791f13597dSJung-uk Kim             case 4:            /* ticket decrypted but need to renew */
33801f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
33811f13597dSJung-uk Kim                 return 3;
33821f13597dSJung-uk Kim             default:           /* fatal error */
33831f13597dSJung-uk Kim                 return -1;
33841f13597dSJung-uk Kim             }
3385db522d3aSSimon L. B. Nielsen         }
3386db522d3aSSimon L. B. Nielsen         p += size;
3387db522d3aSSimon L. B. Nielsen     }
33881f13597dSJung-uk Kim     return 0;
3389db522d3aSSimon L. B. Nielsen }
3390db522d3aSSimon L. B. Nielsen 
33916f9291ceSJung-uk Kim /*-
33926f9291ceSJung-uk Kim  * tls_decrypt_ticket attempts to decrypt a session ticket.
33931f13597dSJung-uk Kim  *
33941f13597dSJung-uk Kim  *   etick: points to the body of the session ticket extension.
33951f13597dSJung-uk Kim  *   eticklen: the length of the session tickets extenion.
33961f13597dSJung-uk Kim  *   sess_id: points at the session ID.
33971f13597dSJung-uk Kim  *   sesslen: the length of the session ID.
33981f13597dSJung-uk Kim  *   psess: (output) on return, if a ticket was decrypted, then this is set to
33991f13597dSJung-uk Kim  *       point to the resulting session.
34001f13597dSJung-uk Kim  *
34011f13597dSJung-uk Kim  * Returns:
34021f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
34031f13597dSJung-uk Kim  *    2: the ticket couldn't be decrypted.
34041f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *psess was set.
34051f13597dSJung-uk Kim  *    4: same as 3, but the ticket needs to be renewed.
34061f13597dSJung-uk Kim  */
34076f9291ceSJung-uk Kim static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
34086f9291ceSJung-uk Kim                               int eticklen, const unsigned char *sess_id,
34096f9291ceSJung-uk Kim                               int sesslen, SSL_SESSION **psess)
3410db522d3aSSimon L. B. Nielsen {
3411db522d3aSSimon L. B. Nielsen     SSL_SESSION *sess;
3412db522d3aSSimon L. B. Nielsen     unsigned char *sdec;
3413db522d3aSSimon L. B. Nielsen     const unsigned char *p;
3414db522d3aSSimon L. B. Nielsen     int slen, mlen, renew_ticket = 0;
3415db522d3aSSimon L. B. Nielsen     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
3416db522d3aSSimon L. B. Nielsen     HMAC_CTX hctx;
3417db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX ctx;
34186a599222SSimon L. B. Nielsen     SSL_CTX *tctx = s->initial_ctx;
3419*aeb5019cSJung-uk Kim 
3420db522d3aSSimon L. B. Nielsen     /* Initialize session ticket encryption and HMAC contexts */
3421db522d3aSSimon L. B. Nielsen     HMAC_CTX_init(&hctx);
3422db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_init(&ctx);
34236f9291ceSJung-uk Kim     if (tctx->tlsext_ticket_key_cb) {
3424db522d3aSSimon L. B. Nielsen         unsigned char *nctick = (unsigned char *)etick;
34256a599222SSimon L. B. Nielsen         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
3426db522d3aSSimon L. B. Nielsen                                             &ctx, &hctx, 0);
3427db522d3aSSimon L. B. Nielsen         if (rv < 0)
3428db522d3aSSimon L. B. Nielsen             return -1;
3429db522d3aSSimon L. B. Nielsen         if (rv == 0)
34301f13597dSJung-uk Kim             return 2;
3431db522d3aSSimon L. B. Nielsen         if (rv == 2)
3432db522d3aSSimon L. B. Nielsen             renew_ticket = 1;
34336f9291ceSJung-uk Kim     } else {
3434db522d3aSSimon L. B. Nielsen         /* Check key name matches */
34356a599222SSimon L. B. Nielsen         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
34361f13597dSJung-uk Kim             return 2;
343780815a77SJung-uk Kim         if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
343880815a77SJung-uk Kim                          tlsext_tick_md(), NULL) <= 0
343980815a77SJung-uk Kim                 || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
344080815a77SJung-uk Kim                                       tctx->tlsext_tick_aes_key,
344180815a77SJung-uk Kim                                       etick + 16) <= 0) {
344280815a77SJung-uk Kim             goto err;
344380815a77SJung-uk Kim        }
3444db522d3aSSimon L. B. Nielsen     }
34456f9291ceSJung-uk Kim     /*
34466f9291ceSJung-uk Kim      * Attempt to process session ticket, first conduct sanity and integrity
34476f9291ceSJung-uk Kim      * checks on ticket.
3448db522d3aSSimon L. B. Nielsen      */
3449db522d3aSSimon L. B. Nielsen     mlen = HMAC_size(&hctx);
34506f9291ceSJung-uk Kim     if (mlen < 0) {
345180815a77SJung-uk Kim         goto err;
34521f13597dSJung-uk Kim     }
3453*aeb5019cSJung-uk Kim     /* Sanity check ticket length: must exceed keyname + IV + HMAC */
3454*aeb5019cSJung-uk Kim     if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) {
3455*aeb5019cSJung-uk Kim         HMAC_CTX_cleanup(&hctx);
3456*aeb5019cSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
3457*aeb5019cSJung-uk Kim         return 2;
3458*aeb5019cSJung-uk Kim     }
3459*aeb5019cSJung-uk Kim 
3460db522d3aSSimon L. B. Nielsen     eticklen -= mlen;
3461db522d3aSSimon L. B. Nielsen     /* Check HMAC of encrypted ticket */
346280815a77SJung-uk Kim     if (HMAC_Update(&hctx, etick, eticklen) <= 0
346380815a77SJung-uk Kim             || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
346480815a77SJung-uk Kim         goto err;
346580815a77SJung-uk Kim     }
3466db522d3aSSimon L. B. Nielsen     HMAC_CTX_cleanup(&hctx);
34676f9291ceSJung-uk Kim     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
3468fa5fddf1SJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
34691f13597dSJung-uk Kim         return 2;
3470fa5fddf1SJung-uk Kim     }
3471db522d3aSSimon L. B. Nielsen     /* Attempt to decrypt session data */
3472db522d3aSSimon L. B. Nielsen     /* Move p after IV to start of encrypted ticket, update length */
3473db522d3aSSimon L. B. Nielsen     p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
3474db522d3aSSimon L. B. Nielsen     eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
3475db522d3aSSimon L. B. Nielsen     sdec = OPENSSL_malloc(eticklen);
3476b8721c16SJung-uk Kim     if (sdec == NULL
3477b8721c16SJung-uk Kim             || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
3478db522d3aSSimon L. B. Nielsen         EVP_CIPHER_CTX_cleanup(&ctx);
3479b8721c16SJung-uk Kim         OPENSSL_free(sdec);
3480db522d3aSSimon L. B. Nielsen         return -1;
3481db522d3aSSimon L. B. Nielsen     }
34826f9291ceSJung-uk Kim     if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
3483a93cbc2bSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
3484a93cbc2bSJung-uk Kim         OPENSSL_free(sdec);
34851f13597dSJung-uk Kim         return 2;
3486a93cbc2bSJung-uk Kim     }
3487db522d3aSSimon L. B. Nielsen     slen += mlen;
3488db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_cleanup(&ctx);
3489db522d3aSSimon L. B. Nielsen     p = sdec;
3490db522d3aSSimon L. B. Nielsen 
3491db522d3aSSimon L. B. Nielsen     sess = d2i_SSL_SESSION(NULL, &p, slen);
3492db522d3aSSimon L. B. Nielsen     OPENSSL_free(sdec);
34936f9291ceSJung-uk Kim     if (sess) {
34946f9291ceSJung-uk Kim         /*
34956f9291ceSJung-uk Kim          * The session ID, if non-empty, is used by some clients to detect
34966f9291ceSJung-uk Kim          * that the ticket has been accepted. So we copy it to the session
34976f9291ceSJung-uk Kim          * structure. If it is empty set length to zero as required by
34986f9291ceSJung-uk Kim          * standard.
3499db522d3aSSimon L. B. Nielsen          */
3500db522d3aSSimon L. B. Nielsen         if (sesslen)
3501db522d3aSSimon L. B. Nielsen             memcpy(sess->session_id, sess_id, sesslen);
3502db522d3aSSimon L. B. Nielsen         sess->session_id_length = sesslen;
3503db522d3aSSimon L. B. Nielsen         *psess = sess;
35041f13597dSJung-uk Kim         if (renew_ticket)
35051f13597dSJung-uk Kim             return 4;
35061f13597dSJung-uk Kim         else
35071f13597dSJung-uk Kim             return 3;
35081f13597dSJung-uk Kim     }
35091f13597dSJung-uk Kim     ERR_clear_error();
35106f9291ceSJung-uk Kim     /*
35116f9291ceSJung-uk Kim      * For session parse failure, indicate that we need to send a new ticket.
35126f9291ceSJung-uk Kim      */
35131f13597dSJung-uk Kim     return 2;
351480815a77SJung-uk Kim err:
351580815a77SJung-uk Kim     EVP_CIPHER_CTX_cleanup(&ctx);
351680815a77SJung-uk Kim     HMAC_CTX_cleanup(&hctx);
351780815a77SJung-uk Kim     return -1;
35181f13597dSJung-uk Kim }
35191f13597dSJung-uk Kim 
35201f13597dSJung-uk Kim /* Tables to translate from NIDs to TLS v1.2 ids */
35211f13597dSJung-uk Kim 
35226f9291ceSJung-uk Kim typedef struct {
35231f13597dSJung-uk Kim     int nid;
35241f13597dSJung-uk Kim     int id;
35251f13597dSJung-uk Kim } tls12_lookup;
35261f13597dSJung-uk Kim 
35271f13597dSJung-uk Kim static tls12_lookup tls12_md[] = {
35281f13597dSJung-uk Kim     {NID_md5, TLSEXT_hash_md5},
35291f13597dSJung-uk Kim     {NID_sha1, TLSEXT_hash_sha1},
35301f13597dSJung-uk Kim     {NID_sha224, TLSEXT_hash_sha224},
35311f13597dSJung-uk Kim     {NID_sha256, TLSEXT_hash_sha256},
35321f13597dSJung-uk Kim     {NID_sha384, TLSEXT_hash_sha384},
35331f13597dSJung-uk Kim     {NID_sha512, TLSEXT_hash_sha512}
35341f13597dSJung-uk Kim };
35351f13597dSJung-uk Kim 
35361f13597dSJung-uk Kim static tls12_lookup tls12_sig[] = {
35371f13597dSJung-uk Kim     {EVP_PKEY_RSA, TLSEXT_signature_rsa},
35381f13597dSJung-uk Kim     {EVP_PKEY_DSA, TLSEXT_signature_dsa},
35391f13597dSJung-uk Kim     {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
35401f13597dSJung-uk Kim };
35411f13597dSJung-uk Kim 
35421f13597dSJung-uk Kim static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
35431f13597dSJung-uk Kim {
35441f13597dSJung-uk Kim     size_t i;
35456f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
35461f13597dSJung-uk Kim         if (table[i].nid == nid)
35471f13597dSJung-uk Kim             return table[i].id;
35481f13597dSJung-uk Kim     }
35491f13597dSJung-uk Kim     return -1;
35501f13597dSJung-uk Kim }
35516f9291ceSJung-uk Kim 
35521f13597dSJung-uk Kim static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
35531f13597dSJung-uk Kim {
35541f13597dSJung-uk Kim     size_t i;
35556f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
35567bded2dbSJung-uk Kim         if ((table[i].id) == id)
35571f13597dSJung-uk Kim             return table[i].nid;
35581f13597dSJung-uk Kim     }
35597bded2dbSJung-uk Kim     return NID_undef;
35601f13597dSJung-uk Kim }
35611f13597dSJung-uk Kim 
35626f9291ceSJung-uk Kim int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
35636f9291ceSJung-uk Kim                          const EVP_MD *md)
35641f13597dSJung-uk Kim {
35651f13597dSJung-uk Kim     int sig_id, md_id;
35661f13597dSJung-uk Kim     if (!md)
35671f13597dSJung-uk Kim         return 0;
35681f13597dSJung-uk Kim     md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
35691f13597dSJung-uk Kim                           sizeof(tls12_md) / sizeof(tls12_lookup));
35701f13597dSJung-uk Kim     if (md_id == -1)
35711f13597dSJung-uk Kim         return 0;
35721f13597dSJung-uk Kim     sig_id = tls12_get_sigid(pk);
35731f13597dSJung-uk Kim     if (sig_id == -1)
35741f13597dSJung-uk Kim         return 0;
35751f13597dSJung-uk Kim     p[0] = (unsigned char)md_id;
35761f13597dSJung-uk Kim     p[1] = (unsigned char)sig_id;
3577db522d3aSSimon L. B. Nielsen     return 1;
3578db522d3aSSimon L. B. Nielsen }
35791f13597dSJung-uk Kim 
35801f13597dSJung-uk Kim int tls12_get_sigid(const EVP_PKEY *pk)
35811f13597dSJung-uk Kim {
35821f13597dSJung-uk Kim     return tls12_find_id(pk->type, tls12_sig,
35831f13597dSJung-uk Kim                          sizeof(tls12_sig) / sizeof(tls12_lookup));
35841f13597dSJung-uk Kim }
35851f13597dSJung-uk Kim 
35861f13597dSJung-uk Kim const EVP_MD *tls12_get_hash(unsigned char hash_alg)
35871f13597dSJung-uk Kim {
35886f9291ceSJung-uk Kim     switch (hash_alg) {
35897bded2dbSJung-uk Kim # ifndef OPENSSL_NO_MD5
35907bded2dbSJung-uk Kim     case TLSEXT_hash_md5:
35917bded2dbSJung-uk Kim #  ifdef OPENSSL_FIPS
35927bded2dbSJung-uk Kim         if (FIPS_mode())
35937bded2dbSJung-uk Kim             return NULL;
35947bded2dbSJung-uk Kim #  endif
35957bded2dbSJung-uk Kim         return EVP_md5();
35967bded2dbSJung-uk Kim # endif
35971f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
35981f13597dSJung-uk Kim     case TLSEXT_hash_sha1:
35991f13597dSJung-uk Kim         return EVP_sha1();
36001f13597dSJung-uk Kim # endif
36011f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
36021f13597dSJung-uk Kim     case TLSEXT_hash_sha224:
36031f13597dSJung-uk Kim         return EVP_sha224();
36041f13597dSJung-uk Kim 
36051f13597dSJung-uk Kim     case TLSEXT_hash_sha256:
36061f13597dSJung-uk Kim         return EVP_sha256();
36071f13597dSJung-uk Kim # endif
36081f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
36091f13597dSJung-uk Kim     case TLSEXT_hash_sha384:
36101f13597dSJung-uk Kim         return EVP_sha384();
36111f13597dSJung-uk Kim 
36121f13597dSJung-uk Kim     case TLSEXT_hash_sha512:
36131f13597dSJung-uk Kim         return EVP_sha512();
36141f13597dSJung-uk Kim # endif
36151f13597dSJung-uk Kim     default:
36161f13597dSJung-uk Kim         return NULL;
36171f13597dSJung-uk Kim 
36181f13597dSJung-uk Kim     }
36191f13597dSJung-uk Kim }
36201f13597dSJung-uk Kim 
36217bded2dbSJung-uk Kim static int tls12_get_pkey_idx(unsigned char sig_alg)
36227bded2dbSJung-uk Kim {
36237bded2dbSJung-uk Kim     switch (sig_alg) {
36247bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA
36257bded2dbSJung-uk Kim     case TLSEXT_signature_rsa:
36267bded2dbSJung-uk Kim         return SSL_PKEY_RSA_SIGN;
36277bded2dbSJung-uk Kim # endif
36287bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA
36297bded2dbSJung-uk Kim     case TLSEXT_signature_dsa:
36307bded2dbSJung-uk Kim         return SSL_PKEY_DSA_SIGN;
36317bded2dbSJung-uk Kim # endif
36327bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
36337bded2dbSJung-uk Kim     case TLSEXT_signature_ecdsa:
36347bded2dbSJung-uk Kim         return SSL_PKEY_ECC;
36357bded2dbSJung-uk Kim # endif
36367bded2dbSJung-uk Kim     }
36377bded2dbSJung-uk Kim     return -1;
36387bded2dbSJung-uk Kim }
36397bded2dbSJung-uk Kim 
36407bded2dbSJung-uk Kim /* Convert TLS 1.2 signature algorithm extension values into NIDs */
36417bded2dbSJung-uk Kim static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
36427bded2dbSJung-uk Kim                                int *psignhash_nid, const unsigned char *data)
36437bded2dbSJung-uk Kim {
36448180e704SJung-uk Kim     int sign_nid = NID_undef, hash_nid = NID_undef;
36457bded2dbSJung-uk Kim     if (!phash_nid && !psign_nid && !psignhash_nid)
36467bded2dbSJung-uk Kim         return;
36477bded2dbSJung-uk Kim     if (phash_nid || psignhash_nid) {
36487bded2dbSJung-uk Kim         hash_nid = tls12_find_nid(data[0], tls12_md,
36497bded2dbSJung-uk Kim                                   sizeof(tls12_md) / sizeof(tls12_lookup));
36507bded2dbSJung-uk Kim         if (phash_nid)
36517bded2dbSJung-uk Kim             *phash_nid = hash_nid;
36527bded2dbSJung-uk Kim     }
36537bded2dbSJung-uk Kim     if (psign_nid || psignhash_nid) {
36547bded2dbSJung-uk Kim         sign_nid = tls12_find_nid(data[1], tls12_sig,
36557bded2dbSJung-uk Kim                                   sizeof(tls12_sig) / sizeof(tls12_lookup));
36567bded2dbSJung-uk Kim         if (psign_nid)
36577bded2dbSJung-uk Kim             *psign_nid = sign_nid;
36587bded2dbSJung-uk Kim     }
36597bded2dbSJung-uk Kim     if (psignhash_nid) {
36608180e704SJung-uk Kim         if (sign_nid == NID_undef || hash_nid == NID_undef
36618180e704SJung-uk Kim                 || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid,
36628180e704SJung-uk Kim                                           sign_nid) <= 0)
36637bded2dbSJung-uk Kim             *psignhash_nid = NID_undef;
36647bded2dbSJung-uk Kim     }
36657bded2dbSJung-uk Kim }
36667bded2dbSJung-uk Kim 
36677bded2dbSJung-uk Kim /* Given preference and allowed sigalgs set shared sigalgs */
36687bded2dbSJung-uk Kim static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig,
36697bded2dbSJung-uk Kim                                    const unsigned char *pref, size_t preflen,
36707bded2dbSJung-uk Kim                                    const unsigned char *allow,
36717bded2dbSJung-uk Kim                                    size_t allowlen)
36727bded2dbSJung-uk Kim {
36737bded2dbSJung-uk Kim     const unsigned char *ptmp, *atmp;
36747bded2dbSJung-uk Kim     size_t i, j, nmatch = 0;
36757bded2dbSJung-uk Kim     for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
36767bded2dbSJung-uk Kim         /* Skip disabled hashes or signature algorithms */
36777bded2dbSJung-uk Kim         if (tls12_get_hash(ptmp[0]) == NULL)
36787bded2dbSJung-uk Kim             continue;
36797bded2dbSJung-uk Kim         if (tls12_get_pkey_idx(ptmp[1]) == -1)
36807bded2dbSJung-uk Kim             continue;
36817bded2dbSJung-uk Kim         for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
36827bded2dbSJung-uk Kim             if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
36837bded2dbSJung-uk Kim                 nmatch++;
36847bded2dbSJung-uk Kim                 if (shsig) {
36857bded2dbSJung-uk Kim                     shsig->rhash = ptmp[0];
36867bded2dbSJung-uk Kim                     shsig->rsign = ptmp[1];
36877bded2dbSJung-uk Kim                     tls1_lookup_sigalg(&shsig->hash_nid,
36887bded2dbSJung-uk Kim                                        &shsig->sign_nid,
36897bded2dbSJung-uk Kim                                        &shsig->signandhash_nid, ptmp);
36907bded2dbSJung-uk Kim                     shsig++;
36917bded2dbSJung-uk Kim                 }
36927bded2dbSJung-uk Kim                 break;
36937bded2dbSJung-uk Kim             }
36947bded2dbSJung-uk Kim         }
36957bded2dbSJung-uk Kim     }
36967bded2dbSJung-uk Kim     return nmatch;
36977bded2dbSJung-uk Kim }
36987bded2dbSJung-uk Kim 
36997bded2dbSJung-uk Kim /* Set shared signature algorithms for SSL structures */
37007bded2dbSJung-uk Kim static int tls1_set_shared_sigalgs(SSL *s)
37017bded2dbSJung-uk Kim {
37027bded2dbSJung-uk Kim     const unsigned char *pref, *allow, *conf;
37037bded2dbSJung-uk Kim     size_t preflen, allowlen, conflen;
37047bded2dbSJung-uk Kim     size_t nmatch;
37057bded2dbSJung-uk Kim     TLS_SIGALGS *salgs = NULL;
37067bded2dbSJung-uk Kim     CERT *c = s->cert;
37077bded2dbSJung-uk Kim     unsigned int is_suiteb = tls1_suiteb(s);
37087bded2dbSJung-uk Kim     if (c->shared_sigalgs) {
37097bded2dbSJung-uk Kim         OPENSSL_free(c->shared_sigalgs);
37107bded2dbSJung-uk Kim         c->shared_sigalgs = NULL;
37117bded2dbSJung-uk Kim         c->shared_sigalgslen = 0;
37127bded2dbSJung-uk Kim     }
37137bded2dbSJung-uk Kim     /* If client use client signature algorithms if not NULL */
37147bded2dbSJung-uk Kim     if (!s->server && c->client_sigalgs && !is_suiteb) {
37157bded2dbSJung-uk Kim         conf = c->client_sigalgs;
37167bded2dbSJung-uk Kim         conflen = c->client_sigalgslen;
37177bded2dbSJung-uk Kim     } else if (c->conf_sigalgs && !is_suiteb) {
37187bded2dbSJung-uk Kim         conf = c->conf_sigalgs;
37197bded2dbSJung-uk Kim         conflen = c->conf_sigalgslen;
37207bded2dbSJung-uk Kim     } else
37217bded2dbSJung-uk Kim         conflen = tls12_get_psigalgs(s, &conf);
37227bded2dbSJung-uk Kim     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
37237bded2dbSJung-uk Kim         pref = conf;
37247bded2dbSJung-uk Kim         preflen = conflen;
37257bded2dbSJung-uk Kim         allow = c->peer_sigalgs;
37267bded2dbSJung-uk Kim         allowlen = c->peer_sigalgslen;
37277bded2dbSJung-uk Kim     } else {
37287bded2dbSJung-uk Kim         allow = conf;
37297bded2dbSJung-uk Kim         allowlen = conflen;
37307bded2dbSJung-uk Kim         pref = c->peer_sigalgs;
37317bded2dbSJung-uk Kim         preflen = c->peer_sigalgslen;
37327bded2dbSJung-uk Kim     }
37337bded2dbSJung-uk Kim     nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
37347bded2dbSJung-uk Kim     if (nmatch) {
37357bded2dbSJung-uk Kim         salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
37367bded2dbSJung-uk Kim         if (!salgs)
37377bded2dbSJung-uk Kim             return 0;
37387bded2dbSJung-uk Kim         nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
37397bded2dbSJung-uk Kim     } else {
37407bded2dbSJung-uk Kim         salgs = NULL;
37417bded2dbSJung-uk Kim     }
37427bded2dbSJung-uk Kim     c->shared_sigalgs = salgs;
37437bded2dbSJung-uk Kim     c->shared_sigalgslen = nmatch;
37447bded2dbSJung-uk Kim     return 1;
37457bded2dbSJung-uk Kim }
37467bded2dbSJung-uk Kim 
37471f13597dSJung-uk Kim /* Set preferred digest for each key type */
37481f13597dSJung-uk Kim 
37497bded2dbSJung-uk Kim int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
37501f13597dSJung-uk Kim {
37511f13597dSJung-uk Kim     CERT *c = s->cert;
37527bded2dbSJung-uk Kim     /* Extension ignored for inappropriate versions */
37537bded2dbSJung-uk Kim     if (!SSL_USE_SIGALGS(s))
37541f13597dSJung-uk Kim         return 1;
37551f13597dSJung-uk Kim     /* Should never happen */
37561f13597dSJung-uk Kim     if (!c)
37571f13597dSJung-uk Kim         return 0;
37581f13597dSJung-uk Kim 
37597bded2dbSJung-uk Kim     if (c->peer_sigalgs)
37607bded2dbSJung-uk Kim         OPENSSL_free(c->peer_sigalgs);
37617bded2dbSJung-uk Kim     c->peer_sigalgs = OPENSSL_malloc(dsize);
37627bded2dbSJung-uk Kim     if (!c->peer_sigalgs)
37637bded2dbSJung-uk Kim         return 0;
37647bded2dbSJung-uk Kim     c->peer_sigalgslen = dsize;
37657bded2dbSJung-uk Kim     memcpy(c->peer_sigalgs, data, dsize);
37667bded2dbSJung-uk Kim     return 1;
37671f13597dSJung-uk Kim }
37681f13597dSJung-uk Kim 
37697bded2dbSJung-uk Kim int tls1_process_sigalgs(SSL *s)
37707bded2dbSJung-uk Kim {
37717bded2dbSJung-uk Kim     int idx;
37727bded2dbSJung-uk Kim     size_t i;
37737bded2dbSJung-uk Kim     const EVP_MD *md;
37747bded2dbSJung-uk Kim     CERT *c = s->cert;
37757bded2dbSJung-uk Kim     TLS_SIGALGS *sigptr;
37767bded2dbSJung-uk Kim     if (!tls1_set_shared_sigalgs(s))
37777bded2dbSJung-uk Kim         return 0;
37787bded2dbSJung-uk Kim 
37797bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
37807bded2dbSJung-uk Kim     if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
37817bded2dbSJung-uk Kim         /*
37827bded2dbSJung-uk Kim          * Use first set signature preference to force message digest,
37837bded2dbSJung-uk Kim          * ignoring any peer preferences.
37847bded2dbSJung-uk Kim          */
37857bded2dbSJung-uk Kim         const unsigned char *sigs = NULL;
37867bded2dbSJung-uk Kim         if (s->server)
37877bded2dbSJung-uk Kim             sigs = c->conf_sigalgs;
37887bded2dbSJung-uk Kim         else
37897bded2dbSJung-uk Kim             sigs = c->client_sigalgs;
37907bded2dbSJung-uk Kim         if (sigs) {
37917bded2dbSJung-uk Kim             idx = tls12_get_pkey_idx(sigs[1]);
37927bded2dbSJung-uk Kim             md = tls12_get_hash(sigs[0]);
37931f13597dSJung-uk Kim             c->pkeys[idx].digest = md;
37947bded2dbSJung-uk Kim             c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
37957bded2dbSJung-uk Kim             if (idx == SSL_PKEY_RSA_SIGN) {
37967bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
37977bded2dbSJung-uk Kim                     CERT_PKEY_EXPLICIT_SIGN;
37987bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
37997bded2dbSJung-uk Kim             }
38007bded2dbSJung-uk Kim         }
38017bded2dbSJung-uk Kim     }
38027bded2dbSJung-uk Kim # endif
38037bded2dbSJung-uk Kim 
38047bded2dbSJung-uk Kim     for (i = 0, sigptr = c->shared_sigalgs;
38057bded2dbSJung-uk Kim          i < c->shared_sigalgslen; i++, sigptr++) {
38067bded2dbSJung-uk Kim         idx = tls12_get_pkey_idx(sigptr->rsign);
38077bded2dbSJung-uk Kim         if (idx > 0 && c->pkeys[idx].digest == NULL) {
38087bded2dbSJung-uk Kim             md = tls12_get_hash(sigptr->rhash);
38097bded2dbSJung-uk Kim             c->pkeys[idx].digest = md;
38107bded2dbSJung-uk Kim             c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
38117bded2dbSJung-uk Kim             if (idx == SSL_PKEY_RSA_SIGN) {
38127bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
38137bded2dbSJung-uk Kim                     CERT_PKEY_EXPLICIT_SIGN;
38141f13597dSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
38151f13597dSJung-uk Kim             }
38161f13597dSJung-uk Kim         }
38171f13597dSJung-uk Kim 
38181f13597dSJung-uk Kim     }
38197bded2dbSJung-uk Kim     /*
38207bded2dbSJung-uk Kim      * In strict mode leave unset digests as NULL to indicate we can't use
38217bded2dbSJung-uk Kim      * the certificate for signing.
38227bded2dbSJung-uk Kim      */
38237bded2dbSJung-uk Kim     if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
38246f9291ceSJung-uk Kim         /*
38256f9291ceSJung-uk Kim          * Set any remaining keys to default values. NOTE: if alg is not
38261f13597dSJung-uk Kim          * supported it stays as NULL.
3827db522d3aSSimon L. B. Nielsen          */
38281f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA
38291f13597dSJung-uk Kim         if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
383009286989SJung-uk Kim             c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
38311f13597dSJung-uk Kim # endif
38321f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA
38336f9291ceSJung-uk Kim         if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
38341f13597dSJung-uk Kim             c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
38351f13597dSJung-uk Kim             c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
38361f13597dSJung-uk Kim         }
38371f13597dSJung-uk Kim # endif
38381f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
38391f13597dSJung-uk Kim         if (!c->pkeys[SSL_PKEY_ECC].digest)
384009286989SJung-uk Kim             c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
38411f13597dSJung-uk Kim # endif
38427bded2dbSJung-uk Kim     }
38431f13597dSJung-uk Kim     return 1;
38441f13597dSJung-uk Kim }
38451f13597dSJung-uk Kim 
38467bded2dbSJung-uk Kim int SSL_get_sigalgs(SSL *s, int idx,
38477bded2dbSJung-uk Kim                     int *psign, int *phash, int *psignhash,
38487bded2dbSJung-uk Kim                     unsigned char *rsig, unsigned char *rhash)
38497bded2dbSJung-uk Kim {
38507bded2dbSJung-uk Kim     const unsigned char *psig = s->cert->peer_sigalgs;
38517bded2dbSJung-uk Kim     if (psig == NULL)
38527bded2dbSJung-uk Kim         return 0;
38537bded2dbSJung-uk Kim     if (idx >= 0) {
38547bded2dbSJung-uk Kim         idx <<= 1;
38557bded2dbSJung-uk Kim         if (idx >= (int)s->cert->peer_sigalgslen)
38567bded2dbSJung-uk Kim             return 0;
38577bded2dbSJung-uk Kim         psig += idx;
38587bded2dbSJung-uk Kim         if (rhash)
38597bded2dbSJung-uk Kim             *rhash = psig[0];
38607bded2dbSJung-uk Kim         if (rsig)
38617bded2dbSJung-uk Kim             *rsig = psig[1];
38627bded2dbSJung-uk Kim         tls1_lookup_sigalg(phash, psign, psignhash, psig);
38637bded2dbSJung-uk Kim     }
38647bded2dbSJung-uk Kim     return s->cert->peer_sigalgslen / 2;
38657bded2dbSJung-uk Kim }
38667bded2dbSJung-uk Kim 
38677bded2dbSJung-uk Kim int SSL_get_shared_sigalgs(SSL *s, int idx,
38687bded2dbSJung-uk Kim                            int *psign, int *phash, int *psignhash,
38697bded2dbSJung-uk Kim                            unsigned char *rsig, unsigned char *rhash)
38707bded2dbSJung-uk Kim {
38717bded2dbSJung-uk Kim     TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
38727bded2dbSJung-uk Kim     if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen)
38737bded2dbSJung-uk Kim         return 0;
38747bded2dbSJung-uk Kim     shsigalgs += idx;
38757bded2dbSJung-uk Kim     if (phash)
38767bded2dbSJung-uk Kim         *phash = shsigalgs->hash_nid;
38777bded2dbSJung-uk Kim     if (psign)
38787bded2dbSJung-uk Kim         *psign = shsigalgs->sign_nid;
38797bded2dbSJung-uk Kim     if (psignhash)
38807bded2dbSJung-uk Kim         *psignhash = shsigalgs->signandhash_nid;
38817bded2dbSJung-uk Kim     if (rsig)
38827bded2dbSJung-uk Kim         *rsig = shsigalgs->rsign;
38837bded2dbSJung-uk Kim     if (rhash)
38847bded2dbSJung-uk Kim         *rhash = shsigalgs->rhash;
38857bded2dbSJung-uk Kim     return s->cert->shared_sigalgslen;
38867bded2dbSJung-uk Kim }
38871f13597dSJung-uk Kim 
38881f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
38896f9291ceSJung-uk Kim int tls1_process_heartbeat(SSL *s)
38901f13597dSJung-uk Kim {
38911f13597dSJung-uk Kim     unsigned char *p = &s->s3->rrec.data[0], *pl;
38921f13597dSJung-uk Kim     unsigned short hbtype;
38931f13597dSJung-uk Kim     unsigned int payload;
38941f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
38951f13597dSJung-uk Kim 
38961f13597dSJung-uk Kim     if (s->msg_callback)
38971f13597dSJung-uk Kim         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
38981f13597dSJung-uk Kim                         &s->s3->rrec.data[0], s->s3->rrec.length,
38991f13597dSJung-uk Kim                         s, s->msg_callback_arg);
39001f13597dSJung-uk Kim 
390125bfde79SXin LI     /* Read type and payload length first */
390225bfde79SXin LI     if (1 + 2 + 16 > s->s3->rrec.length)
390325bfde79SXin LI         return 0;               /* silently discard */
390425bfde79SXin LI     hbtype = *p++;
390525bfde79SXin LI     n2s(p, payload);
390625bfde79SXin LI     if (1 + 2 + payload + 16 > s->s3->rrec.length)
390725bfde79SXin LI         return 0;               /* silently discard per RFC 6520 sec. 4 */
390825bfde79SXin LI     pl = p;
390925bfde79SXin LI 
39106f9291ceSJung-uk Kim     if (hbtype == TLS1_HB_REQUEST) {
39111f13597dSJung-uk Kim         unsigned char *buffer, *bp;
39121f13597dSJung-uk Kim         int r;
39131f13597dSJung-uk Kim 
39146f9291ceSJung-uk Kim         /*
39156f9291ceSJung-uk Kim          * Allocate memory for the response, size is 1 bytes message type,
39166f9291ceSJung-uk Kim          * plus 2 bytes payload length, plus payload, plus padding
39171f13597dSJung-uk Kim          */
39181f13597dSJung-uk Kim         buffer = OPENSSL_malloc(1 + 2 + payload + padding);
3919b8721c16SJung-uk Kim         if (buffer == NULL)
3920b8721c16SJung-uk Kim             return -1;
39211f13597dSJung-uk Kim         bp = buffer;
39221f13597dSJung-uk Kim 
39231f13597dSJung-uk Kim         /* Enter response type, length and copy payload */
39241f13597dSJung-uk Kim         *bp++ = TLS1_HB_RESPONSE;
39251f13597dSJung-uk Kim         s2n(payload, bp);
39261f13597dSJung-uk Kim         memcpy(bp, pl, payload);
39271f13597dSJung-uk Kim         bp += payload;
39281f13597dSJung-uk Kim         /* Random padding */
3929*aeb5019cSJung-uk Kim         if (RAND_bytes(bp, padding) <= 0) {
3930ed6b93beSJung-uk Kim             OPENSSL_free(buffer);
3931ed6b93beSJung-uk Kim             return -1;
3932ed6b93beSJung-uk Kim         }
39331f13597dSJung-uk Kim 
39346f9291ceSJung-uk Kim         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
39356f9291ceSJung-uk Kim                              3 + payload + padding);
39361f13597dSJung-uk Kim 
39371f13597dSJung-uk Kim         if (r >= 0 && s->msg_callback)
39381f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
39391f13597dSJung-uk Kim                             buffer, 3 + payload + padding,
39401f13597dSJung-uk Kim                             s, s->msg_callback_arg);
39411f13597dSJung-uk Kim 
39421f13597dSJung-uk Kim         OPENSSL_free(buffer);
39431f13597dSJung-uk Kim 
39441f13597dSJung-uk Kim         if (r < 0)
39451f13597dSJung-uk Kim             return r;
39466f9291ceSJung-uk Kim     } else if (hbtype == TLS1_HB_RESPONSE) {
39471f13597dSJung-uk Kim         unsigned int seq;
39481f13597dSJung-uk Kim 
39496f9291ceSJung-uk Kim         /*
39506f9291ceSJung-uk Kim          * We only send sequence numbers (2 bytes unsigned int), and 16
39516f9291ceSJung-uk Kim          * random bytes, so we just try to read the sequence number
39526f9291ceSJung-uk Kim          */
39531f13597dSJung-uk Kim         n2s(pl, seq);
39541f13597dSJung-uk Kim 
39556f9291ceSJung-uk Kim         if (payload == 18 && seq == s->tlsext_hb_seq) {
39561f13597dSJung-uk Kim             s->tlsext_hb_seq++;
39571f13597dSJung-uk Kim             s->tlsext_hb_pending = 0;
39581f13597dSJung-uk Kim         }
39591f13597dSJung-uk Kim     }
39601f13597dSJung-uk Kim 
3961db522d3aSSimon L. B. Nielsen     return 0;
3962db522d3aSSimon L. B. Nielsen }
3963db522d3aSSimon L. B. Nielsen 
39646f9291ceSJung-uk Kim int tls1_heartbeat(SSL *s)
39651f13597dSJung-uk Kim {
39661f13597dSJung-uk Kim     unsigned char *buf, *p;
3967ed6b93beSJung-uk Kim     int ret = -1;
39681f13597dSJung-uk Kim     unsigned int payload = 18;  /* Sequence number + random bytes */
39691f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
39701f13597dSJung-uk Kim 
39711f13597dSJung-uk Kim     /* Only send if peer supports and accepts HB requests... */
39721f13597dSJung-uk Kim     if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
39736f9291ceSJung-uk Kim         s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
39741f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
39751f13597dSJung-uk Kim         return -1;
39761f13597dSJung-uk Kim     }
39771f13597dSJung-uk Kim 
39781f13597dSJung-uk Kim     /* ...and there is none in flight yet... */
39796f9291ceSJung-uk Kim     if (s->tlsext_hb_pending) {
39801f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
39811f13597dSJung-uk Kim         return -1;
39821f13597dSJung-uk Kim     }
39831f13597dSJung-uk Kim 
39841f13597dSJung-uk Kim     /* ...and no handshake in progress. */
39856f9291ceSJung-uk Kim     if (SSL_in_init(s) || s->in_handshake) {
39861f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
39871f13597dSJung-uk Kim         return -1;
39881f13597dSJung-uk Kim     }
39891f13597dSJung-uk Kim 
39906f9291ceSJung-uk Kim     /*
39916f9291ceSJung-uk Kim      * Check if padding is too long, payload and padding must not exceed 2^14
39926f9291ceSJung-uk Kim      * - 3 = 16381 bytes in total.
39931f13597dSJung-uk Kim      */
39941f13597dSJung-uk Kim     OPENSSL_assert(payload + padding <= 16381);
39951f13597dSJung-uk Kim 
39966f9291ceSJung-uk Kim     /*-
39976f9291ceSJung-uk Kim      * Create HeartBeat message, we just use a sequence number
39981f13597dSJung-uk Kim      * as payload to distuingish different messages and add
39991f13597dSJung-uk Kim      * some random stuff.
40001f13597dSJung-uk Kim      *  - Message Type, 1 byte
40011f13597dSJung-uk Kim      *  - Payload Length, 2 bytes (unsigned int)
40021f13597dSJung-uk Kim      *  - Payload, the sequence number (2 bytes uint)
40031f13597dSJung-uk Kim      *  - Payload, random bytes (16 bytes uint)
40041f13597dSJung-uk Kim      *  - Padding
40051f13597dSJung-uk Kim      */
40061f13597dSJung-uk Kim     buf = OPENSSL_malloc(1 + 2 + payload + padding);
4007*aeb5019cSJung-uk Kim     if (buf == NULL)
4008*aeb5019cSJung-uk Kim         return -1;
40091f13597dSJung-uk Kim     p = buf;
40101f13597dSJung-uk Kim     /* Message Type */
40111f13597dSJung-uk Kim     *p++ = TLS1_HB_REQUEST;
40121f13597dSJung-uk Kim     /* Payload length (18 bytes here) */
40131f13597dSJung-uk Kim     s2n(payload, p);
40141f13597dSJung-uk Kim     /* Sequence number */
40151f13597dSJung-uk Kim     s2n(s->tlsext_hb_seq, p);
40161f13597dSJung-uk Kim     /* 16 random bytes */
4017*aeb5019cSJung-uk Kim     if (RAND_bytes(p, 16) <= 0) {
4018ed6b93beSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
4019ed6b93beSJung-uk Kim         goto err;
4020ed6b93beSJung-uk Kim     }
40211f13597dSJung-uk Kim     p += 16;
40221f13597dSJung-uk Kim     /* Random padding */
4023*aeb5019cSJung-uk Kim     if (RAND_bytes(p, padding) <= 0) {
4024ed6b93beSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
4025ed6b93beSJung-uk Kim         goto err;
4026ed6b93beSJung-uk Kim     }
40271f13597dSJung-uk Kim 
40281f13597dSJung-uk Kim     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
40296f9291ceSJung-uk Kim     if (ret >= 0) {
40301f13597dSJung-uk Kim         if (s->msg_callback)
40311f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
40321f13597dSJung-uk Kim                             buf, 3 + payload + padding,
40331f13597dSJung-uk Kim                             s, s->msg_callback_arg);
40341f13597dSJung-uk Kim 
40351f13597dSJung-uk Kim         s->tlsext_hb_pending = 1;
40361f13597dSJung-uk Kim     }
40371f13597dSJung-uk Kim 
4038ed6b93beSJung-uk Kim err:
40391f13597dSJung-uk Kim     OPENSSL_free(buf);
40401f13597dSJung-uk Kim 
40411f13597dSJung-uk Kim     return ret;
40421f13597dSJung-uk Kim }
4043db522d3aSSimon L. B. Nielsen # endif
40447bded2dbSJung-uk Kim 
40457bded2dbSJung-uk Kim # define MAX_SIGALGLEN   (TLSEXT_hash_num * TLSEXT_signature_num * 2)
40467bded2dbSJung-uk Kim 
40477bded2dbSJung-uk Kim typedef struct {
40487bded2dbSJung-uk Kim     size_t sigalgcnt;
40497bded2dbSJung-uk Kim     int sigalgs[MAX_SIGALGLEN];
40507bded2dbSJung-uk Kim } sig_cb_st;
40517bded2dbSJung-uk Kim 
40527bded2dbSJung-uk Kim static int sig_cb(const char *elem, int len, void *arg)
40537bded2dbSJung-uk Kim {
40547bded2dbSJung-uk Kim     sig_cb_st *sarg = arg;
40557bded2dbSJung-uk Kim     size_t i;
40567bded2dbSJung-uk Kim     char etmp[20], *p;
40577bded2dbSJung-uk Kim     int sig_alg, hash_alg;
40587bded2dbSJung-uk Kim     if (elem == NULL)
40597bded2dbSJung-uk Kim         return 0;
40607bded2dbSJung-uk Kim     if (sarg->sigalgcnt == MAX_SIGALGLEN)
40617bded2dbSJung-uk Kim         return 0;
40627bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
40637bded2dbSJung-uk Kim         return 0;
40647bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
40657bded2dbSJung-uk Kim     etmp[len] = 0;
40667bded2dbSJung-uk Kim     p = strchr(etmp, '+');
40677bded2dbSJung-uk Kim     if (!p)
40687bded2dbSJung-uk Kim         return 0;
40697bded2dbSJung-uk Kim     *p = 0;
40707bded2dbSJung-uk Kim     p++;
40717bded2dbSJung-uk Kim     if (!*p)
40727bded2dbSJung-uk Kim         return 0;
40737bded2dbSJung-uk Kim 
40747bded2dbSJung-uk Kim     if (!strcmp(etmp, "RSA"))
40757bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_RSA;
40767bded2dbSJung-uk Kim     else if (!strcmp(etmp, "DSA"))
40777bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_DSA;
40787bded2dbSJung-uk Kim     else if (!strcmp(etmp, "ECDSA"))
40797bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_EC;
40807bded2dbSJung-uk Kim     else
40817bded2dbSJung-uk Kim         return 0;
40827bded2dbSJung-uk Kim 
40837bded2dbSJung-uk Kim     hash_alg = OBJ_sn2nid(p);
40847bded2dbSJung-uk Kim     if (hash_alg == NID_undef)
40857bded2dbSJung-uk Kim         hash_alg = OBJ_ln2nid(p);
40867bded2dbSJung-uk Kim     if (hash_alg == NID_undef)
40877bded2dbSJung-uk Kim         return 0;
40887bded2dbSJung-uk Kim 
40897bded2dbSJung-uk Kim     for (i = 0; i < sarg->sigalgcnt; i += 2) {
40907bded2dbSJung-uk Kim         if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg)
40917bded2dbSJung-uk Kim             return 0;
40927bded2dbSJung-uk Kim     }
40937bded2dbSJung-uk Kim     sarg->sigalgs[sarg->sigalgcnt++] = hash_alg;
40947bded2dbSJung-uk Kim     sarg->sigalgs[sarg->sigalgcnt++] = sig_alg;
40957bded2dbSJung-uk Kim     return 1;
40967bded2dbSJung-uk Kim }
40977bded2dbSJung-uk Kim 
40987bded2dbSJung-uk Kim /*
40997bded2dbSJung-uk Kim  * Set suppored signature algorithms based on a colon separated list of the
41007bded2dbSJung-uk Kim  * form sig+hash e.g. RSA+SHA512:DSA+SHA512
41017bded2dbSJung-uk Kim  */
41027bded2dbSJung-uk Kim int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
41037bded2dbSJung-uk Kim {
41047bded2dbSJung-uk Kim     sig_cb_st sig;
41057bded2dbSJung-uk Kim     sig.sigalgcnt = 0;
41067bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
41077bded2dbSJung-uk Kim         return 0;
41087bded2dbSJung-uk Kim     if (c == NULL)
41097bded2dbSJung-uk Kim         return 1;
41107bded2dbSJung-uk Kim     return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
41117bded2dbSJung-uk Kim }
41127bded2dbSJung-uk Kim 
41137bded2dbSJung-uk Kim int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
41147bded2dbSJung-uk Kim                      int client)
41157bded2dbSJung-uk Kim {
41167bded2dbSJung-uk Kim     unsigned char *sigalgs, *sptr;
41177bded2dbSJung-uk Kim     int rhash, rsign;
41187bded2dbSJung-uk Kim     size_t i;
41197bded2dbSJung-uk Kim     if (salglen & 1)
41207bded2dbSJung-uk Kim         return 0;
41217bded2dbSJung-uk Kim     sigalgs = OPENSSL_malloc(salglen);
41227bded2dbSJung-uk Kim     if (sigalgs == NULL)
41237bded2dbSJung-uk Kim         return 0;
41247bded2dbSJung-uk Kim     for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
41257bded2dbSJung-uk Kim         rhash = tls12_find_id(*psig_nids++, tls12_md,
41267bded2dbSJung-uk Kim                               sizeof(tls12_md) / sizeof(tls12_lookup));
41277bded2dbSJung-uk Kim         rsign = tls12_find_id(*psig_nids++, tls12_sig,
41287bded2dbSJung-uk Kim                               sizeof(tls12_sig) / sizeof(tls12_lookup));
41297bded2dbSJung-uk Kim 
41307bded2dbSJung-uk Kim         if (rhash == -1 || rsign == -1)
41317bded2dbSJung-uk Kim             goto err;
41327bded2dbSJung-uk Kim         *sptr++ = rhash;
41337bded2dbSJung-uk Kim         *sptr++ = rsign;
41347bded2dbSJung-uk Kim     }
41357bded2dbSJung-uk Kim 
41367bded2dbSJung-uk Kim     if (client) {
41377bded2dbSJung-uk Kim         if (c->client_sigalgs)
41387bded2dbSJung-uk Kim             OPENSSL_free(c->client_sigalgs);
41397bded2dbSJung-uk Kim         c->client_sigalgs = sigalgs;
41407bded2dbSJung-uk Kim         c->client_sigalgslen = salglen;
41417bded2dbSJung-uk Kim     } else {
41427bded2dbSJung-uk Kim         if (c->conf_sigalgs)
41437bded2dbSJung-uk Kim             OPENSSL_free(c->conf_sigalgs);
41447bded2dbSJung-uk Kim         c->conf_sigalgs = sigalgs;
41457bded2dbSJung-uk Kim         c->conf_sigalgslen = salglen;
41467bded2dbSJung-uk Kim     }
41477bded2dbSJung-uk Kim 
41487bded2dbSJung-uk Kim     return 1;
41497bded2dbSJung-uk Kim 
41507bded2dbSJung-uk Kim  err:
41517bded2dbSJung-uk Kim     OPENSSL_free(sigalgs);
41527bded2dbSJung-uk Kim     return 0;
41537bded2dbSJung-uk Kim }
41547bded2dbSJung-uk Kim 
41557bded2dbSJung-uk Kim static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
41567bded2dbSJung-uk Kim {
41577bded2dbSJung-uk Kim     int sig_nid;
41587bded2dbSJung-uk Kim     size_t i;
41597bded2dbSJung-uk Kim     if (default_nid == -1)
41607bded2dbSJung-uk Kim         return 1;
41617bded2dbSJung-uk Kim     sig_nid = X509_get_signature_nid(x);
41627bded2dbSJung-uk Kim     if (default_nid)
41637bded2dbSJung-uk Kim         return sig_nid == default_nid ? 1 : 0;
41647bded2dbSJung-uk Kim     for (i = 0; i < c->shared_sigalgslen; i++)
41657bded2dbSJung-uk Kim         if (sig_nid == c->shared_sigalgs[i].signandhash_nid)
41667bded2dbSJung-uk Kim             return 1;
41677bded2dbSJung-uk Kim     return 0;
41687bded2dbSJung-uk Kim }
41697bded2dbSJung-uk Kim 
41707bded2dbSJung-uk Kim /* Check to see if a certificate issuer name matches list of CA names */
41717bded2dbSJung-uk Kim static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
41727bded2dbSJung-uk Kim {
41737bded2dbSJung-uk Kim     X509_NAME *nm;
41747bded2dbSJung-uk Kim     int i;
41757bded2dbSJung-uk Kim     nm = X509_get_issuer_name(x);
41767bded2dbSJung-uk Kim     for (i = 0; i < sk_X509_NAME_num(names); i++) {
41777bded2dbSJung-uk Kim         if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
41787bded2dbSJung-uk Kim             return 1;
41797bded2dbSJung-uk Kim     }
41807bded2dbSJung-uk Kim     return 0;
41817bded2dbSJung-uk Kim }
41827bded2dbSJung-uk Kim 
41837bded2dbSJung-uk Kim /*
41847bded2dbSJung-uk Kim  * Check certificate chain is consistent with TLS extensions and is usable by
41857bded2dbSJung-uk Kim  * server. This servers two purposes: it allows users to check chains before
41867bded2dbSJung-uk Kim  * passing them to the server and it allows the server to check chains before
41877bded2dbSJung-uk Kim  * attempting to use them.
41887bded2dbSJung-uk Kim  */
41897bded2dbSJung-uk Kim 
41907bded2dbSJung-uk Kim /* Flags which need to be set for a certificate when stict mode not set */
41917bded2dbSJung-uk Kim 
41927bded2dbSJung-uk Kim # define CERT_PKEY_VALID_FLAGS \
41937bded2dbSJung-uk Kim         (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
41947bded2dbSJung-uk Kim /* Strict mode flags */
41957bded2dbSJung-uk Kim # define CERT_PKEY_STRICT_FLAGS \
41967bded2dbSJung-uk Kim          (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
41977bded2dbSJung-uk Kim          | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
41987bded2dbSJung-uk Kim 
41997bded2dbSJung-uk Kim int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
42007bded2dbSJung-uk Kim                      int idx)
42017bded2dbSJung-uk Kim {
42027bded2dbSJung-uk Kim     int i;
42037bded2dbSJung-uk Kim     int rv = 0;
42047bded2dbSJung-uk Kim     int check_flags = 0, strict_mode;
42057bded2dbSJung-uk Kim     CERT_PKEY *cpk = NULL;
42067bded2dbSJung-uk Kim     CERT *c = s->cert;
42077bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
42087bded2dbSJung-uk Kim     /* idx == -1 means checking server chains */
42097bded2dbSJung-uk Kim     if (idx != -1) {
42107bded2dbSJung-uk Kim         /* idx == -2 means checking client certificate chains */
42117bded2dbSJung-uk Kim         if (idx == -2) {
42127bded2dbSJung-uk Kim             cpk = c->key;
42137bded2dbSJung-uk Kim             idx = cpk - c->pkeys;
42147bded2dbSJung-uk Kim         } else
42157bded2dbSJung-uk Kim             cpk = c->pkeys + idx;
42167bded2dbSJung-uk Kim         x = cpk->x509;
42177bded2dbSJung-uk Kim         pk = cpk->privatekey;
42187bded2dbSJung-uk Kim         chain = cpk->chain;
42197bded2dbSJung-uk Kim         strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
42207bded2dbSJung-uk Kim         /* If no cert or key, forget it */
42217bded2dbSJung-uk Kim         if (!x || !pk)
42227bded2dbSJung-uk Kim             goto end;
42237bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
42247bded2dbSJung-uk Kim         /* Allow any certificate to pass test */
42257bded2dbSJung-uk Kim         if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
42267bded2dbSJung-uk Kim             rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN |
42277bded2dbSJung-uk Kim                 CERT_PKEY_VALID | CERT_PKEY_SIGN;
42287bded2dbSJung-uk Kim             cpk->valid_flags = rv;
42297bded2dbSJung-uk Kim             return rv;
42307bded2dbSJung-uk Kim         }
42317bded2dbSJung-uk Kim # endif
42327bded2dbSJung-uk Kim     } else {
42337bded2dbSJung-uk Kim         if (!x || !pk)
42347bded2dbSJung-uk Kim             return 0;
42357bded2dbSJung-uk Kim         idx = ssl_cert_type(x, pk);
42367bded2dbSJung-uk Kim         if (idx == -1)
42377bded2dbSJung-uk Kim             return 0;
42387bded2dbSJung-uk Kim         cpk = c->pkeys + idx;
42397bded2dbSJung-uk Kim         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
42407bded2dbSJung-uk Kim             check_flags = CERT_PKEY_STRICT_FLAGS;
42417bded2dbSJung-uk Kim         else
42427bded2dbSJung-uk Kim             check_flags = CERT_PKEY_VALID_FLAGS;
42437bded2dbSJung-uk Kim         strict_mode = 1;
42447bded2dbSJung-uk Kim     }
42457bded2dbSJung-uk Kim 
42467bded2dbSJung-uk Kim     if (suiteb_flags) {
42477bded2dbSJung-uk Kim         int ok;
42487bded2dbSJung-uk Kim         if (check_flags)
42497bded2dbSJung-uk Kim             check_flags |= CERT_PKEY_SUITEB;
42507bded2dbSJung-uk Kim         ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
42517bded2dbSJung-uk Kim         if (ok == X509_V_OK)
42527bded2dbSJung-uk Kim             rv |= CERT_PKEY_SUITEB;
42537bded2dbSJung-uk Kim         else if (!check_flags)
42547bded2dbSJung-uk Kim             goto end;
42557bded2dbSJung-uk Kim     }
42567bded2dbSJung-uk Kim 
42577bded2dbSJung-uk Kim     /*
42587bded2dbSJung-uk Kim      * Check all signature algorithms are consistent with signature
42597bded2dbSJung-uk Kim      * algorithms extension if TLS 1.2 or later and strict mode.
42607bded2dbSJung-uk Kim      */
42617bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
42627bded2dbSJung-uk Kim         int default_nid;
42637bded2dbSJung-uk Kim         unsigned char rsign = 0;
42647bded2dbSJung-uk Kim         if (c->peer_sigalgs)
42657bded2dbSJung-uk Kim             default_nid = 0;
42667bded2dbSJung-uk Kim         /* If no sigalgs extension use defaults from RFC5246 */
42677bded2dbSJung-uk Kim         else {
42687bded2dbSJung-uk Kim             switch (idx) {
42697bded2dbSJung-uk Kim             case SSL_PKEY_RSA_ENC:
42707bded2dbSJung-uk Kim             case SSL_PKEY_RSA_SIGN:
42717bded2dbSJung-uk Kim             case SSL_PKEY_DH_RSA:
42727bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_rsa;
42737bded2dbSJung-uk Kim                 default_nid = NID_sha1WithRSAEncryption;
42747bded2dbSJung-uk Kim                 break;
42757bded2dbSJung-uk Kim 
42767bded2dbSJung-uk Kim             case SSL_PKEY_DSA_SIGN:
42777bded2dbSJung-uk Kim             case SSL_PKEY_DH_DSA:
42787bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_dsa;
42797bded2dbSJung-uk Kim                 default_nid = NID_dsaWithSHA1;
42807bded2dbSJung-uk Kim                 break;
42817bded2dbSJung-uk Kim 
42827bded2dbSJung-uk Kim             case SSL_PKEY_ECC:
42837bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_ecdsa;
42847bded2dbSJung-uk Kim                 default_nid = NID_ecdsa_with_SHA1;
42857bded2dbSJung-uk Kim                 break;
42867bded2dbSJung-uk Kim 
42877bded2dbSJung-uk Kim             default:
42887bded2dbSJung-uk Kim                 default_nid = -1;
42897bded2dbSJung-uk Kim                 break;
42907bded2dbSJung-uk Kim             }
42917bded2dbSJung-uk Kim         }
42927bded2dbSJung-uk Kim         /*
42937bded2dbSJung-uk Kim          * If peer sent no signature algorithms extension and we have set
42947bded2dbSJung-uk Kim          * preferred signature algorithms check we support sha1.
42957bded2dbSJung-uk Kim          */
42967bded2dbSJung-uk Kim         if (default_nid > 0 && c->conf_sigalgs) {
42977bded2dbSJung-uk Kim             size_t j;
42987bded2dbSJung-uk Kim             const unsigned char *p = c->conf_sigalgs;
42997bded2dbSJung-uk Kim             for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) {
43007bded2dbSJung-uk Kim                 if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign)
43017bded2dbSJung-uk Kim                     break;
43027bded2dbSJung-uk Kim             }
43037bded2dbSJung-uk Kim             if (j == c->conf_sigalgslen) {
43047bded2dbSJung-uk Kim                 if (check_flags)
43057bded2dbSJung-uk Kim                     goto skip_sigs;
43067bded2dbSJung-uk Kim                 else
43077bded2dbSJung-uk Kim                     goto end;
43087bded2dbSJung-uk Kim             }
43097bded2dbSJung-uk Kim         }
43107bded2dbSJung-uk Kim         /* Check signature algorithm of each cert in chain */
43117bded2dbSJung-uk Kim         if (!tls1_check_sig_alg(c, x, default_nid)) {
43127bded2dbSJung-uk Kim             if (!check_flags)
43137bded2dbSJung-uk Kim                 goto end;
43147bded2dbSJung-uk Kim         } else
43157bded2dbSJung-uk Kim             rv |= CERT_PKEY_EE_SIGNATURE;
43167bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_SIGNATURE;
43177bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
43187bded2dbSJung-uk Kim             if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) {
43197bded2dbSJung-uk Kim                 if (check_flags) {
43207bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_SIGNATURE;
43217bded2dbSJung-uk Kim                     break;
43227bded2dbSJung-uk Kim                 } else
43237bded2dbSJung-uk Kim                     goto end;
43247bded2dbSJung-uk Kim             }
43257bded2dbSJung-uk Kim         }
43267bded2dbSJung-uk Kim     }
43277bded2dbSJung-uk Kim     /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
43287bded2dbSJung-uk Kim     else if (check_flags)
43297bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
43307bded2dbSJung-uk Kim  skip_sigs:
43317bded2dbSJung-uk Kim     /* Check cert parameters are consistent */
43327bded2dbSJung-uk Kim     if (tls1_check_cert_param(s, x, check_flags ? 1 : 2))
43337bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_PARAM;
43347bded2dbSJung-uk Kim     else if (!check_flags)
43357bded2dbSJung-uk Kim         goto end;
43367bded2dbSJung-uk Kim     if (!s->server)
43377bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
43387bded2dbSJung-uk Kim     /* In strict mode check rest of chain too */
43397bded2dbSJung-uk Kim     else if (strict_mode) {
43407bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
43417bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
43427bded2dbSJung-uk Kim             X509 *ca = sk_X509_value(chain, i);
43437bded2dbSJung-uk Kim             if (!tls1_check_cert_param(s, ca, 0)) {
43447bded2dbSJung-uk Kim                 if (check_flags) {
43457bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_PARAM;
43467bded2dbSJung-uk Kim                     break;
43477bded2dbSJung-uk Kim                 } else
43487bded2dbSJung-uk Kim                     goto end;
43497bded2dbSJung-uk Kim             }
43507bded2dbSJung-uk Kim         }
43517bded2dbSJung-uk Kim     }
43527bded2dbSJung-uk Kim     if (!s->server && strict_mode) {
43537bded2dbSJung-uk Kim         STACK_OF(X509_NAME) *ca_dn;
43547bded2dbSJung-uk Kim         int check_type = 0;
43557bded2dbSJung-uk Kim         switch (pk->type) {
43567bded2dbSJung-uk Kim         case EVP_PKEY_RSA:
43577bded2dbSJung-uk Kim             check_type = TLS_CT_RSA_SIGN;
43587bded2dbSJung-uk Kim             break;
43597bded2dbSJung-uk Kim         case EVP_PKEY_DSA:
43607bded2dbSJung-uk Kim             check_type = TLS_CT_DSS_SIGN;
43617bded2dbSJung-uk Kim             break;
43627bded2dbSJung-uk Kim         case EVP_PKEY_EC:
43637bded2dbSJung-uk Kim             check_type = TLS_CT_ECDSA_SIGN;
43647bded2dbSJung-uk Kim             break;
43657bded2dbSJung-uk Kim         case EVP_PKEY_DH:
43667bded2dbSJung-uk Kim         case EVP_PKEY_DHX:
43677bded2dbSJung-uk Kim             {
43687bded2dbSJung-uk Kim                 int cert_type = X509_certificate_type(x, pk);
43697bded2dbSJung-uk Kim                 if (cert_type & EVP_PKS_RSA)
43707bded2dbSJung-uk Kim                     check_type = TLS_CT_RSA_FIXED_DH;
43717bded2dbSJung-uk Kim                 if (cert_type & EVP_PKS_DSA)
43727bded2dbSJung-uk Kim                     check_type = TLS_CT_DSS_FIXED_DH;
43737bded2dbSJung-uk Kim             }
43747bded2dbSJung-uk Kim         }
43757bded2dbSJung-uk Kim         if (check_type) {
43767bded2dbSJung-uk Kim             const unsigned char *ctypes;
43777bded2dbSJung-uk Kim             int ctypelen;
43787bded2dbSJung-uk Kim             if (c->ctypes) {
43797bded2dbSJung-uk Kim                 ctypes = c->ctypes;
43807bded2dbSJung-uk Kim                 ctypelen = (int)c->ctype_num;
43817bded2dbSJung-uk Kim             } else {
43827bded2dbSJung-uk Kim                 ctypes = (unsigned char *)s->s3->tmp.ctype;
43837bded2dbSJung-uk Kim                 ctypelen = s->s3->tmp.ctype_num;
43847bded2dbSJung-uk Kim             }
43857bded2dbSJung-uk Kim             for (i = 0; i < ctypelen; i++) {
43867bded2dbSJung-uk Kim                 if (ctypes[i] == check_type) {
43877bded2dbSJung-uk Kim                     rv |= CERT_PKEY_CERT_TYPE;
43887bded2dbSJung-uk Kim                     break;
43897bded2dbSJung-uk Kim                 }
43907bded2dbSJung-uk Kim             }
43917bded2dbSJung-uk Kim             if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
43927bded2dbSJung-uk Kim                 goto end;
43937bded2dbSJung-uk Kim         } else
43947bded2dbSJung-uk Kim             rv |= CERT_PKEY_CERT_TYPE;
43957bded2dbSJung-uk Kim 
43967bded2dbSJung-uk Kim         ca_dn = s->s3->tmp.ca_names;
43977bded2dbSJung-uk Kim 
43987bded2dbSJung-uk Kim         if (!sk_X509_NAME_num(ca_dn))
43997bded2dbSJung-uk Kim             rv |= CERT_PKEY_ISSUER_NAME;
44007bded2dbSJung-uk Kim 
44017bded2dbSJung-uk Kim         if (!(rv & CERT_PKEY_ISSUER_NAME)) {
44027bded2dbSJung-uk Kim             if (ssl_check_ca_name(ca_dn, x))
44037bded2dbSJung-uk Kim                 rv |= CERT_PKEY_ISSUER_NAME;
44047bded2dbSJung-uk Kim         }
44057bded2dbSJung-uk Kim         if (!(rv & CERT_PKEY_ISSUER_NAME)) {
44067bded2dbSJung-uk Kim             for (i = 0; i < sk_X509_num(chain); i++) {
44077bded2dbSJung-uk Kim                 X509 *xtmp = sk_X509_value(chain, i);
44087bded2dbSJung-uk Kim                 if (ssl_check_ca_name(ca_dn, xtmp)) {
44097bded2dbSJung-uk Kim                     rv |= CERT_PKEY_ISSUER_NAME;
44107bded2dbSJung-uk Kim                     break;
44117bded2dbSJung-uk Kim                 }
44127bded2dbSJung-uk Kim             }
44137bded2dbSJung-uk Kim         }
44147bded2dbSJung-uk Kim         if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
44157bded2dbSJung-uk Kim             goto end;
44167bded2dbSJung-uk Kim     } else
44177bded2dbSJung-uk Kim         rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE;
44187bded2dbSJung-uk Kim 
44197bded2dbSJung-uk Kim     if (!check_flags || (rv & check_flags) == check_flags)
44207bded2dbSJung-uk Kim         rv |= CERT_PKEY_VALID;
44217bded2dbSJung-uk Kim 
44227bded2dbSJung-uk Kim  end:
44237bded2dbSJung-uk Kim 
44247bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION) {
44257bded2dbSJung-uk Kim         if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN)
44267bded2dbSJung-uk Kim             rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
44277bded2dbSJung-uk Kim         else if (cpk->digest)
44287bded2dbSJung-uk Kim             rv |= CERT_PKEY_SIGN;
44297bded2dbSJung-uk Kim     } else
44307bded2dbSJung-uk Kim         rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
44317bded2dbSJung-uk Kim 
44327bded2dbSJung-uk Kim     /*
44337bded2dbSJung-uk Kim      * When checking a CERT_PKEY structure all flags are irrelevant if the
44347bded2dbSJung-uk Kim      * chain is invalid.
44357bded2dbSJung-uk Kim      */
44367bded2dbSJung-uk Kim     if (!check_flags) {
44377bded2dbSJung-uk Kim         if (rv & CERT_PKEY_VALID)
44387bded2dbSJung-uk Kim             cpk->valid_flags = rv;
44397bded2dbSJung-uk Kim         else {
44407bded2dbSJung-uk Kim             /* Preserve explicit sign flag, clear rest */
44417bded2dbSJung-uk Kim             cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
44427bded2dbSJung-uk Kim             return 0;
44437bded2dbSJung-uk Kim         }
44447bded2dbSJung-uk Kim     }
44457bded2dbSJung-uk Kim     return rv;
44467bded2dbSJung-uk Kim }
44477bded2dbSJung-uk Kim 
44487bded2dbSJung-uk Kim /* Set validity of certificates in an SSL structure */
44497bded2dbSJung-uk Kim void tls1_set_cert_validity(SSL *s)
44507bded2dbSJung-uk Kim {
44517bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
44527bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
44537bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
44547bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA);
44557bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA);
44567bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
44577bded2dbSJung-uk Kim }
44587bded2dbSJung-uk Kim 
44597bded2dbSJung-uk Kim /* User level utiity function to check a chain is suitable */
44607bded2dbSJung-uk Kim int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
44617bded2dbSJung-uk Kim {
44627bded2dbSJung-uk Kim     return tls1_check_chain(s, x, pk, chain, -1);
44637bded2dbSJung-uk Kim }
44647bded2dbSJung-uk Kim 
44657bded2dbSJung-uk Kim #endif
4466