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