174664626SKris Kennaway /* ssl/t1_lib.c */ 274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 374664626SKris Kennaway * All rights reserved. 474664626SKris Kennaway * 574664626SKris Kennaway * This package is an SSL implementation written 674664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 774664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 874664626SKris Kennaway * 974664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1074664626SKris Kennaway * the following conditions are aheared to. The following conditions 1174664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1274664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1374664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1474664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1574664626SKris Kennaway * 1674664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1774664626SKris Kennaway * the code are not to be removed. 1874664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 1974664626SKris Kennaway * as the author of the parts of the library used. 2074664626SKris Kennaway * This can be in the form of a textual message at program startup or 2174664626SKris Kennaway * in documentation (online or textual) provided with the package. 2274664626SKris Kennaway * 2374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2474664626SKris Kennaway * modification, are permitted provided that the following conditions 2574664626SKris Kennaway * are met: 2674664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2774664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 2874664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3074664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3174664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3274664626SKris Kennaway * must display the following acknowledgement: 3374664626SKris Kennaway * "This product includes cryptographic software written by 3474664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3574664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3674664626SKris Kennaway * being used are not cryptographic related :-). 3774664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 3874664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 3974664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4074664626SKris Kennaway * 4174664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4274664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4374664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4474664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4574664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4674664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4774664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4874664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4974664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5074664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5174664626SKris Kennaway * SUCH DAMAGE. 5274664626SKris Kennaway * 5374664626SKris Kennaway * The licence and distribution terms for any publically available version or 5474664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5574664626SKris Kennaway * copied and put under another distribution licence 5674664626SKris Kennaway * [including the GNU Public Licence.] 5774664626SKris Kennaway */ 581f13597dSJung-uk Kim /* ==================================================================== 591f13597dSJung-uk Kim * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 601f13597dSJung-uk Kim * 611f13597dSJung-uk Kim * Redistribution and use in source and binary forms, with or without 621f13597dSJung-uk Kim * modification, are permitted provided that the following conditions 631f13597dSJung-uk Kim * are met: 641f13597dSJung-uk Kim * 651f13597dSJung-uk Kim * 1. Redistributions of source code must retain the above copyright 661f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer. 671f13597dSJung-uk Kim * 681f13597dSJung-uk Kim * 2. Redistributions in binary form must reproduce the above copyright 691f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer in 701f13597dSJung-uk Kim * the documentation and/or other materials provided with the 711f13597dSJung-uk Kim * distribution. 721f13597dSJung-uk Kim * 731f13597dSJung-uk Kim * 3. All advertising materials mentioning features or use of this 741f13597dSJung-uk Kim * software must display the following acknowledgment: 751f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 761f13597dSJung-uk Kim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 771f13597dSJung-uk Kim * 781f13597dSJung-uk Kim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 791f13597dSJung-uk Kim * endorse or promote products derived from this software without 801f13597dSJung-uk Kim * prior written permission. For written permission, please contact 811f13597dSJung-uk Kim * openssl-core@openssl.org. 821f13597dSJung-uk Kim * 831f13597dSJung-uk Kim * 5. Products derived from this software may not be called "OpenSSL" 841f13597dSJung-uk Kim * nor may "OpenSSL" appear in their names without prior written 851f13597dSJung-uk Kim * permission of the OpenSSL Project. 861f13597dSJung-uk Kim * 871f13597dSJung-uk Kim * 6. Redistributions of any form whatsoever must retain the following 881f13597dSJung-uk Kim * acknowledgment: 891f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 901f13597dSJung-uk Kim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 911f13597dSJung-uk Kim * 921f13597dSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 931f13597dSJung-uk Kim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 941f13597dSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 951f13597dSJung-uk Kim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 961f13597dSJung-uk Kim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 971f13597dSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 981f13597dSJung-uk Kim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 991f13597dSJung-uk Kim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1001f13597dSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1011f13597dSJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1021f13597dSJung-uk Kim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1031f13597dSJung-uk Kim * OF THE POSSIBILITY OF SUCH DAMAGE. 1041f13597dSJung-uk Kim * ==================================================================== 1051f13597dSJung-uk Kim * 1061f13597dSJung-uk Kim * This product includes cryptographic software written by Eric Young 1071f13597dSJung-uk Kim * (eay@cryptsoft.com). This product includes software written by Tim 1081f13597dSJung-uk Kim * Hudson (tjh@cryptsoft.com). 1091f13597dSJung-uk Kim * 1101f13597dSJung-uk Kim */ 11174664626SKris Kennaway 11274664626SKris Kennaway #include <stdio.h> 11374664626SKris Kennaway #include <openssl/objects.h> 114db522d3aSSimon L. B. Nielsen #include <openssl/evp.h> 115db522d3aSSimon L. B. Nielsen #include <openssl/hmac.h> 1167bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC 1177bded2dbSJung-uk Kim #ifdef OPENSSL_NO_EC2M 1187bded2dbSJung-uk Kim # include <openssl/ec.h> 1197bded2dbSJung-uk Kim #endif 1207bded2dbSJung-uk Kim #endif 121db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h> 1221f13597dSJung-uk Kim #include <openssl/rand.h> 12374664626SKris Kennaway #include "ssl_locl.h" 12474664626SKris Kennaway 1255471f83eSSimon L. B. Nielsen const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; 12674664626SKris Kennaway 127db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 128db522d3aSSimon L. B. Nielsen static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, 129db522d3aSSimon L. B. Nielsen const unsigned char *sess_id, int sesslen, 130db522d3aSSimon L. B. Nielsen SSL_SESSION **psess); 1317bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s); 1327bded2dbSJung-uk Kim int ssl_check_serverhello_tlsext(SSL *s); 133db522d3aSSimon L. B. Nielsen #endif 134db522d3aSSimon L. B. Nielsen 135*6cf8931aSJung-uk Kim #define CHECKLEN(curr, val, limit) \ 136*6cf8931aSJung-uk Kim (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val)) 137*6cf8931aSJung-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 10387bded2dbSJung-uk Kim size_t tls12_get_psigalgs(SSL *s, 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 */ 10607bded2dbSJung-uk Kim if (s->server && 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 */ 11247bded2dbSJung-uk Kim sent_sigslen = tls12_get_psigalgs(s, &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 */ 11727bded2dbSJung-uk Kim sigalgslen = tls12_get_psigalgs(s, &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 */ 1269*6cf8931aSJung-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 */ 1279*6cf8931aSJung-uk Kim size_str = strlen(s->tlsext_hostname); 1280*6cf8931aSJung-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 1324*6cf8931aSJung-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 */ 1336*6cf8931aSJung-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 } 1362*6cf8931aSJung-uk Kim /*- 1363*6cf8931aSJung-uk Kim * check for enough space. 1364*6cf8931aSJung-uk Kim * 4 bytes for the ec point formats type and extension length 1365*6cf8931aSJung-uk Kim * 1 byte for the length of the formats 1366*6cf8931aSJung-uk Kim * + formats length 1367*6cf8931aSJung-uk Kim */ 1368*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 5 + num_formats, limit)) 1369*6cf8931aSJung-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; 1390*6cf8931aSJung-uk Kim /*- 1391*6cf8931aSJung-uk Kim * check for enough space. 1392*6cf8931aSJung-uk Kim * 4 bytes for the ec curves type and extension length 1393*6cf8931aSJung-uk Kim * 2 bytes for the curve list length 1394*6cf8931aSJung-uk Kim * + curve list length 1395*6cf8931aSJung-uk Kim */ 1396*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 6 + curves_list_len, limit)) 1397*6cf8931aSJung-uk Kim return NULL; 1398*6cf8931aSJung-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)) { 1408*6cf8931aSJung-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 */ 1429*6cf8931aSJung-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); 1433*6cf8931aSJung-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; 14437bded2dbSJung-uk Kim salglen = tls12_get_psigalgs(s, &salg); 1444*6cf8931aSJung-uk Kim 1445*6cf8931aSJung-uk Kim /*- 1446*6cf8931aSJung-uk Kim * check for enough space. 1447*6cf8931aSJung-uk Kim * 4 bytes for the sigalgs type and extension length 1448*6cf8931aSJung-uk Kim * 2 bytes for the sigalg list length 1449*6cf8931aSJung-uk Kim * + sigalg list length 1450*6cf8931aSJung-uk Kim */ 1451*6cf8931aSJung-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; 1478*6cf8931aSJung-uk Kim size_t extlen, idlen; 1479*6cf8931aSJung-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); 1485*6cf8931aSJung-uk Kim lentmp = i2d_OCSP_RESPID(id, NULL); 1486*6cf8931aSJung-uk Kim if (lentmp <= 0) 1487db522d3aSSimon L. B. Nielsen return NULL; 1488*6cf8931aSJung-uk Kim idlen += (size_t)lentmp + 2; 1489db522d3aSSimon L. B. Nielsen } 1490db522d3aSSimon L. B. Nielsen 14916f9291ceSJung-uk Kim if (s->tlsext_ocsp_exts) { 1492*6cf8931aSJung-uk Kim lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); 1493*6cf8931aSJung-uk Kim if (lentmp < 0) 1494db522d3aSSimon L. B. Nielsen return NULL; 1495*6cf8931aSJung-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; 1501*6cf8931aSJung-uk Kim /* 1502*6cf8931aSJung-uk Kim * 2 bytes for status request type 1503*6cf8931aSJung-uk Kim * 2 bytes for status request len 1504*6cf8931aSJung-uk Kim * 1 byte for OCSP request type 1505*6cf8931aSJung-uk Kim * 2 bytes for length of ids 1506*6cf8931aSJung-uk Kim * 2 bytes for length of extensions 1507*6cf8931aSJung-uk Kim * + length of ids 1508*6cf8931aSJung-uk Kim * + length of extensions 1509*6cf8931aSJung-uk Kim */ 1510*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 9 + idlen + extlen, limit)) 1511*6cf8931aSJung-uk Kim return NULL; 1512*6cf8931aSJung-uk Kim 1513*6cf8931aSJung-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; 1523*6cf8931aSJung-uk Kim lentmp = i2d_OCSP_RESPID(id, &ret); 1524db522d3aSSimon L. B. Nielsen /* write id len */ 1525*6cf8931aSJung-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 */ 1533*6cf8931aSJung-uk Kim 1534*6cf8931aSJung-uk Kim /*- 1535*6cf8931aSJung-uk Kim * check for enough space. 1536*6cf8931aSJung-uk Kim * 4 bytes for the heartbeat ext type and extension length 1537*6cf8931aSJung-uk Kim * 1 byte for the mode 1538*6cf8931aSJung-uk Kim */ 1539*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 5, limit)) 154094ad176cSJung-uk Kim return NULL; 1541*6cf8931aSJung-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 */ 1561*6cf8931aSJung-uk Kim 1562*6cf8931aSJung-uk Kim /*- 1563*6cf8931aSJung-uk Kim * check for enough space. 1564*6cf8931aSJung-uk Kim * 4 bytes for the NPN ext type and extension length 1565*6cf8931aSJung-uk Kim */ 1566*6cf8931aSJung-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) { 1574*6cf8931aSJung-uk Kim /*- 1575*6cf8931aSJung-uk Kim * check for enough space. 1576*6cf8931aSJung-uk Kim * 4 bytes for the ALPN type and extension length 1577*6cf8931aSJung-uk Kim * 2 bytes for the ALPN protocol list length 1578*6cf8931aSJung-uk Kim * + ALPN protocol list length 1579*6cf8931aSJung-uk Kim */ 1580*6cf8931aSJung-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 1595*6cf8931aSJung-uk Kim /*- 1596*6cf8931aSJung-uk Kim * check for enough space. 1597*6cf8931aSJung-uk Kim * 4 bytes for the SRTP type and extension length 1598*6cf8931aSJung-uk Kim * + SRTP profiles length 1599*6cf8931aSJung-uk Kim */ 1600*6cf8931aSJung-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 1640*6cf8931aSJung-uk Kim /*- 1641*6cf8931aSJung-uk Kim * check for enough space. Strictly speaking we know we've already 1642*6cf8931aSJung-uk Kim * got enough space because to get here the message size is < 0x200, 1643*6cf8931aSJung-uk Kim * but we know that we've allocated far more than that in the buffer 1644*6cf8931aSJung-uk Kim * - but for consistency and robustness we're going to check anyway. 1645*6cf8931aSJung-uk Kim * 1646*6cf8931aSJung-uk Kim * 4 bytes for the padding type and extension length 1647*6cf8931aSJung-uk Kim * + padding length 1648*6cf8931aSJung-uk Kim */ 1649*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 4 + hlen, limit)) 1650*6cf8931aSJung-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 1708*6cf8931aSJung-uk Kim /*- 1709*6cf8931aSJung-uk Kim * check for enough space. 1710*6cf8931aSJung-uk Kim * 4 bytes for the reneg type and extension length 1711*6cf8931aSJung-uk Kim * + reneg data length 1712*6cf8931aSJung-uk Kim */ 1713*6cf8931aSJung-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 1741*6cf8931aSJung-uk Kim /*- 1742*6cf8931aSJung-uk Kim * check for enough space. 1743*6cf8931aSJung-uk Kim * 4 bytes for the ec points format type and extension length 1744*6cf8931aSJung-uk Kim * 1 byte for the points format list length 1745*6cf8931aSJung-uk Kim * + length of points format list 1746*6cf8931aSJung-uk Kim */ 1747*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 5 + plistlen, limit)) 1748*6cf8931aSJung-uk Kim return NULL; 1749*6cf8931aSJung-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)) { 1764*6cf8931aSJung-uk Kim /*- 1765*6cf8931aSJung-uk Kim * check for enough space. 1766*6cf8931aSJung-uk Kim * 4 bytes for the Ticket type and extension length 1767*6cf8931aSJung-uk Kim */ 1768*6cf8931aSJung-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); 1772db522d3aSSimon L. B. Nielsen } 1773db522d3aSSimon L. B. Nielsen 17746f9291ceSJung-uk Kim if (s->tlsext_status_expected) { 1775*6cf8931aSJung-uk Kim /*- 1776*6cf8931aSJung-uk Kim * check for enough space. 1777*6cf8931aSJung-uk Kim * 4 bytes for the Status request type and extension length 1778*6cf8931aSJung-uk Kim */ 1779*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 4, limit)) 17806f9291ceSJung-uk Kim return NULL; 1781db522d3aSSimon L. B. Nielsen s2n(TLSEXT_TYPE_status_request, ret); 1782db522d3aSSimon L. B. Nielsen s2n(0, ret); 1783db522d3aSSimon L. B. Nielsen } 17841f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input 17857bded2dbSJung-uk Kim if (s->s3->server_opaque_prf_input != NULL) { 17861f13597dSJung-uk Kim size_t sol = s->s3->server_opaque_prf_input_len; 17871f13597dSJung-uk Kim 17881f13597dSJung-uk Kim if ((long)(limit - ret - 6 - sol) < 0) 17891f13597dSJung-uk Kim return NULL; 17901f13597dSJung-uk Kim if (sol > 0xFFFD) /* can't happen */ 17911f13597dSJung-uk Kim return NULL; 17921f13597dSJung-uk Kim 17931f13597dSJung-uk Kim s2n(TLSEXT_TYPE_opaque_prf_input, ret); 17941f13597dSJung-uk Kim s2n(sol + 2, ret); 17951f13597dSJung-uk Kim s2n(sol, ret); 17961f13597dSJung-uk Kim memcpy(ret, s->s3->server_opaque_prf_input, sol); 17971f13597dSJung-uk Kim ret += sol; 17981f13597dSJung-uk Kim } 17991f13597dSJung-uk Kim # endif 18001f13597dSJung-uk Kim 180109286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP 18026f9291ceSJung-uk Kim if (SSL_IS_DTLS(s) && s->srtp_profile) { 18031f13597dSJung-uk Kim int el; 18041f13597dSJung-uk Kim 18051f13597dSJung-uk Kim ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); 18061f13597dSJung-uk Kim 1807*6cf8931aSJung-uk Kim /*- 1808*6cf8931aSJung-uk Kim * check for enough space. 1809*6cf8931aSJung-uk Kim * 4 bytes for the SRTP profiles type and extension length 1810*6cf8931aSJung-uk Kim * + length of the SRTP profiles list 1811*6cf8931aSJung-uk Kim */ 1812*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 4 + el, limit)) 18136f9291ceSJung-uk Kim return NULL; 18141f13597dSJung-uk Kim 18151f13597dSJung-uk Kim s2n(TLSEXT_TYPE_use_srtp, ret); 18161f13597dSJung-uk Kim s2n(el, ret); 18171f13597dSJung-uk Kim 18186f9291ceSJung-uk Kim if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { 18191f13597dSJung-uk Kim SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); 18201f13597dSJung-uk Kim return NULL; 18211f13597dSJung-uk Kim } 18221f13597dSJung-uk Kim ret += el; 18231f13597dSJung-uk Kim } 182409286989SJung-uk Kim # endif 18251f13597dSJung-uk Kim 18266f9291ceSJung-uk Kim if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 18276f9291ceSJung-uk Kim || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) 18286f9291ceSJung-uk Kim && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) { 18296f9291ceSJung-uk Kim const unsigned char cryptopro_ext[36] = { 18301f13597dSJung-uk Kim 0xfd, 0xe8, /* 65000 */ 18311f13597dSJung-uk Kim 0x00, 0x20, /* 32 bytes length */ 18321f13597dSJung-uk Kim 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, 18331f13597dSJung-uk Kim 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, 18341f13597dSJung-uk Kim 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, 18356f9291ceSJung-uk Kim 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 18366f9291ceSJung-uk Kim }; 1837*6cf8931aSJung-uk Kim 1838*6cf8931aSJung-uk Kim /* check for enough space. */ 1839*6cf8931aSJung-uk Kim if (CHECKLEN(ret, sizeof(cryptopro_ext), limit)) 18406f9291ceSJung-uk Kim return NULL; 1841*6cf8931aSJung-uk Kim memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext)); 1842*6cf8931aSJung-uk Kim ret += sizeof(cryptopro_ext); 18431f13597dSJung-uk Kim 18441f13597dSJung-uk Kim } 18451f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS 18461f13597dSJung-uk Kim /* Add Heartbeat extension if we've received one */ 18476f9291ceSJung-uk Kim if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { 1848*6cf8931aSJung-uk Kim /*- 1849*6cf8931aSJung-uk Kim * check for enough space. 1850*6cf8931aSJung-uk Kim * 4 bytes for the Heartbeat type and extension length 1851*6cf8931aSJung-uk Kim * 1 byte for the mode 1852*6cf8931aSJung-uk Kim */ 1853*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 5, limit)) 185494ad176cSJung-uk Kim return NULL; 18551f13597dSJung-uk Kim s2n(TLSEXT_TYPE_heartbeat, ret); 18561f13597dSJung-uk Kim s2n(1, ret); 18576f9291ceSJung-uk Kim /*- 18586f9291ceSJung-uk Kim * Set mode: 18591f13597dSJung-uk Kim * 1: peer may send requests 18601f13597dSJung-uk Kim * 2: peer not allowed to send requests 18611f13597dSJung-uk Kim */ 18621f13597dSJung-uk Kim if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) 18631f13597dSJung-uk Kim *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; 18641f13597dSJung-uk Kim else 18651f13597dSJung-uk Kim *(ret++) = SSL_TLSEXT_HB_ENABLED; 18661f13597dSJung-uk Kim 18671f13597dSJung-uk Kim } 18681f13597dSJung-uk Kim # endif 18691f13597dSJung-uk Kim 18701f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 18711f13597dSJung-uk Kim next_proto_neg_seen = s->s3->next_proto_neg_seen; 18721f13597dSJung-uk Kim s->s3->next_proto_neg_seen = 0; 18736f9291ceSJung-uk Kim if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { 18741f13597dSJung-uk Kim const unsigned char *npa; 18751f13597dSJung-uk Kim unsigned int npalen; 18761f13597dSJung-uk Kim int r; 18771f13597dSJung-uk Kim 18786f9291ceSJung-uk Kim r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, 18796f9291ceSJung-uk Kim s-> 18806f9291ceSJung-uk Kim ctx->next_protos_advertised_cb_arg); 18816f9291ceSJung-uk Kim if (r == SSL_TLSEXT_ERR_OK) { 1882*6cf8931aSJung-uk Kim /*- 1883*6cf8931aSJung-uk Kim * check for enough space. 1884*6cf8931aSJung-uk Kim * 4 bytes for the NPN type and extension length 1885*6cf8931aSJung-uk Kim * + length of protocols list 1886*6cf8931aSJung-uk Kim */ 1887*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 4 + npalen, limit)) 18886f9291ceSJung-uk Kim return NULL; 18891f13597dSJung-uk Kim s2n(TLSEXT_TYPE_next_proto_neg, ret); 18901f13597dSJung-uk Kim s2n(npalen, ret); 18911f13597dSJung-uk Kim memcpy(ret, npa, npalen); 18921f13597dSJung-uk Kim ret += npalen; 18931f13597dSJung-uk Kim s->s3->next_proto_neg_seen = 1; 18941f13597dSJung-uk Kim } 18951f13597dSJung-uk Kim } 18961f13597dSJung-uk Kim # endif 18977bded2dbSJung-uk Kim if (!custom_ext_add(s, 1, &ret, limit, al)) 18987bded2dbSJung-uk Kim return NULL; 18997bded2dbSJung-uk Kim 19007bded2dbSJung-uk Kim if (s->s3->alpn_selected) { 19017bded2dbSJung-uk Kim const unsigned char *selected = s->s3->alpn_selected; 1902*6cf8931aSJung-uk Kim size_t len = s->s3->alpn_selected_len; 19037bded2dbSJung-uk Kim 1904*6cf8931aSJung-uk Kim /*- 1905*6cf8931aSJung-uk Kim * check for enough space. 1906*6cf8931aSJung-uk Kim * 4 bytes for the ALPN type and extension length 1907*6cf8931aSJung-uk Kim * 2 bytes for ALPN data length 1908*6cf8931aSJung-uk Kim * 1 byte for selected protocol length 1909*6cf8931aSJung-uk Kim * + length of the selected protocol 1910*6cf8931aSJung-uk Kim */ 1911*6cf8931aSJung-uk Kim if (CHECKLEN(ret, 7 + len, limit)) 19127bded2dbSJung-uk Kim return NULL; 19137bded2dbSJung-uk Kim s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); 19147bded2dbSJung-uk Kim s2n(3 + len, ret); 19157bded2dbSJung-uk Kim s2n(1 + len, ret); 19167bded2dbSJung-uk Kim *ret++ = len; 19177bded2dbSJung-uk Kim memcpy(ret, selected, len); 19187bded2dbSJung-uk Kim ret += len; 19197bded2dbSJung-uk Kim } 19201f13597dSJung-uk Kim 1921a93cbc2bSJung-uk Kim if ((extdatalen = ret - orig - 2) == 0) 1922a93cbc2bSJung-uk Kim return orig; 1923db522d3aSSimon L. B. Nielsen 1924a93cbc2bSJung-uk Kim s2n(extdatalen, orig); 1925db522d3aSSimon L. B. Nielsen return ret; 1926db522d3aSSimon L. B. Nielsen } 1927db522d3aSSimon L. B. Nielsen 1928de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC 19296f9291ceSJung-uk Kim /*- 19306f9291ceSJung-uk Kim * ssl_check_for_safari attempts to fingerprint Safari using OS X 1931de78d5d8SJung-uk Kim * SecureTransport using the TLS extension block in |d|, of length |n|. 1932de78d5d8SJung-uk Kim * Safari, since 10.6, sends exactly these extensions, in this order: 1933de78d5d8SJung-uk Kim * SNI, 1934de78d5d8SJung-uk Kim * elliptic_curves 1935de78d5d8SJung-uk Kim * ec_point_formats 1936de78d5d8SJung-uk Kim * 1937de78d5d8SJung-uk Kim * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8, 1938de78d5d8SJung-uk Kim * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them. 1939de78d5d8SJung-uk Kim * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from 1940de78d5d8SJung-uk Kim * 10.8..10.8.3 (which don't work). 1941de78d5d8SJung-uk Kim */ 19426f9291ceSJung-uk Kim static void ssl_check_for_safari(SSL *s, const unsigned char *data, 194380815a77SJung-uk Kim const unsigned char *limit) 19446f9291ceSJung-uk Kim { 1945de78d5d8SJung-uk Kim unsigned short type, size; 1946de78d5d8SJung-uk Kim static const unsigned char kSafariExtensionsBlock[] = { 1947de78d5d8SJung-uk Kim 0x00, 0x0a, /* elliptic_curves extension */ 1948de78d5d8SJung-uk Kim 0x00, 0x08, /* 8 bytes */ 1949de78d5d8SJung-uk Kim 0x00, 0x06, /* 6 bytes of curve ids */ 1950de78d5d8SJung-uk Kim 0x00, 0x17, /* P-256 */ 1951de78d5d8SJung-uk Kim 0x00, 0x18, /* P-384 */ 1952de78d5d8SJung-uk Kim 0x00, 0x19, /* P-521 */ 1953de78d5d8SJung-uk Kim 1954de78d5d8SJung-uk Kim 0x00, 0x0b, /* ec_point_formats */ 1955de78d5d8SJung-uk Kim 0x00, 0x02, /* 2 bytes */ 1956de78d5d8SJung-uk Kim 0x01, /* 1 point format */ 1957de78d5d8SJung-uk Kim 0x00, /* uncompressed */ 1958de78d5d8SJung-uk Kim }; 1959de78d5d8SJung-uk Kim 1960de78d5d8SJung-uk Kim /* The following is only present in TLS 1.2 */ 1961de78d5d8SJung-uk Kim static const unsigned char kSafariTLS12ExtensionsBlock[] = { 1962de78d5d8SJung-uk Kim 0x00, 0x0d, /* signature_algorithms */ 1963de78d5d8SJung-uk Kim 0x00, 0x0c, /* 12 bytes */ 1964de78d5d8SJung-uk Kim 0x00, 0x0a, /* 10 bytes */ 1965de78d5d8SJung-uk Kim 0x05, 0x01, /* SHA-384/RSA */ 1966de78d5d8SJung-uk Kim 0x04, 0x01, /* SHA-256/RSA */ 1967de78d5d8SJung-uk Kim 0x02, 0x01, /* SHA-1/RSA */ 1968de78d5d8SJung-uk Kim 0x04, 0x03, /* SHA-256/ECDSA */ 1969de78d5d8SJung-uk Kim 0x02, 0x03, /* SHA-1/ECDSA */ 1970de78d5d8SJung-uk Kim }; 1971de78d5d8SJung-uk Kim 1972aeb5019cSJung-uk Kim if (limit - data <= 2) 1973de78d5d8SJung-uk Kim return; 1974de78d5d8SJung-uk Kim data += 2; 1975de78d5d8SJung-uk Kim 1976aeb5019cSJung-uk Kim if (limit - data < 4) 1977de78d5d8SJung-uk Kim return; 1978de78d5d8SJung-uk Kim n2s(data, type); 1979de78d5d8SJung-uk Kim n2s(data, size); 1980de78d5d8SJung-uk Kim 1981de78d5d8SJung-uk Kim if (type != TLSEXT_TYPE_server_name) 1982de78d5d8SJung-uk Kim return; 1983de78d5d8SJung-uk Kim 1984aeb5019cSJung-uk Kim if (limit - data < size) 1985de78d5d8SJung-uk Kim return; 1986de78d5d8SJung-uk Kim data += size; 1987de78d5d8SJung-uk Kim 19886f9291ceSJung-uk Kim if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { 1989de78d5d8SJung-uk Kim const size_t len1 = sizeof(kSafariExtensionsBlock); 1990de78d5d8SJung-uk Kim const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); 1991de78d5d8SJung-uk Kim 1992aeb5019cSJung-uk Kim if (limit - data != (int)(len1 + len2)) 1993de78d5d8SJung-uk Kim return; 1994de78d5d8SJung-uk Kim if (memcmp(data, kSafariExtensionsBlock, len1) != 0) 1995de78d5d8SJung-uk Kim return; 1996de78d5d8SJung-uk Kim if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0) 1997de78d5d8SJung-uk Kim return; 19986f9291ceSJung-uk Kim } else { 1999de78d5d8SJung-uk Kim const size_t len = sizeof(kSafariExtensionsBlock); 2000de78d5d8SJung-uk Kim 2001aeb5019cSJung-uk Kim if (limit - data != (int)(len)) 2002de78d5d8SJung-uk Kim return; 2003de78d5d8SJung-uk Kim if (memcmp(data, kSafariExtensionsBlock, len) != 0) 2004de78d5d8SJung-uk Kim return; 2005de78d5d8SJung-uk Kim } 2006de78d5d8SJung-uk Kim 2007de78d5d8SJung-uk Kim s->s3->is_probably_safari = 1; 2008de78d5d8SJung-uk Kim } 2009de78d5d8SJung-uk Kim # endif /* !OPENSSL_NO_EC */ 2010de78d5d8SJung-uk Kim 20117bded2dbSJung-uk Kim /* 2012b8721c16SJung-uk Kim * tls1_alpn_handle_client_hello is called to save the ALPN extension in a 20137bded2dbSJung-uk Kim * ClientHello. data: the contents of the extension, not including the type 20147bded2dbSJung-uk Kim * and length. data_len: the number of bytes in |data| al: a pointer to the 20157bded2dbSJung-uk Kim * alert value to send in the event of a non-zero return. returns: 0 on 20167bded2dbSJung-uk Kim * success. 20177bded2dbSJung-uk Kim */ 20187bded2dbSJung-uk Kim static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, 20197bded2dbSJung-uk Kim unsigned data_len, int *al) 20207bded2dbSJung-uk Kim { 20217bded2dbSJung-uk Kim unsigned i; 20227bded2dbSJung-uk Kim unsigned proto_len; 20237bded2dbSJung-uk Kim 20247bded2dbSJung-uk Kim if (data_len < 2) 20257bded2dbSJung-uk Kim goto parse_error; 20267bded2dbSJung-uk Kim 20277bded2dbSJung-uk Kim /* 20287bded2dbSJung-uk Kim * data should contain a uint16 length followed by a series of 8-bit, 20297bded2dbSJung-uk Kim * length-prefixed strings. 20307bded2dbSJung-uk Kim */ 20317bded2dbSJung-uk Kim i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]); 20327bded2dbSJung-uk Kim data_len -= 2; 20337bded2dbSJung-uk Kim data += 2; 20347bded2dbSJung-uk Kim if (data_len != i) 20357bded2dbSJung-uk Kim goto parse_error; 20367bded2dbSJung-uk Kim 20377bded2dbSJung-uk Kim if (data_len < 2) 20387bded2dbSJung-uk Kim goto parse_error; 20397bded2dbSJung-uk Kim 20407bded2dbSJung-uk Kim for (i = 0; i < data_len;) { 20417bded2dbSJung-uk Kim proto_len = data[i]; 20427bded2dbSJung-uk Kim i++; 20437bded2dbSJung-uk Kim 20447bded2dbSJung-uk Kim if (proto_len == 0) 20457bded2dbSJung-uk Kim goto parse_error; 20467bded2dbSJung-uk Kim 20477bded2dbSJung-uk Kim if (i + proto_len < i || i + proto_len > data_len) 20487bded2dbSJung-uk Kim goto parse_error; 20497bded2dbSJung-uk Kim 20507bded2dbSJung-uk Kim i += proto_len; 20517bded2dbSJung-uk Kim } 20527bded2dbSJung-uk Kim 2053b8721c16SJung-uk Kim if (s->cert->alpn_proposed != NULL) 2054b8721c16SJung-uk Kim OPENSSL_free(s->cert->alpn_proposed); 2055b8721c16SJung-uk Kim s->cert->alpn_proposed = OPENSSL_malloc(data_len); 2056b8721c16SJung-uk Kim if (s->cert->alpn_proposed == NULL) { 20577bded2dbSJung-uk Kim *al = SSL_AD_INTERNAL_ERROR; 20587bded2dbSJung-uk Kim return -1; 20597bded2dbSJung-uk Kim } 2060b8721c16SJung-uk Kim memcpy(s->cert->alpn_proposed, data, data_len); 2061b8721c16SJung-uk Kim s->cert->alpn_proposed_len = data_len; 20627bded2dbSJung-uk Kim return 0; 20637bded2dbSJung-uk Kim 20647bded2dbSJung-uk Kim parse_error: 20657bded2dbSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 20667bded2dbSJung-uk Kim return -1; 20677bded2dbSJung-uk Kim } 20687bded2dbSJung-uk Kim 2069b8721c16SJung-uk Kim /* 2070b8721c16SJung-uk Kim * Process the ALPN extension in a ClientHello. 2071b8721c16SJung-uk Kim * al: a pointer to the alert value to send in the event of a failure. 2072*6cf8931aSJung-uk Kim * returns 1 on success, 0 on failure: al set only on failure 2073b8721c16SJung-uk Kim */ 2074*6cf8931aSJung-uk Kim static int tls1_alpn_handle_client_hello_late(SSL *s, int *al) 2075b8721c16SJung-uk Kim { 2076b8721c16SJung-uk Kim const unsigned char *selected = NULL; 2077b8721c16SJung-uk Kim unsigned char selected_len = 0; 2078b8721c16SJung-uk Kim 2079b8721c16SJung-uk Kim if (s->ctx->alpn_select_cb != NULL && s->cert->alpn_proposed != NULL) { 2080b8721c16SJung-uk Kim int r = s->ctx->alpn_select_cb(s, &selected, &selected_len, 2081b8721c16SJung-uk Kim s->cert->alpn_proposed, 2082b8721c16SJung-uk Kim s->cert->alpn_proposed_len, 2083b8721c16SJung-uk Kim s->ctx->alpn_select_cb_arg); 2084b8721c16SJung-uk Kim 2085b8721c16SJung-uk Kim if (r == SSL_TLSEXT_ERR_OK) { 2086b8721c16SJung-uk Kim OPENSSL_free(s->s3->alpn_selected); 2087b8721c16SJung-uk Kim s->s3->alpn_selected = OPENSSL_malloc(selected_len); 2088b8721c16SJung-uk Kim if (s->s3->alpn_selected == NULL) { 2089b8721c16SJung-uk Kim *al = SSL_AD_INTERNAL_ERROR; 2090b8721c16SJung-uk Kim return 0; 2091b8721c16SJung-uk Kim } 2092b8721c16SJung-uk Kim memcpy(s->s3->alpn_selected, selected, selected_len); 2093b8721c16SJung-uk Kim s->s3->alpn_selected_len = selected_len; 2094b8721c16SJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 2095b8721c16SJung-uk Kim /* ALPN takes precedence over NPN. */ 2096b8721c16SJung-uk Kim s->s3->next_proto_neg_seen = 0; 2097b8721c16SJung-uk Kim # endif 2098b8721c16SJung-uk Kim } 2099b8721c16SJung-uk Kim } 2100b8721c16SJung-uk Kim 2101b8721c16SJung-uk Kim return 1; 2102b8721c16SJung-uk Kim } 2103b8721c16SJung-uk Kim 21047bded2dbSJung-uk Kim static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, 210580815a77SJung-uk Kim unsigned char *limit, int *al) 2106db522d3aSSimon L. B. Nielsen { 2107db522d3aSSimon L. B. Nielsen unsigned short type; 2108db522d3aSSimon L. B. Nielsen unsigned short size; 2109db522d3aSSimon L. B. Nielsen unsigned short len; 2110db522d3aSSimon L. B. Nielsen unsigned char *data = *p; 21116a599222SSimon L. B. Nielsen int renegotiate_seen = 0; 21126a599222SSimon L. B. Nielsen 2113db522d3aSSimon L. B. Nielsen s->servername_done = 0; 2114db522d3aSSimon L. B. Nielsen s->tlsext_status_type = -1; 21151f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 21161f13597dSJung-uk Kim s->s3->next_proto_neg_seen = 0; 21171f13597dSJung-uk Kim # endif 21181f13597dSJung-uk Kim 21197bded2dbSJung-uk Kim if (s->s3->alpn_selected) { 21207bded2dbSJung-uk Kim OPENSSL_free(s->s3->alpn_selected); 21217bded2dbSJung-uk Kim s->s3->alpn_selected = NULL; 21227bded2dbSJung-uk Kim } 2123b8721c16SJung-uk Kim s->s3->alpn_selected_len = 0; 2124b8721c16SJung-uk Kim if (s->cert->alpn_proposed) { 2125b8721c16SJung-uk Kim OPENSSL_free(s->cert->alpn_proposed); 2126b8721c16SJung-uk Kim s->cert->alpn_proposed = NULL; 2127b8721c16SJung-uk Kim } 2128b8721c16SJung-uk Kim s->cert->alpn_proposed_len = 0; 21291f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS 21301f13597dSJung-uk Kim s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | 21311f13597dSJung-uk Kim SSL_TLSEXT_HB_DONT_SEND_REQUESTS); 21321f13597dSJung-uk Kim # endif 2133db522d3aSSimon L. B. Nielsen 2134de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC 2135de78d5d8SJung-uk Kim if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) 213680815a77SJung-uk Kim ssl_check_for_safari(s, data, limit); 2137de78d5d8SJung-uk Kim # endif /* !OPENSSL_NO_EC */ 2138de78d5d8SJung-uk Kim 21397bded2dbSJung-uk Kim /* Clear any signature algorithms extension received */ 21407bded2dbSJung-uk Kim if (s->cert->peer_sigalgs) { 21417bded2dbSJung-uk Kim OPENSSL_free(s->cert->peer_sigalgs); 21427bded2dbSJung-uk Kim s->cert->peer_sigalgs = NULL; 21437bded2dbSJung-uk Kim } 2144751d2991SJung-uk Kim # ifndef OPENSSL_NO_SRP 21456f9291ceSJung-uk Kim if (s->srp_ctx.login != NULL) { 2146751d2991SJung-uk Kim OPENSSL_free(s->srp_ctx.login); 2147751d2991SJung-uk Kim s->srp_ctx.login = NULL; 2148751d2991SJung-uk Kim } 2149751d2991SJung-uk Kim # endif 2150751d2991SJung-uk Kim 2151751d2991SJung-uk Kim s->srtp_profile = NULL; 2152751d2991SJung-uk Kim 215380815a77SJung-uk Kim if (data == limit) 21546a599222SSimon L. B. Nielsen goto ri_check; 2155d47910c6SJung-uk Kim 2156aeb5019cSJung-uk Kim if (limit - data < 2) 2157d47910c6SJung-uk Kim goto err; 2158d47910c6SJung-uk Kim 2159db522d3aSSimon L. B. Nielsen n2s(data, len); 2160db522d3aSSimon L. B. Nielsen 2161aeb5019cSJung-uk Kim if (limit - data != len) 2162ed6b93beSJung-uk Kim goto err; 2163db522d3aSSimon L. B. Nielsen 2164aeb5019cSJung-uk Kim while (limit - data >= 4) { 2165db522d3aSSimon L. B. Nielsen n2s(data, type); 2166db522d3aSSimon L. B. Nielsen n2s(data, size); 2167db522d3aSSimon L. B. Nielsen 2168aeb5019cSJung-uk Kim if (limit - data < size) 2169ed6b93beSJung-uk Kim goto err; 21701f13597dSJung-uk Kim # if 0 21711f13597dSJung-uk Kim fprintf(stderr, "Received extension type %d size %d\n", type, size); 21721f13597dSJung-uk Kim # endif 2173db522d3aSSimon L. B. Nielsen if (s->tlsext_debug_cb) 21746f9291ceSJung-uk Kim s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); 21756f9291ceSJung-uk Kim /*- 21766f9291ceSJung-uk Kim * The servername extension is treated as follows: 21776f9291ceSJung-uk Kim * 21786f9291ceSJung-uk Kim * - Only the hostname type is supported with a maximum length of 255. 21796f9291ceSJung-uk Kim * - The servername is rejected if too long or if it contains zeros, 21806f9291ceSJung-uk Kim * in which case an fatal alert is generated. 21816f9291ceSJung-uk Kim * - The servername field is maintained together with the session cache. 21826f9291ceSJung-uk Kim * - When a session is resumed, the servername call back invoked in order 21836f9291ceSJung-uk Kim * to allow the application to position itself to the right context. 21846f9291ceSJung-uk Kim * - The servername is acknowledged if it is new for a session or when 21856f9291ceSJung-uk Kim * it is identical to a previously used for the same session. 21866f9291ceSJung-uk Kim * Applications can control the behaviour. They can at any time 21876f9291ceSJung-uk Kim * set a 'desirable' servername for a new SSL object. This can be the 21886f9291ceSJung-uk Kim * case for example with HTTPS when a Host: header field is received and 21896f9291ceSJung-uk Kim * a renegotiation is requested. In this case, a possible servername 21906f9291ceSJung-uk Kim * presented in the new client hello is only acknowledged if it matches 21916f9291ceSJung-uk Kim * the value of the Host: field. 21926f9291ceSJung-uk Kim * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 21936f9291ceSJung-uk Kim * if they provide for changing an explicit servername context for the 21946f9291ceSJung-uk Kim * session, i.e. when the session has been established with a servername 21956f9291ceSJung-uk Kim * extension. 21966f9291ceSJung-uk Kim * - On session reconnect, the servername extension may be absent. 21976f9291ceSJung-uk Kim * 2198db522d3aSSimon L. B. Nielsen */ 2199db522d3aSSimon L. B. Nielsen 22006f9291ceSJung-uk Kim if (type == TLSEXT_TYPE_server_name) { 2201db522d3aSSimon L. B. Nielsen unsigned char *sdata; 2202db522d3aSSimon L. B. Nielsen int servname_type; 2203db522d3aSSimon L. B. Nielsen int dsize; 2204db522d3aSSimon L. B. Nielsen 2205ed6b93beSJung-uk Kim if (size < 2) 2206ed6b93beSJung-uk Kim goto err; 2207db522d3aSSimon L. B. Nielsen n2s(data, dsize); 2208db522d3aSSimon L. B. Nielsen size -= 2; 2209ed6b93beSJung-uk Kim if (dsize > size) 2210ed6b93beSJung-uk Kim goto err; 2211db522d3aSSimon L. B. Nielsen 2212db522d3aSSimon L. B. Nielsen sdata = data; 22136f9291ceSJung-uk Kim while (dsize > 3) { 2214db522d3aSSimon L. B. Nielsen servname_type = *(sdata++); 2215db522d3aSSimon L. B. Nielsen n2s(sdata, len); 2216db522d3aSSimon L. B. Nielsen dsize -= 3; 2217db522d3aSSimon L. B. Nielsen 2218ed6b93beSJung-uk Kim if (len > dsize) 2219ed6b93beSJung-uk Kim goto err; 2220ed6b93beSJung-uk Kim 2221db522d3aSSimon L. B. Nielsen if (s->servername_done == 0) 22226f9291ceSJung-uk Kim switch (servname_type) { 2223db522d3aSSimon L. B. Nielsen case TLSEXT_NAMETYPE_host_name: 22246f9291ceSJung-uk Kim if (!s->hit) { 2225ed6b93beSJung-uk Kim if (s->session->tlsext_hostname) 2226ed6b93beSJung-uk Kim goto err; 2227ed6b93beSJung-uk Kim 22286f9291ceSJung-uk Kim if (len > TLSEXT_MAXLEN_host_name) { 2229db522d3aSSimon L. B. Nielsen *al = TLS1_AD_UNRECOGNIZED_NAME; 2230db522d3aSSimon L. B. Nielsen return 0; 2231db522d3aSSimon L. B. Nielsen } 22326f9291ceSJung-uk Kim if ((s->session->tlsext_hostname = 22336f9291ceSJung-uk Kim OPENSSL_malloc(len + 1)) == NULL) { 2234a3ddd25aSSimon L. B. Nielsen *al = TLS1_AD_INTERNAL_ERROR; 2235a3ddd25aSSimon L. B. Nielsen return 0; 2236a3ddd25aSSimon L. B. Nielsen } 2237db522d3aSSimon L. B. Nielsen memcpy(s->session->tlsext_hostname, sdata, len); 2238db522d3aSSimon L. B. Nielsen s->session->tlsext_hostname[len] = '\0'; 2239db522d3aSSimon L. B. Nielsen if (strlen(s->session->tlsext_hostname) != len) { 2240db522d3aSSimon L. B. Nielsen OPENSSL_free(s->session->tlsext_hostname); 2241db522d3aSSimon L. B. Nielsen s->session->tlsext_hostname = NULL; 2242db522d3aSSimon L. B. Nielsen *al = TLS1_AD_UNRECOGNIZED_NAME; 2243db522d3aSSimon L. B. Nielsen return 0; 2244db522d3aSSimon L. B. Nielsen } 2245db522d3aSSimon L. B. Nielsen s->servername_done = 1; 2246db522d3aSSimon L. B. Nielsen 22476f9291ceSJung-uk Kim } else 2248a3ddd25aSSimon L. B. Nielsen s->servername_done = s->session->tlsext_hostname 2249a3ddd25aSSimon L. B. Nielsen && strlen(s->session->tlsext_hostname) == len 22506f9291ceSJung-uk Kim && strncmp(s->session->tlsext_hostname, 22516f9291ceSJung-uk Kim (char *)sdata, len) == 0; 2252db522d3aSSimon L. B. Nielsen 2253db522d3aSSimon L. B. Nielsen break; 2254db522d3aSSimon L. B. Nielsen 2255db522d3aSSimon L. B. Nielsen default: 2256db522d3aSSimon L. B. Nielsen break; 2257db522d3aSSimon L. B. Nielsen } 2258db522d3aSSimon L. B. Nielsen 2259db522d3aSSimon L. B. Nielsen dsize -= len; 2260db522d3aSSimon L. B. Nielsen } 2261ed6b93beSJung-uk Kim if (dsize != 0) 2262ed6b93beSJung-uk Kim goto err; 2263db522d3aSSimon L. B. Nielsen 2264db522d3aSSimon L. B. Nielsen } 22651f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP 22666f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_srp) { 2267ed6b93beSJung-uk Kim if (size == 0 || ((len = data[0])) != (size - 1)) 2268ed6b93beSJung-uk Kim goto err; 2269ed6b93beSJung-uk Kim if (s->srp_ctx.login != NULL) 2270ed6b93beSJung-uk Kim goto err; 22711f13597dSJung-uk Kim if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL) 22721f13597dSJung-uk Kim return -1; 22731f13597dSJung-uk Kim memcpy(s->srp_ctx.login, &data[1], len); 22741f13597dSJung-uk Kim s->srp_ctx.login[len] = '\0'; 22751f13597dSJung-uk Kim 2276ed6b93beSJung-uk Kim if (strlen(s->srp_ctx.login) != len) 2277ed6b93beSJung-uk Kim goto err; 22781f13597dSJung-uk Kim } 22791f13597dSJung-uk Kim # endif 22801f13597dSJung-uk Kim 22811f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 22826f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_ec_point_formats) { 22831f13597dSJung-uk Kim unsigned char *sdata = data; 22841f13597dSJung-uk Kim int ecpointformatlist_length = *(sdata++); 22851f13597dSJung-uk Kim 22867bded2dbSJung-uk Kim if (ecpointformatlist_length != size - 1 || 22877bded2dbSJung-uk Kim ecpointformatlist_length < 1) 2288ed6b93beSJung-uk Kim goto err; 22896f9291ceSJung-uk Kim if (!s->hit) { 22906f9291ceSJung-uk Kim if (s->session->tlsext_ecpointformatlist) { 22911f13597dSJung-uk Kim OPENSSL_free(s->session->tlsext_ecpointformatlist); 22921f13597dSJung-uk Kim s->session->tlsext_ecpointformatlist = NULL; 22931f13597dSJung-uk Kim } 22941f13597dSJung-uk Kim s->session->tlsext_ecpointformatlist_length = 0; 22956f9291ceSJung-uk Kim if ((s->session->tlsext_ecpointformatlist = 22966f9291ceSJung-uk Kim OPENSSL_malloc(ecpointformatlist_length)) == NULL) { 22971f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 22981f13597dSJung-uk Kim return 0; 22991f13597dSJung-uk Kim } 23006f9291ceSJung-uk Kim s->session->tlsext_ecpointformatlist_length = 23016f9291ceSJung-uk Kim ecpointformatlist_length; 23026f9291ceSJung-uk Kim memcpy(s->session->tlsext_ecpointformatlist, sdata, 23036f9291ceSJung-uk Kim ecpointformatlist_length); 23041f13597dSJung-uk Kim } 23051f13597dSJung-uk Kim # if 0 23066f9291ceSJung-uk Kim fprintf(stderr, 23076f9291ceSJung-uk Kim "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", 23086f9291ceSJung-uk Kim s->session->tlsext_ecpointformatlist_length); 23091f13597dSJung-uk Kim sdata = s->session->tlsext_ecpointformatlist; 23101f13597dSJung-uk Kim for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) 23111f13597dSJung-uk Kim fprintf(stderr, "%i ", *(sdata++)); 23121f13597dSJung-uk Kim fprintf(stderr, "\n"); 23131f13597dSJung-uk Kim # endif 23146f9291ceSJung-uk Kim } else if (type == TLSEXT_TYPE_elliptic_curves) { 23151f13597dSJung-uk Kim unsigned char *sdata = data; 23161f13597dSJung-uk Kim int ellipticcurvelist_length = (*(sdata++) << 8); 23171f13597dSJung-uk Kim ellipticcurvelist_length += (*(sdata++)); 23181f13597dSJung-uk Kim 231909286989SJung-uk Kim if (ellipticcurvelist_length != size - 2 || 2320751d2991SJung-uk Kim ellipticcurvelist_length < 1 || 2321751d2991SJung-uk Kim /* Each NamedCurve is 2 bytes. */ 2322ed6b93beSJung-uk Kim ellipticcurvelist_length & 1) 2323ed6b93beSJung-uk Kim goto err; 2324ed6b93beSJung-uk Kim 23256f9291ceSJung-uk Kim if (!s->hit) { 2326ed6b93beSJung-uk Kim if (s->session->tlsext_ellipticcurvelist) 2327ed6b93beSJung-uk Kim goto err; 2328ed6b93beSJung-uk Kim 23291f13597dSJung-uk Kim s->session->tlsext_ellipticcurvelist_length = 0; 23306f9291ceSJung-uk Kim if ((s->session->tlsext_ellipticcurvelist = 23316f9291ceSJung-uk Kim OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { 23321f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 23331f13597dSJung-uk Kim return 0; 23341f13597dSJung-uk Kim } 23356f9291ceSJung-uk Kim s->session->tlsext_ellipticcurvelist_length = 23366f9291ceSJung-uk Kim ellipticcurvelist_length; 23376f9291ceSJung-uk Kim memcpy(s->session->tlsext_ellipticcurvelist, sdata, 23386f9291ceSJung-uk Kim ellipticcurvelist_length); 23391f13597dSJung-uk Kim } 23401f13597dSJung-uk Kim # if 0 23416f9291ceSJung-uk Kim fprintf(stderr, 23426f9291ceSJung-uk Kim "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", 23436f9291ceSJung-uk Kim s->session->tlsext_ellipticcurvelist_length); 23441f13597dSJung-uk Kim sdata = s->session->tlsext_ellipticcurvelist; 23451f13597dSJung-uk Kim for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) 23461f13597dSJung-uk Kim fprintf(stderr, "%i ", *(sdata++)); 23471f13597dSJung-uk Kim fprintf(stderr, "\n"); 23481f13597dSJung-uk Kim # endif 23491f13597dSJung-uk Kim } 23501f13597dSJung-uk Kim # endif /* OPENSSL_NO_EC */ 23511f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input 23527bded2dbSJung-uk Kim else if (type == TLSEXT_TYPE_opaque_prf_input) { 23531f13597dSJung-uk Kim unsigned char *sdata = data; 23541f13597dSJung-uk Kim 23556f9291ceSJung-uk Kim if (size < 2) { 23561f13597dSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 23571f13597dSJung-uk Kim return 0; 23581f13597dSJung-uk Kim } 23591f13597dSJung-uk Kim n2s(sdata, s->s3->client_opaque_prf_input_len); 23606f9291ceSJung-uk Kim if (s->s3->client_opaque_prf_input_len != size - 2) { 23611f13597dSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 23621f13597dSJung-uk Kim return 0; 23631f13597dSJung-uk Kim } 23641f13597dSJung-uk Kim 23656f9291ceSJung-uk Kim if (s->s3->client_opaque_prf_input != NULL) { 23666f9291ceSJung-uk Kim /* shouldn't really happen */ 23671f13597dSJung-uk Kim OPENSSL_free(s->s3->client_opaque_prf_input); 23686f9291ceSJung-uk Kim } 23696f9291ceSJung-uk Kim 23706f9291ceSJung-uk Kim /* dummy byte just to get non-NULL */ 23711f13597dSJung-uk Kim if (s->s3->client_opaque_prf_input_len == 0) 23726f9291ceSJung-uk Kim s->s3->client_opaque_prf_input = OPENSSL_malloc(1); 23731f13597dSJung-uk Kim else 23746f9291ceSJung-uk Kim s->s3->client_opaque_prf_input = 23756f9291ceSJung-uk Kim BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); 23766f9291ceSJung-uk Kim if (s->s3->client_opaque_prf_input == NULL) { 23771f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 23781f13597dSJung-uk Kim return 0; 23791f13597dSJung-uk Kim } 23801f13597dSJung-uk Kim } 23811f13597dSJung-uk Kim # endif 23826f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_session_ticket) { 23831f13597dSJung-uk Kim if (s->tls_session_ticket_ext_cb && 23846f9291ceSJung-uk Kim !s->tls_session_ticket_ext_cb(s, data, size, 23856f9291ceSJung-uk Kim s->tls_session_ticket_ext_cb_arg)) 23861f13597dSJung-uk Kim { 23871f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 23881f13597dSJung-uk Kim return 0; 23891f13597dSJung-uk Kim } 23906f9291ceSJung-uk Kim } else if (type == TLSEXT_TYPE_renegotiate) { 23916a599222SSimon L. B. Nielsen if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) 23926a599222SSimon L. B. Nielsen return 0; 23936a599222SSimon L. B. Nielsen renegotiate_seen = 1; 23946f9291ceSJung-uk Kim } else if (type == TLSEXT_TYPE_signature_algorithms) { 23951f13597dSJung-uk Kim int dsize; 23967bded2dbSJung-uk Kim if (s->cert->peer_sigalgs || size < 2) 2397ed6b93beSJung-uk Kim goto err; 23981f13597dSJung-uk Kim n2s(data, dsize); 23991f13597dSJung-uk Kim size -= 2; 24007bded2dbSJung-uk Kim if (dsize != size || dsize & 1 || !dsize) 2401ed6b93beSJung-uk Kim goto err; 24027bded2dbSJung-uk Kim if (!tls1_save_sigalgs(s, data, dsize)) 2403ed6b93beSJung-uk Kim goto err; 24047bded2dbSJung-uk Kim } else if (type == TLSEXT_TYPE_status_request) { 2405db522d3aSSimon L. B. Nielsen 2406ed6b93beSJung-uk Kim if (size < 5) 2407ed6b93beSJung-uk Kim goto err; 2408db522d3aSSimon L. B. Nielsen 2409db522d3aSSimon L. B. Nielsen s->tlsext_status_type = *data++; 2410db522d3aSSimon L. B. Nielsen size--; 24116f9291ceSJung-uk Kim if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { 2412db522d3aSSimon L. B. Nielsen const unsigned char *sdata; 2413db522d3aSSimon L. B. Nielsen int dsize; 2414db522d3aSSimon L. B. Nielsen /* Read in responder_id_list */ 2415db522d3aSSimon L. B. Nielsen n2s(data, dsize); 2416db522d3aSSimon L. B. Nielsen size -= 2; 2417ed6b93beSJung-uk Kim if (dsize > size) 2418ed6b93beSJung-uk Kim goto err; 2419aeb5019cSJung-uk Kim 2420aeb5019cSJung-uk Kim /* 2421aeb5019cSJung-uk Kim * We remove any OCSP_RESPIDs from a previous handshake 2422aeb5019cSJung-uk Kim * to prevent unbounded memory growth - CVE-2016-6304 2423aeb5019cSJung-uk Kim */ 2424aeb5019cSJung-uk Kim sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, 2425aeb5019cSJung-uk Kim OCSP_RESPID_free); 2426aeb5019cSJung-uk Kim if (dsize > 0) { 2427aeb5019cSJung-uk Kim s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); 2428aeb5019cSJung-uk Kim if (s->tlsext_ocsp_ids == NULL) { 2429aeb5019cSJung-uk Kim *al = SSL_AD_INTERNAL_ERROR; 2430aeb5019cSJung-uk Kim return 0; 2431aeb5019cSJung-uk Kim } 2432aeb5019cSJung-uk Kim } else { 2433aeb5019cSJung-uk Kim s->tlsext_ocsp_ids = NULL; 2434aeb5019cSJung-uk Kim } 2435aeb5019cSJung-uk Kim 24366f9291ceSJung-uk Kim while (dsize > 0) { 2437db522d3aSSimon L. B. Nielsen OCSP_RESPID *id; 2438db522d3aSSimon L. B. Nielsen int idsize; 2439ed6b93beSJung-uk Kim if (dsize < 4) 2440ed6b93beSJung-uk Kim goto err; 2441db522d3aSSimon L. B. Nielsen n2s(data, idsize); 2442db522d3aSSimon L. B. Nielsen dsize -= 2 + idsize; 24430a704568SSimon L. B. Nielsen size -= 2 + idsize; 2444ed6b93beSJung-uk Kim if (dsize < 0) 2445ed6b93beSJung-uk Kim goto err; 2446db522d3aSSimon L. B. Nielsen sdata = data; 2447db522d3aSSimon L. B. Nielsen data += idsize; 24486f9291ceSJung-uk Kim id = d2i_OCSP_RESPID(NULL, &sdata, idsize); 2449ed6b93beSJung-uk Kim if (!id) 2450ed6b93beSJung-uk Kim goto err; 24516f9291ceSJung-uk Kim if (data != sdata) { 2452db522d3aSSimon L. B. Nielsen OCSP_RESPID_free(id); 2453ed6b93beSJung-uk Kim goto err; 2454db522d3aSSimon L. B. Nielsen } 24556f9291ceSJung-uk Kim if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { 2456db522d3aSSimon L. B. Nielsen OCSP_RESPID_free(id); 2457db522d3aSSimon L. B. Nielsen *al = SSL_AD_INTERNAL_ERROR; 2458db522d3aSSimon L. B. Nielsen return 0; 2459db522d3aSSimon L. B. Nielsen } 2460db522d3aSSimon L. B. Nielsen } 2461db522d3aSSimon L. B. Nielsen 2462db522d3aSSimon L. B. Nielsen /* Read in request_extensions */ 2463ed6b93beSJung-uk Kim if (size < 2) 2464ed6b93beSJung-uk Kim goto err; 2465db522d3aSSimon L. B. Nielsen n2s(data, dsize); 2466db522d3aSSimon L. B. Nielsen size -= 2; 2467ed6b93beSJung-uk Kim if (dsize != size) 2468ed6b93beSJung-uk Kim goto err; 2469db522d3aSSimon L. B. Nielsen sdata = data; 24706f9291ceSJung-uk Kim if (dsize > 0) { 24716f9291ceSJung-uk Kim if (s->tlsext_ocsp_exts) { 247212de4ed2SJung-uk Kim sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, 247312de4ed2SJung-uk Kim X509_EXTENSION_free); 247412de4ed2SJung-uk Kim } 247512de4ed2SJung-uk Kim 2476db522d3aSSimon L. B. Nielsen s->tlsext_ocsp_exts = 24776f9291ceSJung-uk Kim d2i_X509_EXTENSIONS(NULL, &sdata, dsize); 2478ed6b93beSJung-uk Kim if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) 2479ed6b93beSJung-uk Kim goto err; 2480db522d3aSSimon L. B. Nielsen } 2481db522d3aSSimon L. B. Nielsen } 24826f9291ceSJung-uk Kim /* 24836f9291ceSJung-uk Kim * We don't know what to do with any other type * so ignore it. 2484db522d3aSSimon L. B. Nielsen */ 2485db522d3aSSimon L. B. Nielsen else 2486db522d3aSSimon L. B. Nielsen s->tlsext_status_type = -1; 2487db522d3aSSimon L. B. Nielsen } 24881f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS 24896f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_heartbeat) { 24906f9291ceSJung-uk Kim switch (data[0]) { 24911f13597dSJung-uk Kim case 0x01: /* Client allows us to send HB requests */ 24921f13597dSJung-uk Kim s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; 24931f13597dSJung-uk Kim break; 24941f13597dSJung-uk Kim case 0x02: /* Client doesn't accept HB requests */ 24951f13597dSJung-uk Kim s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; 24961f13597dSJung-uk Kim s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; 24971f13597dSJung-uk Kim break; 24986f9291ceSJung-uk Kim default: 24996f9291ceSJung-uk Kim *al = SSL_AD_ILLEGAL_PARAMETER; 25001f13597dSJung-uk Kim return 0; 25011f13597dSJung-uk Kim } 25021f13597dSJung-uk Kim } 25031f13597dSJung-uk Kim # endif 25041f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 25051f13597dSJung-uk Kim else if (type == TLSEXT_TYPE_next_proto_neg && 2506b8721c16SJung-uk Kim s->s3->tmp.finish_md_len == 0) { 25076f9291ceSJung-uk Kim /*- 25086f9291ceSJung-uk Kim * We shouldn't accept this extension on a 25091f13597dSJung-uk Kim * renegotiation. 25101f13597dSJung-uk Kim * 25111f13597dSJung-uk Kim * s->new_session will be set on renegotiation, but we 25121f13597dSJung-uk Kim * probably shouldn't rely that it couldn't be set on 25131f13597dSJung-uk Kim * the initial renegotation too in certain cases (when 25141f13597dSJung-uk Kim * there's some other reason to disallow resuming an 25151f13597dSJung-uk Kim * earlier session -- the current code won't be doing 25161f13597dSJung-uk Kim * anything like that, but this might change). 25176f9291ceSJung-uk Kim * 25181f13597dSJung-uk Kim * A valid sign that there's been a previous handshake 25191f13597dSJung-uk Kim * in this connection is if s->s3->tmp.finish_md_len > 25201f13597dSJung-uk Kim * 0. (We are talking about a check that will happen 25211f13597dSJung-uk Kim * in the Hello protocol round, well before a new 25226f9291ceSJung-uk Kim * Finished message could have been computed.) 25236f9291ceSJung-uk Kim */ 25241f13597dSJung-uk Kim s->s3->next_proto_neg_seen = 1; 25251f13597dSJung-uk Kim } 25261f13597dSJung-uk Kim # endif 25276a599222SSimon L. B. Nielsen 25287bded2dbSJung-uk Kim else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation && 2529b8721c16SJung-uk Kim s->s3->tmp.finish_md_len == 0) { 25307bded2dbSJung-uk Kim if (tls1_alpn_handle_client_hello(s, data, size, al) != 0) 25317bded2dbSJung-uk Kim return 0; 25327bded2dbSJung-uk Kim } 25337bded2dbSJung-uk Kim 2534db522d3aSSimon L. B. Nielsen /* session ticket processed earlier */ 253509286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP 2536fa5fddf1SJung-uk Kim else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) 25376f9291ceSJung-uk Kim && type == TLSEXT_TYPE_use_srtp) { 25386f9291ceSJung-uk Kim if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) 25391f13597dSJung-uk Kim return 0; 25401f13597dSJung-uk Kim } 254109286989SJung-uk Kim # endif 2542db522d3aSSimon L. B. Nielsen 2543db522d3aSSimon L. B. Nielsen data += size; 2544db522d3aSSimon L. B. Nielsen } 25451f13597dSJung-uk Kim 2546ed6b93beSJung-uk Kim /* Spurious data on the end */ 254780815a77SJung-uk Kim if (data != limit) 2548ed6b93beSJung-uk Kim goto err; 2549ed6b93beSJung-uk Kim 2550db522d3aSSimon L. B. Nielsen *p = data; 25516a599222SSimon L. B. Nielsen 25526a599222SSimon L. B. Nielsen ri_check: 25536a599222SSimon L. B. Nielsen 25546a599222SSimon L. B. Nielsen /* Need RI if renegotiating */ 25556a599222SSimon L. B. Nielsen 25561f13597dSJung-uk Kim if (!renegotiate_seen && s->renegotiate && 25576f9291ceSJung-uk Kim !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { 25586a599222SSimon L. B. Nielsen *al = SSL_AD_HANDSHAKE_FAILURE; 25597bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 25606a599222SSimon L. B. Nielsen SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); 25616a599222SSimon L. B. Nielsen return 0; 25626a599222SSimon L. B. Nielsen } 25636a599222SSimon L. B. Nielsen 2564db522d3aSSimon L. B. Nielsen return 1; 2565ed6b93beSJung-uk Kim err: 2566ed6b93beSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 2567ed6b93beSJung-uk Kim return 0; 2568db522d3aSSimon L. B. Nielsen } 2569db522d3aSSimon L. B. Nielsen 25707bded2dbSJung-uk Kim /* 25717bded2dbSJung-uk Kim * Parse any custom extensions found. "data" is the start of the extension data 25727bded2dbSJung-uk Kim * and "limit" is the end of the record. TODO: add strict syntax checking. 25737bded2dbSJung-uk Kim */ 25747bded2dbSJung-uk Kim 25757bded2dbSJung-uk Kim static int ssl_scan_clienthello_custom_tlsext(SSL *s, 25767bded2dbSJung-uk Kim const unsigned char *data, 25777bded2dbSJung-uk Kim const unsigned char *limit, 25787bded2dbSJung-uk Kim int *al) 25797bded2dbSJung-uk Kim { 25807bded2dbSJung-uk Kim unsigned short type, size, len; 25817bded2dbSJung-uk Kim /* If resumed session or no custom extensions nothing to do */ 25827bded2dbSJung-uk Kim if (s->hit || s->cert->srv_ext.meths_count == 0) 25837bded2dbSJung-uk Kim return 1; 25847bded2dbSJung-uk Kim 2585aeb5019cSJung-uk Kim if (limit - data <= 2) 25867bded2dbSJung-uk Kim return 1; 25877bded2dbSJung-uk Kim n2s(data, len); 25887bded2dbSJung-uk Kim 2589aeb5019cSJung-uk Kim if (limit - data < len) 25907bded2dbSJung-uk Kim return 1; 25917bded2dbSJung-uk Kim 2592aeb5019cSJung-uk Kim while (limit - data >= 4) { 25937bded2dbSJung-uk Kim n2s(data, type); 25947bded2dbSJung-uk Kim n2s(data, size); 25957bded2dbSJung-uk Kim 2596aeb5019cSJung-uk Kim if (limit - data < size) 25977bded2dbSJung-uk Kim return 1; 25987bded2dbSJung-uk Kim if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0) 25997bded2dbSJung-uk Kim return 0; 26007bded2dbSJung-uk Kim 26017bded2dbSJung-uk Kim data += size; 26027bded2dbSJung-uk Kim } 26037bded2dbSJung-uk Kim 26047bded2dbSJung-uk Kim return 1; 26057bded2dbSJung-uk Kim } 26067bded2dbSJung-uk Kim 260780815a77SJung-uk Kim int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, 260880815a77SJung-uk Kim unsigned char *limit) 26097bded2dbSJung-uk Kim { 26107bded2dbSJung-uk Kim int al = -1; 26117bded2dbSJung-uk Kim unsigned char *ptmp = *p; 26127bded2dbSJung-uk Kim /* 26137bded2dbSJung-uk Kim * Internally supported extensions are parsed first so SNI can be handled 26147bded2dbSJung-uk Kim * before custom extensions. An application processing SNI will typically 26157bded2dbSJung-uk Kim * switch the parent context using SSL_set_SSL_CTX and custom extensions 26167bded2dbSJung-uk Kim * need to be handled by the new SSL_CTX structure. 26177bded2dbSJung-uk Kim */ 261880815a77SJung-uk Kim if (ssl_scan_clienthello_tlsext(s, p, limit, &al) <= 0) { 26197bded2dbSJung-uk Kim ssl3_send_alert(s, SSL3_AL_FATAL, al); 26207bded2dbSJung-uk Kim return 0; 26217bded2dbSJung-uk Kim } 26227bded2dbSJung-uk Kim 26237bded2dbSJung-uk Kim if (ssl_check_clienthello_tlsext_early(s) <= 0) { 26247bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT); 26257bded2dbSJung-uk Kim return 0; 26267bded2dbSJung-uk Kim } 26277bded2dbSJung-uk Kim 26287bded2dbSJung-uk Kim custom_ext_init(&s->cert->srv_ext); 262980815a77SJung-uk Kim if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) { 26307bded2dbSJung-uk Kim ssl3_send_alert(s, SSL3_AL_FATAL, al); 26317bded2dbSJung-uk Kim return 0; 26327bded2dbSJung-uk Kim } 26337bded2dbSJung-uk Kim 26347bded2dbSJung-uk Kim return 1; 26357bded2dbSJung-uk Kim } 26367bded2dbSJung-uk Kim 26371f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 26386f9291ceSJung-uk Kim /* 26396f9291ceSJung-uk Kim * ssl_next_proto_validate validates a Next Protocol Negotiation block. No 26406f9291ceSJung-uk Kim * elements of zero length are allowed and the set of elements must exactly 26416f9291ceSJung-uk Kim * fill the length of the block. 26426f9291ceSJung-uk Kim */ 26431f13597dSJung-uk Kim static char ssl_next_proto_validate(unsigned char *d, unsigned len) 26441f13597dSJung-uk Kim { 26451f13597dSJung-uk Kim unsigned int off = 0; 26461f13597dSJung-uk Kim 26476f9291ceSJung-uk Kim while (off < len) { 26481f13597dSJung-uk Kim if (d[off] == 0) 26491f13597dSJung-uk Kim return 0; 26501f13597dSJung-uk Kim off += d[off]; 26511f13597dSJung-uk Kim off++; 26521f13597dSJung-uk Kim } 26531f13597dSJung-uk Kim 26541f13597dSJung-uk Kim return off == len; 26551f13597dSJung-uk Kim } 26561f13597dSJung-uk Kim # endif 26571f13597dSJung-uk Kim 26587bded2dbSJung-uk Kim static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, 26597bded2dbSJung-uk Kim unsigned char *d, int n, int *al) 2660db522d3aSSimon L. B. Nielsen { 2661a3ddd25aSSimon L. B. Nielsen unsigned short length; 2662db522d3aSSimon L. B. Nielsen unsigned short type; 2663db522d3aSSimon L. B. Nielsen unsigned short size; 2664db522d3aSSimon L. B. Nielsen unsigned char *data = *p; 2665db522d3aSSimon L. B. Nielsen int tlsext_servername = 0; 26666a599222SSimon L. B. Nielsen int renegotiate_seen = 0; 2667db522d3aSSimon L. B. Nielsen 26681f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 26691f13597dSJung-uk Kim s->s3->next_proto_neg_seen = 0; 26701f13597dSJung-uk Kim # endif 2671751d2991SJung-uk Kim s->tlsext_ticket_expected = 0; 26721f13597dSJung-uk Kim 26737bded2dbSJung-uk Kim if (s->s3->alpn_selected) { 26747bded2dbSJung-uk Kim OPENSSL_free(s->s3->alpn_selected); 26757bded2dbSJung-uk Kim s->s3->alpn_selected = NULL; 26767bded2dbSJung-uk Kim } 26771f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS 26781f13597dSJung-uk Kim s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | 26791f13597dSJung-uk Kim SSL_TLSEXT_HB_DONT_SEND_REQUESTS); 26801f13597dSJung-uk Kim # endif 26811f13597dSJung-uk Kim 2682aeb5019cSJung-uk Kim if ((d + n) - data <= 2) 26836a599222SSimon L. B. Nielsen goto ri_check; 2684db522d3aSSimon L. B. Nielsen 2685a3ddd25aSSimon L. B. Nielsen n2s(data, length); 2686aeb5019cSJung-uk Kim if ((d + n) - data != length) { 2687a3ddd25aSSimon L. B. Nielsen *al = SSL_AD_DECODE_ERROR; 2688a3ddd25aSSimon L. B. Nielsen return 0; 2689a3ddd25aSSimon L. B. Nielsen } 2690db522d3aSSimon L. B. Nielsen 2691aeb5019cSJung-uk Kim while ((d + n) - data >= 4) { 2692db522d3aSSimon L. B. Nielsen n2s(data, type); 2693db522d3aSSimon L. B. Nielsen n2s(data, size); 2694db522d3aSSimon L. B. Nielsen 2695aeb5019cSJung-uk Kim if ((d + n) - data < size) 26966a599222SSimon L. B. Nielsen goto ri_check; 2697db522d3aSSimon L. B. Nielsen 2698db522d3aSSimon L. B. Nielsen if (s->tlsext_debug_cb) 26996f9291ceSJung-uk Kim s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg); 2700db522d3aSSimon L. B. Nielsen 27016f9291ceSJung-uk Kim if (type == TLSEXT_TYPE_server_name) { 27026f9291ceSJung-uk Kim if (s->tlsext_hostname == NULL || size > 0) { 2703db522d3aSSimon L. B. Nielsen *al = TLS1_AD_UNRECOGNIZED_NAME; 2704db522d3aSSimon L. B. Nielsen return 0; 2705db522d3aSSimon L. B. Nielsen } 2706db522d3aSSimon L. B. Nielsen tlsext_servername = 1; 2707db522d3aSSimon L. B. Nielsen } 27081f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 27096f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_ec_point_formats) { 27101f13597dSJung-uk Kim unsigned char *sdata = data; 27111f13597dSJung-uk Kim int ecpointformatlist_length = *(sdata++); 27121f13597dSJung-uk Kim 27137bded2dbSJung-uk Kim if (ecpointformatlist_length != size - 1) { 27141f13597dSJung-uk Kim *al = TLS1_AD_DECODE_ERROR; 27151f13597dSJung-uk Kim return 0; 27161f13597dSJung-uk Kim } 27176f9291ceSJung-uk Kim if (!s->hit) { 27181f13597dSJung-uk Kim s->session->tlsext_ecpointformatlist_length = 0; 27196f9291ceSJung-uk Kim if (s->session->tlsext_ecpointformatlist != NULL) 27206f9291ceSJung-uk Kim OPENSSL_free(s->session->tlsext_ecpointformatlist); 27216f9291ceSJung-uk Kim if ((s->session->tlsext_ecpointformatlist = 27226f9291ceSJung-uk Kim OPENSSL_malloc(ecpointformatlist_length)) == NULL) { 27231f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 27241f13597dSJung-uk Kim return 0; 27251f13597dSJung-uk Kim } 27266f9291ceSJung-uk Kim s->session->tlsext_ecpointformatlist_length = 27276f9291ceSJung-uk Kim ecpointformatlist_length; 27286f9291ceSJung-uk Kim memcpy(s->session->tlsext_ecpointformatlist, sdata, 27296f9291ceSJung-uk Kim ecpointformatlist_length); 2730a93cbc2bSJung-uk Kim } 27311f13597dSJung-uk Kim # if 0 27326f9291ceSJung-uk Kim fprintf(stderr, 27336f9291ceSJung-uk Kim "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); 27341f13597dSJung-uk Kim sdata = s->session->tlsext_ecpointformatlist; 27351f13597dSJung-uk Kim for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) 27361f13597dSJung-uk Kim fprintf(stderr, "%i ", *(sdata++)); 27371f13597dSJung-uk Kim fprintf(stderr, "\n"); 27381f13597dSJung-uk Kim # endif 27391f13597dSJung-uk Kim } 27401f13597dSJung-uk Kim # endif /* OPENSSL_NO_EC */ 27411f13597dSJung-uk Kim 27426f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_session_ticket) { 27431f13597dSJung-uk Kim if (s->tls_session_ticket_ext_cb && 27446f9291ceSJung-uk Kim !s->tls_session_ticket_ext_cb(s, data, size, 27456f9291ceSJung-uk Kim s->tls_session_ticket_ext_cb_arg)) 27461f13597dSJung-uk Kim { 27471f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 27481f13597dSJung-uk Kim return 0; 27491f13597dSJung-uk Kim } 2750db522d3aSSimon L. B. Nielsen if ((SSL_get_options(s) & SSL_OP_NO_TICKET) 27516f9291ceSJung-uk Kim || (size > 0)) { 2752db522d3aSSimon L. B. Nielsen *al = TLS1_AD_UNSUPPORTED_EXTENSION; 2753db522d3aSSimon L. B. Nielsen return 0; 2754db522d3aSSimon L. B. Nielsen } 2755db522d3aSSimon L. B. Nielsen s->tlsext_ticket_expected = 1; 2756db522d3aSSimon L. B. Nielsen } 27571f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input 27587bded2dbSJung-uk Kim else if (type == TLSEXT_TYPE_opaque_prf_input) { 27591f13597dSJung-uk Kim unsigned char *sdata = data; 27601f13597dSJung-uk Kim 27616f9291ceSJung-uk Kim if (size < 2) { 27621f13597dSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 27631f13597dSJung-uk Kim return 0; 27641f13597dSJung-uk Kim } 27651f13597dSJung-uk Kim n2s(sdata, s->s3->server_opaque_prf_input_len); 27666f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input_len != size - 2) { 27671f13597dSJung-uk Kim *al = SSL_AD_DECODE_ERROR; 27681f13597dSJung-uk Kim return 0; 27691f13597dSJung-uk Kim } 27701f13597dSJung-uk Kim 27716f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input != NULL) { 27726f9291ceSJung-uk Kim /* shouldn't really happen */ 27731f13597dSJung-uk Kim OPENSSL_free(s->s3->server_opaque_prf_input); 27746f9291ceSJung-uk Kim } 27756f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input_len == 0) { 27766f9291ceSJung-uk Kim /* dummy byte just to get non-NULL */ 27776f9291ceSJung-uk Kim s->s3->server_opaque_prf_input = OPENSSL_malloc(1); 27786f9291ceSJung-uk Kim } else { 27796f9291ceSJung-uk Kim s->s3->server_opaque_prf_input = 27806f9291ceSJung-uk Kim BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); 27816f9291ceSJung-uk Kim } 27821f13597dSJung-uk Kim 27836f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input == NULL) { 27841f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 27851f13597dSJung-uk Kim return 0; 27861f13597dSJung-uk Kim } 27871f13597dSJung-uk Kim } 27881f13597dSJung-uk Kim # endif 27897bded2dbSJung-uk Kim else if (type == TLSEXT_TYPE_status_request) { 27906f9291ceSJung-uk Kim /* 27916f9291ceSJung-uk Kim * MUST be empty and only sent if we've requested a status 27926f9291ceSJung-uk Kim * request message. 2793db522d3aSSimon L. B. Nielsen */ 27946f9291ceSJung-uk Kim if ((s->tlsext_status_type == -1) || (size > 0)) { 2795db522d3aSSimon L. B. Nielsen *al = TLS1_AD_UNSUPPORTED_EXTENSION; 2796db522d3aSSimon L. B. Nielsen return 0; 2797db522d3aSSimon L. B. Nielsen } 2798db522d3aSSimon L. B. Nielsen /* Set flag to expect CertificateStatus message */ 2799db522d3aSSimon L. B. Nielsen s->tlsext_status_expected = 1; 2800db522d3aSSimon L. B. Nielsen } 28011f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 28021f13597dSJung-uk Kim else if (type == TLSEXT_TYPE_next_proto_neg && 28036f9291ceSJung-uk Kim s->s3->tmp.finish_md_len == 0) { 28041f13597dSJung-uk Kim unsigned char *selected; 28051f13597dSJung-uk Kim unsigned char selected_len; 28061f13597dSJung-uk Kim 28071f13597dSJung-uk Kim /* We must have requested it. */ 28086f9291ceSJung-uk Kim if (s->ctx->next_proto_select_cb == NULL) { 28091f13597dSJung-uk Kim *al = TLS1_AD_UNSUPPORTED_EXTENSION; 28101f13597dSJung-uk Kim return 0; 28111f13597dSJung-uk Kim } 28121f13597dSJung-uk Kim /* The data must be valid */ 28136f9291ceSJung-uk Kim if (!ssl_next_proto_validate(data, size)) { 28141f13597dSJung-uk Kim *al = TLS1_AD_DECODE_ERROR; 28151f13597dSJung-uk Kim return 0; 28161f13597dSJung-uk Kim } 28176f9291ceSJung-uk Kim if (s-> 28186f9291ceSJung-uk Kim ctx->next_proto_select_cb(s, &selected, &selected_len, data, 28196f9291ceSJung-uk Kim size, 28206f9291ceSJung-uk Kim s->ctx->next_proto_select_cb_arg) != 28216f9291ceSJung-uk Kim SSL_TLSEXT_ERR_OK) { 28221f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 28231f13597dSJung-uk Kim return 0; 28241f13597dSJung-uk Kim } 2825aeb5019cSJung-uk Kim /* 2826aeb5019cSJung-uk Kim * Could be non-NULL if server has sent multiple NPN extensions in 2827aeb5019cSJung-uk Kim * a single Serverhello 2828aeb5019cSJung-uk Kim */ 2829aeb5019cSJung-uk Kim OPENSSL_free(s->next_proto_negotiated); 28301f13597dSJung-uk Kim s->next_proto_negotiated = OPENSSL_malloc(selected_len); 28316f9291ceSJung-uk Kim if (!s->next_proto_negotiated) { 28321f13597dSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 28331f13597dSJung-uk Kim return 0; 28341f13597dSJung-uk Kim } 28351f13597dSJung-uk Kim memcpy(s->next_proto_negotiated, selected, selected_len); 28361f13597dSJung-uk Kim s->next_proto_negotiated_len = selected_len; 28371f13597dSJung-uk Kim s->s3->next_proto_neg_seen = 1; 28381f13597dSJung-uk Kim } 28391f13597dSJung-uk Kim # endif 28407bded2dbSJung-uk Kim 28417bded2dbSJung-uk Kim else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { 28427bded2dbSJung-uk Kim unsigned len; 28437bded2dbSJung-uk Kim 28447bded2dbSJung-uk Kim /* We must have requested it. */ 2845b8721c16SJung-uk Kim if (!s->cert->alpn_sent) { 28467bded2dbSJung-uk Kim *al = TLS1_AD_UNSUPPORTED_EXTENSION; 28477bded2dbSJung-uk Kim return 0; 28487bded2dbSJung-uk Kim } 28497bded2dbSJung-uk Kim if (size < 4) { 28507bded2dbSJung-uk Kim *al = TLS1_AD_DECODE_ERROR; 28517bded2dbSJung-uk Kim return 0; 28527bded2dbSJung-uk Kim } 28537bded2dbSJung-uk Kim /*- 28547bded2dbSJung-uk Kim * The extension data consists of: 28557bded2dbSJung-uk Kim * uint16 list_length 28567bded2dbSJung-uk Kim * uint8 proto_length; 28577bded2dbSJung-uk Kim * uint8 proto[proto_length]; 28587bded2dbSJung-uk Kim */ 28597bded2dbSJung-uk Kim len = data[0]; 28607bded2dbSJung-uk Kim len <<= 8; 28617bded2dbSJung-uk Kim len |= data[1]; 28627bded2dbSJung-uk Kim if (len != (unsigned)size - 2) { 28637bded2dbSJung-uk Kim *al = TLS1_AD_DECODE_ERROR; 28647bded2dbSJung-uk Kim return 0; 28657bded2dbSJung-uk Kim } 28667bded2dbSJung-uk Kim len = data[2]; 28677bded2dbSJung-uk Kim if (len != (unsigned)size - 3) { 28687bded2dbSJung-uk Kim *al = TLS1_AD_DECODE_ERROR; 28697bded2dbSJung-uk Kim return 0; 28707bded2dbSJung-uk Kim } 28717bded2dbSJung-uk Kim if (s->s3->alpn_selected) 28727bded2dbSJung-uk Kim OPENSSL_free(s->s3->alpn_selected); 28737bded2dbSJung-uk Kim s->s3->alpn_selected = OPENSSL_malloc(len); 28747bded2dbSJung-uk Kim if (!s->s3->alpn_selected) { 28757bded2dbSJung-uk Kim *al = TLS1_AD_INTERNAL_ERROR; 28767bded2dbSJung-uk Kim return 0; 28777bded2dbSJung-uk Kim } 28787bded2dbSJung-uk Kim memcpy(s->s3->alpn_selected, data + 3, len); 28797bded2dbSJung-uk Kim s->s3->alpn_selected_len = len; 28807bded2dbSJung-uk Kim } 28817bded2dbSJung-uk Kim 28826f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_renegotiate) { 28836a599222SSimon L. B. Nielsen if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) 28846a599222SSimon L. B. Nielsen return 0; 28856a599222SSimon L. B. Nielsen renegotiate_seen = 1; 28866a599222SSimon L. B. Nielsen } 28871f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS 28886f9291ceSJung-uk Kim else if (type == TLSEXT_TYPE_heartbeat) { 28896f9291ceSJung-uk Kim switch (data[0]) { 28901f13597dSJung-uk Kim case 0x01: /* Server allows us to send HB requests */ 28911f13597dSJung-uk Kim s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; 28921f13597dSJung-uk Kim break; 28931f13597dSJung-uk Kim case 0x02: /* Server doesn't accept HB requests */ 28941f13597dSJung-uk Kim s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; 28951f13597dSJung-uk Kim s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; 28961f13597dSJung-uk Kim break; 28976f9291ceSJung-uk Kim default: 28986f9291ceSJung-uk Kim *al = SSL_AD_ILLEGAL_PARAMETER; 28991f13597dSJung-uk Kim return 0; 29001f13597dSJung-uk Kim } 29011f13597dSJung-uk Kim } 29021f13597dSJung-uk Kim # endif 290309286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP 29046f9291ceSJung-uk Kim else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { 29056f9291ceSJung-uk Kim if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) 29061f13597dSJung-uk Kim return 0; 29071f13597dSJung-uk Kim } 290809286989SJung-uk Kim # endif 29097bded2dbSJung-uk Kim /* 29107bded2dbSJung-uk Kim * If this extension type was not otherwise handled, but matches a 29117bded2dbSJung-uk Kim * custom_cli_ext_record, then send it to the c callback 29127bded2dbSJung-uk Kim */ 29137bded2dbSJung-uk Kim else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) 29147bded2dbSJung-uk Kim return 0; 29151f13597dSJung-uk Kim 2916db522d3aSSimon L. B. Nielsen data += size; 2917db522d3aSSimon L. B. Nielsen } 2918db522d3aSSimon L. B. Nielsen 29196f9291ceSJung-uk Kim if (data != d + n) { 2920db522d3aSSimon L. B. Nielsen *al = SSL_AD_DECODE_ERROR; 2921db522d3aSSimon L. B. Nielsen return 0; 2922db522d3aSSimon L. B. Nielsen } 2923db522d3aSSimon L. B. Nielsen 29246f9291ceSJung-uk Kim if (!s->hit && tlsext_servername == 1) { 29256f9291ceSJung-uk Kim if (s->tlsext_hostname) { 29266f9291ceSJung-uk Kim if (s->session->tlsext_hostname == NULL) { 2927db522d3aSSimon L. B. Nielsen s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); 29286f9291ceSJung-uk Kim if (!s->session->tlsext_hostname) { 2929db522d3aSSimon L. B. Nielsen *al = SSL_AD_UNRECOGNIZED_NAME; 2930db522d3aSSimon L. B. Nielsen return 0; 2931db522d3aSSimon L. B. Nielsen } 29326f9291ceSJung-uk Kim } else { 2933db522d3aSSimon L. B. Nielsen *al = SSL_AD_DECODE_ERROR; 2934db522d3aSSimon L. B. Nielsen return 0; 2935db522d3aSSimon L. B. Nielsen } 2936db522d3aSSimon L. B. Nielsen } 2937db522d3aSSimon L. B. Nielsen } 2938db522d3aSSimon L. B. Nielsen 2939db522d3aSSimon L. B. Nielsen *p = data; 29406a599222SSimon L. B. Nielsen 29416a599222SSimon L. B. Nielsen ri_check: 29426a599222SSimon L. B. Nielsen 29436f9291ceSJung-uk Kim /* 29446f9291ceSJung-uk Kim * Determine if we need to see RI. Strictly speaking if we want to avoid 29456f9291ceSJung-uk Kim * an attack we should *always* see RI even on initial server hello 29466f9291ceSJung-uk Kim * because the client doesn't see any renegotiation during an attack. 29476f9291ceSJung-uk Kim * However this would mean we could not connect to any server which 29486f9291ceSJung-uk Kim * doesn't support RI so for the immediate future tolerate RI absence on 29496f9291ceSJung-uk Kim * initial connect only. 29506a599222SSimon L. B. Nielsen */ 29516f9291ceSJung-uk Kim if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) 29526f9291ceSJung-uk Kim && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { 29536a599222SSimon L. B. Nielsen *al = SSL_AD_HANDSHAKE_FAILURE; 29547bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 29556a599222SSimon L. B. Nielsen SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); 29566a599222SSimon L. B. Nielsen return 0; 29576a599222SSimon L. B. Nielsen } 29586a599222SSimon L. B. Nielsen 2959db522d3aSSimon L. B. Nielsen return 1; 2960db522d3aSSimon L. B. Nielsen } 2961db522d3aSSimon L. B. Nielsen 29621f13597dSJung-uk Kim int ssl_prepare_clienthello_tlsext(SSL *s) 29631f13597dSJung-uk Kim { 29641f13597dSJung-uk Kim 29651f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input 29661f13597dSJung-uk Kim { 29671f13597dSJung-uk Kim int r = 1; 29681f13597dSJung-uk Kim 29696f9291ceSJung-uk Kim if (s->ctx->tlsext_opaque_prf_input_callback != 0) { 29706f9291ceSJung-uk Kim r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, 29716f9291ceSJung-uk Kim s-> 29726f9291ceSJung-uk Kim ctx->tlsext_opaque_prf_input_callback_arg); 29731f13597dSJung-uk Kim if (!r) 29741f13597dSJung-uk Kim return -1; 29751f13597dSJung-uk Kim } 29761f13597dSJung-uk Kim 29776f9291ceSJung-uk Kim if (s->tlsext_opaque_prf_input != NULL) { 29786f9291ceSJung-uk Kim if (s->s3->client_opaque_prf_input != NULL) { 29796f9291ceSJung-uk Kim /* shouldn't really happen */ 29801f13597dSJung-uk Kim OPENSSL_free(s->s3->client_opaque_prf_input); 29816f9291ceSJung-uk Kim } 29821f13597dSJung-uk Kim 29836f9291ceSJung-uk Kim if (s->tlsext_opaque_prf_input_len == 0) { 29846f9291ceSJung-uk Kim /* dummy byte just to get non-NULL */ 29856f9291ceSJung-uk Kim s->s3->client_opaque_prf_input = OPENSSL_malloc(1); 29866f9291ceSJung-uk Kim } else { 29876f9291ceSJung-uk Kim s->s3->client_opaque_prf_input = 29886f9291ceSJung-uk Kim BUF_memdup(s->tlsext_opaque_prf_input, 29896f9291ceSJung-uk Kim s->tlsext_opaque_prf_input_len); 29906f9291ceSJung-uk Kim } 29916f9291ceSJung-uk Kim if (s->s3->client_opaque_prf_input == NULL) { 29926f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, 29936f9291ceSJung-uk Kim ERR_R_MALLOC_FAILURE); 29941f13597dSJung-uk Kim return -1; 29951f13597dSJung-uk Kim } 29966f9291ceSJung-uk Kim s->s3->client_opaque_prf_input_len = 29976f9291ceSJung-uk Kim s->tlsext_opaque_prf_input_len; 29981f13597dSJung-uk Kim } 29991f13597dSJung-uk Kim 30001f13597dSJung-uk Kim if (r == 2) 30016f9291ceSJung-uk Kim /* 30026f9291ceSJung-uk Kim * at callback's request, insist on receiving an appropriate 30036f9291ceSJung-uk Kim * server opaque PRF input 30046f9291ceSJung-uk Kim */ 30056f9291ceSJung-uk Kim s->s3->server_opaque_prf_input_len = 30066f9291ceSJung-uk Kim s->tlsext_opaque_prf_input_len; 30071f13597dSJung-uk Kim } 30081f13597dSJung-uk Kim # endif 30091f13597dSJung-uk Kim 3010b8721c16SJung-uk Kim s->cert->alpn_sent = 0; 30111f13597dSJung-uk Kim return 1; 30121f13597dSJung-uk Kim } 30131f13597dSJung-uk Kim 30141f13597dSJung-uk Kim int ssl_prepare_serverhello_tlsext(SSL *s) 30151f13597dSJung-uk Kim { 30161f13597dSJung-uk Kim return 1; 30171f13597dSJung-uk Kim } 30181f13597dSJung-uk Kim 30197bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s) 3020db522d3aSSimon L. B. Nielsen { 3021db522d3aSSimon L. B. Nielsen int ret = SSL_TLSEXT_ERR_NOACK; 3022db522d3aSSimon L. B. Nielsen int al = SSL_AD_UNRECOGNIZED_NAME; 3023db522d3aSSimon L. B. Nielsen 30241f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 30256f9291ceSJung-uk Kim /* 30266f9291ceSJung-uk Kim * The handling of the ECPointFormats extension is done elsewhere, namely 30276f9291ceSJung-uk Kim * in ssl3_choose_cipher in s3_lib.c. 30281f13597dSJung-uk Kim */ 30296f9291ceSJung-uk Kim /* 30306f9291ceSJung-uk Kim * The handling of the EllipticCurves extension is done elsewhere, namely 30316f9291ceSJung-uk Kim * in ssl3_choose_cipher in s3_lib.c. 30321f13597dSJung-uk Kim */ 30331f13597dSJung-uk Kim # endif 30341f13597dSJung-uk Kim 3035db522d3aSSimon L. B. Nielsen if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 30366f9291ceSJung-uk Kim ret = 30376f9291ceSJung-uk Kim s->ctx->tlsext_servername_callback(s, &al, 30386f9291ceSJung-uk Kim s->ctx->tlsext_servername_arg); 30396f9291ceSJung-uk Kim else if (s->initial_ctx != NULL 30406f9291ceSJung-uk Kim && s->initial_ctx->tlsext_servername_callback != 0) 30416f9291ceSJung-uk Kim ret = 30426f9291ceSJung-uk Kim s->initial_ctx->tlsext_servername_callback(s, &al, 30436f9291ceSJung-uk Kim s-> 30446f9291ceSJung-uk Kim initial_ctx->tlsext_servername_arg); 3045db522d3aSSimon L. B. Nielsen 30461f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input 30471f13597dSJung-uk Kim { 30486f9291ceSJung-uk Kim /* 30496f9291ceSJung-uk Kim * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we 30506f9291ceSJung-uk Kim * might be sending an alert in response to the client hello, so this 30516f9291ceSJung-uk Kim * has to happen here in ssl_check_clienthello_tlsext_early(). 30526f9291ceSJung-uk Kim */ 30531f13597dSJung-uk Kim 30541f13597dSJung-uk Kim int r = 1; 30551f13597dSJung-uk Kim 30566f9291ceSJung-uk Kim if (s->ctx->tlsext_opaque_prf_input_callback != 0) { 30576f9291ceSJung-uk Kim r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, 30586f9291ceSJung-uk Kim s-> 30596f9291ceSJung-uk Kim ctx->tlsext_opaque_prf_input_callback_arg); 30606f9291ceSJung-uk Kim if (!r) { 30611f13597dSJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 30621f13597dSJung-uk Kim al = SSL_AD_INTERNAL_ERROR; 30631f13597dSJung-uk Kim goto err; 30641f13597dSJung-uk Kim } 30651f13597dSJung-uk Kim } 30661f13597dSJung-uk Kim 30676f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input != NULL) { 30686f9291ceSJung-uk Kim /* shouldn't really happen */ 30691f13597dSJung-uk Kim OPENSSL_free(s->s3->server_opaque_prf_input); 30706f9291ceSJung-uk Kim } 30711f13597dSJung-uk Kim s->s3->server_opaque_prf_input = NULL; 30721f13597dSJung-uk Kim 30736f9291ceSJung-uk Kim if (s->tlsext_opaque_prf_input != NULL) { 30741f13597dSJung-uk Kim if (s->s3->client_opaque_prf_input != NULL && 30756f9291ceSJung-uk Kim s->s3->client_opaque_prf_input_len == 30766f9291ceSJung-uk Kim s->tlsext_opaque_prf_input_len) { 30776f9291ceSJung-uk Kim /* 30786f9291ceSJung-uk Kim * can only use this extension if we have a server opaque PRF 30796f9291ceSJung-uk Kim * input of the same length as the client opaque PRF input! 30806f9291ceSJung-uk Kim */ 30811f13597dSJung-uk Kim 30826f9291ceSJung-uk Kim if (s->tlsext_opaque_prf_input_len == 0) { 30836f9291ceSJung-uk Kim /* dummy byte just to get non-NULL */ 30846f9291ceSJung-uk Kim s->s3->server_opaque_prf_input = OPENSSL_malloc(1); 30856f9291ceSJung-uk Kim } else { 30866f9291ceSJung-uk Kim s->s3->server_opaque_prf_input = 30876f9291ceSJung-uk Kim BUF_memdup(s->tlsext_opaque_prf_input, 30886f9291ceSJung-uk Kim s->tlsext_opaque_prf_input_len); 30896f9291ceSJung-uk Kim } 30906f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input == NULL) { 30911f13597dSJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 30921f13597dSJung-uk Kim al = SSL_AD_INTERNAL_ERROR; 30931f13597dSJung-uk Kim goto err; 30941f13597dSJung-uk Kim } 30956f9291ceSJung-uk Kim s->s3->server_opaque_prf_input_len = 30966f9291ceSJung-uk Kim s->tlsext_opaque_prf_input_len; 30971f13597dSJung-uk Kim } 30981f13597dSJung-uk Kim } 30991f13597dSJung-uk Kim 31006f9291ceSJung-uk Kim if (r == 2 && s->s3->server_opaque_prf_input == NULL) { 31016f9291ceSJung-uk Kim /* 31026f9291ceSJung-uk Kim * The callback wants to enforce use of the extension, but we 31036f9291ceSJung-uk Kim * can't do that with the client opaque PRF input; abort the 31046f9291ceSJung-uk Kim * handshake. 31051f13597dSJung-uk Kim */ 31061f13597dSJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 31071f13597dSJung-uk Kim al = SSL_AD_HANDSHAKE_FAILURE; 31081f13597dSJung-uk Kim } 31091f13597dSJung-uk Kim } 31101f13597dSJung-uk Kim 3111db522d3aSSimon L. B. Nielsen err: 311209286989SJung-uk Kim # endif 31136f9291ceSJung-uk Kim switch (ret) { 3114db522d3aSSimon L. B. Nielsen case SSL_TLSEXT_ERR_ALERT_FATAL: 3115db522d3aSSimon L. B. Nielsen ssl3_send_alert(s, SSL3_AL_FATAL, al); 3116db522d3aSSimon L. B. Nielsen return -1; 3117db522d3aSSimon L. B. Nielsen 3118db522d3aSSimon L. B. Nielsen case SSL_TLSEXT_ERR_ALERT_WARNING: 3119db522d3aSSimon L. B. Nielsen ssl3_send_alert(s, SSL3_AL_WARNING, al); 3120db522d3aSSimon L. B. Nielsen return 1; 3121db522d3aSSimon L. B. Nielsen 3122db522d3aSSimon L. B. Nielsen case SSL_TLSEXT_ERR_NOACK: 3123db522d3aSSimon L. B. Nielsen s->servername_done = 0; 3124db522d3aSSimon L. B. Nielsen default: 3125db522d3aSSimon L. B. Nielsen return 1; 3126db522d3aSSimon L. B. Nielsen } 3127db522d3aSSimon L. B. Nielsen } 3128db522d3aSSimon L. B. Nielsen 31297bded2dbSJung-uk Kim int tls1_set_server_sigalgs(SSL *s) 31307bded2dbSJung-uk Kim { 31317bded2dbSJung-uk Kim int al; 31327bded2dbSJung-uk Kim size_t i; 31337bded2dbSJung-uk Kim /* Clear any shared sigtnature algorithms */ 31347bded2dbSJung-uk Kim if (s->cert->shared_sigalgs) { 31357bded2dbSJung-uk Kim OPENSSL_free(s->cert->shared_sigalgs); 31367bded2dbSJung-uk Kim s->cert->shared_sigalgs = NULL; 31377bded2dbSJung-uk Kim s->cert->shared_sigalgslen = 0; 31387bded2dbSJung-uk Kim } 31397bded2dbSJung-uk Kim /* Clear certificate digests and validity flags */ 31407bded2dbSJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) { 31417bded2dbSJung-uk Kim s->cert->pkeys[i].digest = NULL; 31427bded2dbSJung-uk Kim s->cert->pkeys[i].valid_flags = 0; 31437bded2dbSJung-uk Kim } 31447bded2dbSJung-uk Kim 31457bded2dbSJung-uk Kim /* If sigalgs received process it. */ 31467bded2dbSJung-uk Kim if (s->cert->peer_sigalgs) { 31477bded2dbSJung-uk Kim if (!tls1_process_sigalgs(s)) { 31487bded2dbSJung-uk Kim SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE); 31497bded2dbSJung-uk Kim al = SSL_AD_INTERNAL_ERROR; 31507bded2dbSJung-uk Kim goto err; 31517bded2dbSJung-uk Kim } 31527bded2dbSJung-uk Kim /* Fatal error is no shared signature algorithms */ 31537bded2dbSJung-uk Kim if (!s->cert->shared_sigalgs) { 31547bded2dbSJung-uk Kim SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, 31557bded2dbSJung-uk Kim SSL_R_NO_SHARED_SIGATURE_ALGORITHMS); 31567bded2dbSJung-uk Kim al = SSL_AD_ILLEGAL_PARAMETER; 31577bded2dbSJung-uk Kim goto err; 31587bded2dbSJung-uk Kim } 31597bded2dbSJung-uk Kim } else 31607bded2dbSJung-uk Kim ssl_cert_set_default_md(s->cert); 31617bded2dbSJung-uk Kim return 1; 31627bded2dbSJung-uk Kim err: 31637bded2dbSJung-uk Kim ssl3_send_alert(s, SSL3_AL_FATAL, al); 31647bded2dbSJung-uk Kim return 0; 31657bded2dbSJung-uk Kim } 31667bded2dbSJung-uk Kim 3167*6cf8931aSJung-uk Kim /* 3168*6cf8931aSJung-uk Kim * Upon success, returns 1. 3169*6cf8931aSJung-uk Kim * Upon failure, returns 0 and sets |al| to the appropriate fatal alert. 3170*6cf8931aSJung-uk Kim */ 3171*6cf8931aSJung-uk Kim int ssl_check_clienthello_tlsext_late(SSL *s, int *al) 317209286989SJung-uk Kim { 317309286989SJung-uk Kim 31746f9291ceSJung-uk Kim /* 31756f9291ceSJung-uk Kim * If status request then ask callback what to do. Note: this must be 31767bded2dbSJung-uk Kim * called after servername callbacks in case the certificate has changed, 31777bded2dbSJung-uk Kim * and must be called after the cipher has been chosen because this may 31787bded2dbSJung-uk Kim * influence which certificate is sent 317909286989SJung-uk Kim */ 31806f9291ceSJung-uk Kim if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { 3181*6cf8931aSJung-uk Kim int ret; 318209286989SJung-uk Kim CERT_PKEY *certpkey; 318309286989SJung-uk Kim certpkey = ssl_get_server_send_pkey(s); 318409286989SJung-uk Kim /* If no certificate can't return certificate status */ 3185*6cf8931aSJung-uk Kim if (certpkey != NULL) { 31866f9291ceSJung-uk Kim /* 31876f9291ceSJung-uk Kim * Set current certificate to one we will use so SSL_get_certificate 31886f9291ceSJung-uk Kim * et al can pick it up. 318909286989SJung-uk Kim */ 319009286989SJung-uk Kim s->cert->key = certpkey; 3191*6cf8931aSJung-uk Kim ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); 3192*6cf8931aSJung-uk Kim switch (ret) { 319309286989SJung-uk Kim /* We don't want to send a status request response */ 319409286989SJung-uk Kim case SSL_TLSEXT_ERR_NOACK: 319509286989SJung-uk Kim s->tlsext_status_expected = 0; 319609286989SJung-uk Kim break; 319709286989SJung-uk Kim /* status request response should be sent */ 319809286989SJung-uk Kim case SSL_TLSEXT_ERR_OK: 319909286989SJung-uk Kim if (s->tlsext_ocsp_resp) 320009286989SJung-uk Kim s->tlsext_status_expected = 1; 320109286989SJung-uk Kim break; 320209286989SJung-uk Kim /* something bad happened */ 320309286989SJung-uk Kim case SSL_TLSEXT_ERR_ALERT_FATAL: 320409286989SJung-uk Kim default: 3205*6cf8931aSJung-uk Kim *al = SSL_AD_INTERNAL_ERROR; 3206*6cf8931aSJung-uk Kim return 0; 320709286989SJung-uk Kim } 320809286989SJung-uk Kim } 3209*6cf8931aSJung-uk Kim } 3210*6cf8931aSJung-uk Kim 3211*6cf8931aSJung-uk Kim if (!tls1_alpn_handle_client_hello_late(s, al)) { 3212*6cf8931aSJung-uk Kim return 0; 3213*6cf8931aSJung-uk Kim } 3214*6cf8931aSJung-uk Kim 3215*6cf8931aSJung-uk Kim return 1; 3216*6cf8931aSJung-uk Kim } 321709286989SJung-uk Kim 3218db522d3aSSimon L. B. Nielsen int ssl_check_serverhello_tlsext(SSL *s) 3219db522d3aSSimon L. B. Nielsen { 3220db522d3aSSimon L. B. Nielsen int ret = SSL_TLSEXT_ERR_NOACK; 3221db522d3aSSimon L. B. Nielsen int al = SSL_AD_UNRECOGNIZED_NAME; 3222db522d3aSSimon L. B. Nielsen 32231f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 32246f9291ceSJung-uk Kim /* 32256f9291ceSJung-uk Kim * If we are client and using an elliptic curve cryptography cipher 32266f9291ceSJung-uk Kim * suite, then if server returns an EC point formats lists extension it 32276f9291ceSJung-uk Kim * must contain uncompressed. 32281f13597dSJung-uk Kim */ 32291f13597dSJung-uk Kim unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; 32301f13597dSJung-uk Kim unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; 32316f9291ceSJung-uk Kim if ((s->tlsext_ecpointformatlist != NULL) 32326f9291ceSJung-uk Kim && (s->tlsext_ecpointformatlist_length > 0) 32336f9291ceSJung-uk Kim && (s->session->tlsext_ecpointformatlist != NULL) 32346f9291ceSJung-uk Kim && (s->session->tlsext_ecpointformatlist_length > 0) 32356f9291ceSJung-uk Kim && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) 32366f9291ceSJung-uk Kim || (alg_a & SSL_aECDSA))) { 32371f13597dSJung-uk Kim /* we are using an ECC cipher */ 32381f13597dSJung-uk Kim size_t i; 32391f13597dSJung-uk Kim unsigned char *list; 32401f13597dSJung-uk Kim int found_uncompressed = 0; 32411f13597dSJung-uk Kim list = s->session->tlsext_ecpointformatlist; 32426f9291ceSJung-uk Kim for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) { 32436f9291ceSJung-uk Kim if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { 32441f13597dSJung-uk Kim found_uncompressed = 1; 32451f13597dSJung-uk Kim break; 32461f13597dSJung-uk Kim } 32471f13597dSJung-uk Kim } 32486f9291ceSJung-uk Kim if (!found_uncompressed) { 32496f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, 32506f9291ceSJung-uk Kim SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); 32511f13597dSJung-uk Kim return -1; 32521f13597dSJung-uk Kim } 32531f13597dSJung-uk Kim } 32541f13597dSJung-uk Kim ret = SSL_TLSEXT_ERR_OK; 32551f13597dSJung-uk Kim # endif /* OPENSSL_NO_EC */ 32561f13597dSJung-uk Kim 3257db522d3aSSimon L. B. Nielsen if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 32586f9291ceSJung-uk Kim ret = 32596f9291ceSJung-uk Kim s->ctx->tlsext_servername_callback(s, &al, 32606f9291ceSJung-uk Kim s->ctx->tlsext_servername_arg); 32616f9291ceSJung-uk Kim else if (s->initial_ctx != NULL 32626f9291ceSJung-uk Kim && s->initial_ctx->tlsext_servername_callback != 0) 32636f9291ceSJung-uk Kim ret = 32646f9291ceSJung-uk Kim s->initial_ctx->tlsext_servername_callback(s, &al, 32656f9291ceSJung-uk Kim s-> 32666f9291ceSJung-uk Kim initial_ctx->tlsext_servername_arg); 3267db522d3aSSimon L. B. Nielsen 32681f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input 32696f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input_len > 0) { 32706f9291ceSJung-uk Kim /* 32716f9291ceSJung-uk Kim * This case may indicate that we, as a client, want to insist on 32726f9291ceSJung-uk Kim * using opaque PRF inputs. So first verify that we really have a 32736f9291ceSJung-uk Kim * value from the server too. 32746f9291ceSJung-uk Kim */ 32751f13597dSJung-uk Kim 32766f9291ceSJung-uk Kim if (s->s3->server_opaque_prf_input == NULL) { 32771f13597dSJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 32781f13597dSJung-uk Kim al = SSL_AD_HANDSHAKE_FAILURE; 32791f13597dSJung-uk Kim } 32801f13597dSJung-uk Kim 32816f9291ceSJung-uk Kim /* 32826f9291ceSJung-uk Kim * Anytime the server *has* sent an opaque PRF input, we need to 32836f9291ceSJung-uk Kim * check that we have a client opaque PRF input of the same size. 32846f9291ceSJung-uk Kim */ 32851f13597dSJung-uk Kim if (s->s3->client_opaque_prf_input == NULL || 32866f9291ceSJung-uk Kim s->s3->client_opaque_prf_input_len != 32876f9291ceSJung-uk Kim s->s3->server_opaque_prf_input_len) { 32881f13597dSJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 32891f13597dSJung-uk Kim al = SSL_AD_ILLEGAL_PARAMETER; 32901f13597dSJung-uk Kim } 32911f13597dSJung-uk Kim } 32921f13597dSJung-uk Kim # endif 32931f13597dSJung-uk Kim 32948180e704SJung-uk Kim OPENSSL_free(s->tlsext_ocsp_resp); 32958180e704SJung-uk Kim s->tlsext_ocsp_resp = NULL; 32968180e704SJung-uk Kim s->tlsext_ocsp_resplen = -1; 32976f9291ceSJung-uk Kim /* 32986f9291ceSJung-uk Kim * If we've requested certificate status and we wont get one tell the 32996f9291ceSJung-uk Kim * callback 3300db522d3aSSimon L. B. Nielsen */ 3301db522d3aSSimon L. B. Nielsen if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) 33028180e704SJung-uk Kim && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) { 3303db522d3aSSimon L. B. Nielsen int r; 33046f9291ceSJung-uk Kim /* 33058180e704SJung-uk Kim * Call callback with resp == NULL and resplen == -1 so callback 33068180e704SJung-uk Kim * knows there is no response 3307db522d3aSSimon L. B. Nielsen */ 3308db522d3aSSimon L. B. Nielsen r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); 33096f9291ceSJung-uk Kim if (r == 0) { 3310db522d3aSSimon L. B. Nielsen al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; 3311db522d3aSSimon L. B. Nielsen ret = SSL_TLSEXT_ERR_ALERT_FATAL; 3312db522d3aSSimon L. B. Nielsen } 33136f9291ceSJung-uk Kim if (r < 0) { 3314db522d3aSSimon L. B. Nielsen al = SSL_AD_INTERNAL_ERROR; 3315db522d3aSSimon L. B. Nielsen ret = SSL_TLSEXT_ERR_ALERT_FATAL; 3316db522d3aSSimon L. B. Nielsen } 3317db522d3aSSimon L. B. Nielsen } 3318db522d3aSSimon L. B. Nielsen 33196f9291ceSJung-uk Kim switch (ret) { 3320db522d3aSSimon L. B. Nielsen case SSL_TLSEXT_ERR_ALERT_FATAL: 3321db522d3aSSimon L. B. Nielsen ssl3_send_alert(s, SSL3_AL_FATAL, al); 3322db522d3aSSimon L. B. Nielsen return -1; 3323db522d3aSSimon L. B. Nielsen 3324db522d3aSSimon L. B. Nielsen case SSL_TLSEXT_ERR_ALERT_WARNING: 3325db522d3aSSimon L. B. Nielsen ssl3_send_alert(s, SSL3_AL_WARNING, al); 3326db522d3aSSimon L. B. Nielsen return 1; 3327db522d3aSSimon L. B. Nielsen 3328db522d3aSSimon L. B. Nielsen case SSL_TLSEXT_ERR_NOACK: 3329db522d3aSSimon L. B. Nielsen s->servername_done = 0; 3330db522d3aSSimon L. B. Nielsen default: 3331db522d3aSSimon L. B. Nielsen return 1; 3332db522d3aSSimon L. B. Nielsen } 3333db522d3aSSimon L. B. Nielsen } 3334db522d3aSSimon L. B. Nielsen 33357bded2dbSJung-uk Kim int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, 33367bded2dbSJung-uk Kim int n) 33377bded2dbSJung-uk Kim { 33387bded2dbSJung-uk Kim int al = -1; 33397bded2dbSJung-uk Kim if (s->version < SSL3_VERSION) 33407bded2dbSJung-uk Kim return 1; 33417bded2dbSJung-uk Kim if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) { 33427bded2dbSJung-uk Kim ssl3_send_alert(s, SSL3_AL_FATAL, al); 33437bded2dbSJung-uk Kim return 0; 33447bded2dbSJung-uk Kim } 33457bded2dbSJung-uk Kim 33467bded2dbSJung-uk Kim if (ssl_check_serverhello_tlsext(s) <= 0) { 33477bded2dbSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT); 33487bded2dbSJung-uk Kim return 0; 33497bded2dbSJung-uk Kim } 33507bded2dbSJung-uk Kim return 1; 33517bded2dbSJung-uk Kim } 33527bded2dbSJung-uk Kim 33536f9291ceSJung-uk Kim /*- 33546f9291ceSJung-uk Kim * Since the server cache lookup is done early on in the processing of the 33551f13597dSJung-uk Kim * ClientHello, and other operations depend on the result, we need to handle 33561f13597dSJung-uk Kim * any TLS session ticket extension at the same time. 33571f13597dSJung-uk Kim * 33581f13597dSJung-uk Kim * session_id: points at the session ID in the ClientHello. This code will 33591f13597dSJung-uk Kim * read past the end of this in order to parse out the session ticket 33601f13597dSJung-uk Kim * extension, if any. 33611f13597dSJung-uk Kim * len: the length of the session ID. 33621f13597dSJung-uk Kim * limit: a pointer to the first byte after the ClientHello. 33631f13597dSJung-uk Kim * ret: (output) on return, if a ticket was decrypted, then this is set to 33641f13597dSJung-uk Kim * point to the resulting session. 33651f13597dSJung-uk Kim * 33661f13597dSJung-uk Kim * If s->tls_session_secret_cb is set then we are expecting a pre-shared key 33671f13597dSJung-uk Kim * ciphersuite, in which case we have no use for session tickets and one will 33681f13597dSJung-uk Kim * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. 33691f13597dSJung-uk Kim * 33701f13597dSJung-uk Kim * Returns: 33711f13597dSJung-uk Kim * -1: fatal error, either from parsing or decrypting the ticket. 33721f13597dSJung-uk Kim * 0: no ticket was found (or was ignored, based on settings). 33731f13597dSJung-uk Kim * 1: a zero length extension was found, indicating that the client supports 33741f13597dSJung-uk Kim * session tickets but doesn't currently have one to offer. 33751f13597dSJung-uk Kim * 2: either s->tls_session_secret_cb was set, or a ticket was offered but 33761f13597dSJung-uk Kim * couldn't be decrypted because of a non-fatal error. 33771f13597dSJung-uk Kim * 3: a ticket was successfully decrypted and *ret was set. 33781f13597dSJung-uk Kim * 33791f13597dSJung-uk Kim * Side effects: 33801f13597dSJung-uk Kim * Sets s->tlsext_ticket_expected to 1 if the server will have to issue 33811f13597dSJung-uk Kim * a new session ticket to the client because the client indicated support 33821f13597dSJung-uk Kim * (and s->tls_session_secret_cb is NULL) but the client either doesn't have 33831f13597dSJung-uk Kim * a session ticket or we couldn't use the one it gave us, or if 33841f13597dSJung-uk Kim * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. 33851f13597dSJung-uk Kim * Otherwise, s->tlsext_ticket_expected is set to 0. 3386db522d3aSSimon L. B. Nielsen */ 3387db522d3aSSimon L. B. Nielsen int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, 3388db522d3aSSimon L. B. Nielsen const unsigned char *limit, SSL_SESSION **ret) 3389db522d3aSSimon L. B. Nielsen { 3390db522d3aSSimon L. B. Nielsen /* Point after session ID in client hello */ 3391db522d3aSSimon L. B. Nielsen const unsigned char *p = session_id + len; 3392db522d3aSSimon L. B. Nielsen unsigned short i; 3393db522d3aSSimon L. B. Nielsen 33941f13597dSJung-uk Kim *ret = NULL; 33951f13597dSJung-uk Kim s->tlsext_ticket_expected = 0; 33961f13597dSJung-uk Kim 33976f9291ceSJung-uk Kim /* 33986f9291ceSJung-uk Kim * If tickets disabled behave as if no ticket present to permit stateful 33996f9291ceSJung-uk Kim * resumption. 3400db522d3aSSimon L. B. Nielsen */ 3401db522d3aSSimon L. B. Nielsen if (SSL_get_options(s) & SSL_OP_NO_TICKET) 34021f13597dSJung-uk Kim return 0; 3403db522d3aSSimon L. B. Nielsen if ((s->version <= SSL3_VERSION) || !limit) 34041f13597dSJung-uk Kim return 0; 3405db522d3aSSimon L. B. Nielsen if (p >= limit) 3406db522d3aSSimon L. B. Nielsen return -1; 34076a599222SSimon L. B. Nielsen /* Skip past DTLS cookie */ 34087bded2dbSJung-uk Kim if (SSL_IS_DTLS(s)) { 34096a599222SSimon L. B. Nielsen i = *(p++); 3410aeb5019cSJung-uk Kim 3411aeb5019cSJung-uk Kim if (limit - p <= i) 34126a599222SSimon L. B. Nielsen return -1; 3413aeb5019cSJung-uk Kim 3414aeb5019cSJung-uk Kim p += i; 34156a599222SSimon L. B. Nielsen } 3416db522d3aSSimon L. B. Nielsen /* Skip past cipher list */ 3417db522d3aSSimon L. B. Nielsen n2s(p, i); 3418aeb5019cSJung-uk Kim if (limit - p <= i) 3419db522d3aSSimon L. B. Nielsen return -1; 3420aeb5019cSJung-uk Kim p += i; 3421aeb5019cSJung-uk Kim 3422db522d3aSSimon L. B. Nielsen /* Skip past compression algorithm list */ 3423db522d3aSSimon L. B. Nielsen i = *(p++); 3424aeb5019cSJung-uk Kim if (limit - p < i) 3425db522d3aSSimon L. B. Nielsen return -1; 3426aeb5019cSJung-uk Kim p += i; 3427aeb5019cSJung-uk Kim 3428db522d3aSSimon L. B. Nielsen /* Now at start of extensions */ 3429aeb5019cSJung-uk Kim if (limit - p <= 2) 34301f13597dSJung-uk Kim return 0; 3431db522d3aSSimon L. B. Nielsen n2s(p, i); 3432aeb5019cSJung-uk Kim while (limit - p >= 4) { 3433db522d3aSSimon L. B. Nielsen unsigned short type, size; 3434db522d3aSSimon L. B. Nielsen n2s(p, type); 3435db522d3aSSimon L. B. Nielsen n2s(p, size); 3436aeb5019cSJung-uk Kim if (limit - p < size) 34371f13597dSJung-uk Kim return 0; 34386f9291ceSJung-uk Kim if (type == TLSEXT_TYPE_session_ticket) { 34391f13597dSJung-uk Kim int r; 34406f9291ceSJung-uk Kim if (size == 0) { 34416f9291ceSJung-uk Kim /* 34426f9291ceSJung-uk Kim * The client will accept a ticket but doesn't currently have 34436f9291ceSJung-uk Kim * one. 34446f9291ceSJung-uk Kim */ 3445db522d3aSSimon L. B. Nielsen s->tlsext_ticket_expected = 1; 34461f13597dSJung-uk Kim return 1; 3447db522d3aSSimon L. B. Nielsen } 34486f9291ceSJung-uk Kim if (s->tls_session_secret_cb) { 34496f9291ceSJung-uk Kim /* 34506f9291ceSJung-uk Kim * Indicate that the ticket couldn't be decrypted rather than 34516f9291ceSJung-uk Kim * generating the session from ticket now, trigger 34526f9291ceSJung-uk Kim * abbreviated handshake based on external mechanism to 34536f9291ceSJung-uk Kim * calculate the master secret later. 34546f9291ceSJung-uk Kim */ 34551f13597dSJung-uk Kim return 2; 34561f13597dSJung-uk Kim } 34571f13597dSJung-uk Kim r = tls_decrypt_ticket(s, p, size, session_id, len, ret); 34586f9291ceSJung-uk Kim switch (r) { 34591f13597dSJung-uk Kim case 2: /* ticket couldn't be decrypted */ 34601f13597dSJung-uk Kim s->tlsext_ticket_expected = 1; 34611f13597dSJung-uk Kim return 2; 34621f13597dSJung-uk Kim case 3: /* ticket was decrypted */ 34631f13597dSJung-uk Kim return r; 34641f13597dSJung-uk Kim case 4: /* ticket decrypted but need to renew */ 34651f13597dSJung-uk Kim s->tlsext_ticket_expected = 1; 34661f13597dSJung-uk Kim return 3; 34671f13597dSJung-uk Kim default: /* fatal error */ 34681f13597dSJung-uk Kim return -1; 34691f13597dSJung-uk Kim } 3470db522d3aSSimon L. B. Nielsen } 3471db522d3aSSimon L. B. Nielsen p += size; 3472db522d3aSSimon L. B. Nielsen } 34731f13597dSJung-uk Kim return 0; 3474db522d3aSSimon L. B. Nielsen } 3475db522d3aSSimon L. B. Nielsen 34766f9291ceSJung-uk Kim /*- 34776f9291ceSJung-uk Kim * tls_decrypt_ticket attempts to decrypt a session ticket. 34781f13597dSJung-uk Kim * 34791f13597dSJung-uk Kim * etick: points to the body of the session ticket extension. 34801f13597dSJung-uk Kim * eticklen: the length of the session tickets extenion. 34811f13597dSJung-uk Kim * sess_id: points at the session ID. 34821f13597dSJung-uk Kim * sesslen: the length of the session ID. 34831f13597dSJung-uk Kim * psess: (output) on return, if a ticket was decrypted, then this is set to 34841f13597dSJung-uk Kim * point to the resulting session. 34851f13597dSJung-uk Kim * 34861f13597dSJung-uk Kim * Returns: 34871f13597dSJung-uk Kim * -1: fatal error, either from parsing or decrypting the ticket. 34881f13597dSJung-uk Kim * 2: the ticket couldn't be decrypted. 34891f13597dSJung-uk Kim * 3: a ticket was successfully decrypted and *psess was set. 34901f13597dSJung-uk Kim * 4: same as 3, but the ticket needs to be renewed. 34911f13597dSJung-uk Kim */ 34926f9291ceSJung-uk Kim static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, 34936f9291ceSJung-uk Kim int eticklen, const unsigned char *sess_id, 34946f9291ceSJung-uk Kim int sesslen, SSL_SESSION **psess) 3495db522d3aSSimon L. B. Nielsen { 3496db522d3aSSimon L. B. Nielsen SSL_SESSION *sess; 3497db522d3aSSimon L. B. Nielsen unsigned char *sdec; 3498db522d3aSSimon L. B. Nielsen const unsigned char *p; 3499db522d3aSSimon L. B. Nielsen int slen, mlen, renew_ticket = 0; 3500db522d3aSSimon L. B. Nielsen unsigned char tick_hmac[EVP_MAX_MD_SIZE]; 3501db522d3aSSimon L. B. Nielsen HMAC_CTX hctx; 3502db522d3aSSimon L. B. Nielsen EVP_CIPHER_CTX ctx; 35036a599222SSimon L. B. Nielsen SSL_CTX *tctx = s->initial_ctx; 3504aeb5019cSJung-uk Kim 3505db522d3aSSimon L. B. Nielsen /* Initialize session ticket encryption and HMAC contexts */ 3506db522d3aSSimon L. B. Nielsen HMAC_CTX_init(&hctx); 3507db522d3aSSimon L. B. Nielsen EVP_CIPHER_CTX_init(&ctx); 35086f9291ceSJung-uk Kim if (tctx->tlsext_ticket_key_cb) { 3509db522d3aSSimon L. B. Nielsen unsigned char *nctick = (unsigned char *)etick; 35106a599222SSimon L. B. Nielsen int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, 3511db522d3aSSimon L. B. Nielsen &ctx, &hctx, 0); 3512db522d3aSSimon L. B. Nielsen if (rv < 0) 3513db522d3aSSimon L. B. Nielsen return -1; 3514db522d3aSSimon L. B. Nielsen if (rv == 0) 35151f13597dSJung-uk Kim return 2; 3516db522d3aSSimon L. B. Nielsen if (rv == 2) 3517db522d3aSSimon L. B. Nielsen renew_ticket = 1; 35186f9291ceSJung-uk Kim } else { 3519db522d3aSSimon L. B. Nielsen /* Check key name matches */ 35206a599222SSimon L. B. Nielsen if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) 35211f13597dSJung-uk Kim return 2; 352280815a77SJung-uk Kim if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, 352380815a77SJung-uk Kim tlsext_tick_md(), NULL) <= 0 352480815a77SJung-uk Kim || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, 352580815a77SJung-uk Kim tctx->tlsext_tick_aes_key, 352680815a77SJung-uk Kim etick + 16) <= 0) { 352780815a77SJung-uk Kim goto err; 352880815a77SJung-uk Kim } 3529db522d3aSSimon L. B. Nielsen } 35306f9291ceSJung-uk Kim /* 35316f9291ceSJung-uk Kim * Attempt to process session ticket, first conduct sanity and integrity 35326f9291ceSJung-uk Kim * checks on ticket. 3533db522d3aSSimon L. B. Nielsen */ 3534db522d3aSSimon L. B. Nielsen mlen = HMAC_size(&hctx); 35356f9291ceSJung-uk Kim if (mlen < 0) { 353680815a77SJung-uk Kim goto err; 35371f13597dSJung-uk Kim } 3538aeb5019cSJung-uk Kim /* Sanity check ticket length: must exceed keyname + IV + HMAC */ 3539aeb5019cSJung-uk Kim if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { 3540aeb5019cSJung-uk Kim HMAC_CTX_cleanup(&hctx); 3541aeb5019cSJung-uk Kim EVP_CIPHER_CTX_cleanup(&ctx); 3542aeb5019cSJung-uk Kim return 2; 3543aeb5019cSJung-uk Kim } 3544aeb5019cSJung-uk Kim 3545db522d3aSSimon L. B. Nielsen eticklen -= mlen; 3546db522d3aSSimon L. B. Nielsen /* Check HMAC of encrypted ticket */ 354780815a77SJung-uk Kim if (HMAC_Update(&hctx, etick, eticklen) <= 0 354880815a77SJung-uk Kim || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) { 354980815a77SJung-uk Kim goto err; 355080815a77SJung-uk Kim } 3551db522d3aSSimon L. B. Nielsen HMAC_CTX_cleanup(&hctx); 35526f9291ceSJung-uk Kim if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { 3553fa5fddf1SJung-uk Kim EVP_CIPHER_CTX_cleanup(&ctx); 35541f13597dSJung-uk Kim return 2; 3555fa5fddf1SJung-uk Kim } 3556db522d3aSSimon L. B. Nielsen /* Attempt to decrypt session data */ 3557db522d3aSSimon L. B. Nielsen /* Move p after IV to start of encrypted ticket, update length */ 3558db522d3aSSimon L. B. Nielsen p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); 3559db522d3aSSimon L. B. Nielsen eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); 3560db522d3aSSimon L. B. Nielsen sdec = OPENSSL_malloc(eticklen); 3561b8721c16SJung-uk Kim if (sdec == NULL 3562b8721c16SJung-uk Kim || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { 3563db522d3aSSimon L. B. Nielsen EVP_CIPHER_CTX_cleanup(&ctx); 3564b8721c16SJung-uk Kim OPENSSL_free(sdec); 3565db522d3aSSimon L. B. Nielsen return -1; 3566db522d3aSSimon L. B. Nielsen } 35676f9291ceSJung-uk Kim if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) { 3568a93cbc2bSJung-uk Kim EVP_CIPHER_CTX_cleanup(&ctx); 3569a93cbc2bSJung-uk Kim OPENSSL_free(sdec); 35701f13597dSJung-uk Kim return 2; 3571a93cbc2bSJung-uk Kim } 3572db522d3aSSimon L. B. Nielsen slen += mlen; 3573db522d3aSSimon L. B. Nielsen EVP_CIPHER_CTX_cleanup(&ctx); 3574db522d3aSSimon L. B. Nielsen p = sdec; 3575db522d3aSSimon L. B. Nielsen 3576db522d3aSSimon L. B. Nielsen sess = d2i_SSL_SESSION(NULL, &p, slen); 3577db522d3aSSimon L. B. Nielsen OPENSSL_free(sdec); 35786f9291ceSJung-uk Kim if (sess) { 35796f9291ceSJung-uk Kim /* 35806f9291ceSJung-uk Kim * The session ID, if non-empty, is used by some clients to detect 35816f9291ceSJung-uk Kim * that the ticket has been accepted. So we copy it to the session 35826f9291ceSJung-uk Kim * structure. If it is empty set length to zero as required by 35836f9291ceSJung-uk Kim * standard. 3584db522d3aSSimon L. B. Nielsen */ 3585db522d3aSSimon L. B. Nielsen if (sesslen) 3586db522d3aSSimon L. B. Nielsen memcpy(sess->session_id, sess_id, sesslen); 3587db522d3aSSimon L. B. Nielsen sess->session_id_length = sesslen; 3588db522d3aSSimon L. B. Nielsen *psess = sess; 35891f13597dSJung-uk Kim if (renew_ticket) 35901f13597dSJung-uk Kim return 4; 35911f13597dSJung-uk Kim else 35921f13597dSJung-uk Kim return 3; 35931f13597dSJung-uk Kim } 35941f13597dSJung-uk Kim ERR_clear_error(); 35956f9291ceSJung-uk Kim /* 35966f9291ceSJung-uk Kim * For session parse failure, indicate that we need to send a new ticket. 35976f9291ceSJung-uk Kim */ 35981f13597dSJung-uk Kim return 2; 359980815a77SJung-uk Kim err: 360080815a77SJung-uk Kim EVP_CIPHER_CTX_cleanup(&ctx); 360180815a77SJung-uk Kim HMAC_CTX_cleanup(&hctx); 360280815a77SJung-uk Kim return -1; 36031f13597dSJung-uk Kim } 36041f13597dSJung-uk Kim 36051f13597dSJung-uk Kim /* Tables to translate from NIDs to TLS v1.2 ids */ 36061f13597dSJung-uk Kim 36076f9291ceSJung-uk Kim typedef struct { 36081f13597dSJung-uk Kim int nid; 36091f13597dSJung-uk Kim int id; 36101f13597dSJung-uk Kim } tls12_lookup; 36111f13597dSJung-uk Kim 36121f13597dSJung-uk Kim static tls12_lookup tls12_md[] = { 36131f13597dSJung-uk Kim {NID_md5, TLSEXT_hash_md5}, 36141f13597dSJung-uk Kim {NID_sha1, TLSEXT_hash_sha1}, 36151f13597dSJung-uk Kim {NID_sha224, TLSEXT_hash_sha224}, 36161f13597dSJung-uk Kim {NID_sha256, TLSEXT_hash_sha256}, 36171f13597dSJung-uk Kim {NID_sha384, TLSEXT_hash_sha384}, 36181f13597dSJung-uk Kim {NID_sha512, TLSEXT_hash_sha512} 36191f13597dSJung-uk Kim }; 36201f13597dSJung-uk Kim 36211f13597dSJung-uk Kim static tls12_lookup tls12_sig[] = { 36221f13597dSJung-uk Kim {EVP_PKEY_RSA, TLSEXT_signature_rsa}, 36231f13597dSJung-uk Kim {EVP_PKEY_DSA, TLSEXT_signature_dsa}, 36241f13597dSJung-uk Kim {EVP_PKEY_EC, TLSEXT_signature_ecdsa} 36251f13597dSJung-uk Kim }; 36261f13597dSJung-uk Kim 36271f13597dSJung-uk Kim static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) 36281f13597dSJung-uk Kim { 36291f13597dSJung-uk Kim size_t i; 36306f9291ceSJung-uk Kim for (i = 0; i < tlen; i++) { 36311f13597dSJung-uk Kim if (table[i].nid == nid) 36321f13597dSJung-uk Kim return table[i].id; 36331f13597dSJung-uk Kim } 36341f13597dSJung-uk Kim return -1; 36351f13597dSJung-uk Kim } 36366f9291ceSJung-uk Kim 36371f13597dSJung-uk Kim static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) 36381f13597dSJung-uk Kim { 36391f13597dSJung-uk Kim size_t i; 36406f9291ceSJung-uk Kim for (i = 0; i < tlen; i++) { 36417bded2dbSJung-uk Kim if ((table[i].id) == id) 36421f13597dSJung-uk Kim return table[i].nid; 36431f13597dSJung-uk Kim } 36447bded2dbSJung-uk Kim return NID_undef; 36451f13597dSJung-uk Kim } 36461f13597dSJung-uk Kim 36476f9291ceSJung-uk Kim int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, 36486f9291ceSJung-uk Kim const EVP_MD *md) 36491f13597dSJung-uk Kim { 36501f13597dSJung-uk Kim int sig_id, md_id; 36511f13597dSJung-uk Kim if (!md) 36521f13597dSJung-uk Kim return 0; 36531f13597dSJung-uk Kim md_id = tls12_find_id(EVP_MD_type(md), tls12_md, 36541f13597dSJung-uk Kim sizeof(tls12_md) / sizeof(tls12_lookup)); 36551f13597dSJung-uk Kim if (md_id == -1) 36561f13597dSJung-uk Kim return 0; 36571f13597dSJung-uk Kim sig_id = tls12_get_sigid(pk); 36581f13597dSJung-uk Kim if (sig_id == -1) 36591f13597dSJung-uk Kim return 0; 36601f13597dSJung-uk Kim p[0] = (unsigned char)md_id; 36611f13597dSJung-uk Kim p[1] = (unsigned char)sig_id; 3662db522d3aSSimon L. B. Nielsen return 1; 3663db522d3aSSimon L. B. Nielsen } 36641f13597dSJung-uk Kim 36651f13597dSJung-uk Kim int tls12_get_sigid(const EVP_PKEY *pk) 36661f13597dSJung-uk Kim { 36671f13597dSJung-uk Kim return tls12_find_id(pk->type, tls12_sig, 36681f13597dSJung-uk Kim sizeof(tls12_sig) / sizeof(tls12_lookup)); 36691f13597dSJung-uk Kim } 36701f13597dSJung-uk Kim 36711f13597dSJung-uk Kim const EVP_MD *tls12_get_hash(unsigned char hash_alg) 36721f13597dSJung-uk Kim { 36736f9291ceSJung-uk Kim switch (hash_alg) { 36747bded2dbSJung-uk Kim # ifndef OPENSSL_NO_MD5 36757bded2dbSJung-uk Kim case TLSEXT_hash_md5: 36767bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS 36777bded2dbSJung-uk Kim if (FIPS_mode()) 36787bded2dbSJung-uk Kim return NULL; 36797bded2dbSJung-uk Kim # endif 36807bded2dbSJung-uk Kim return EVP_md5(); 36817bded2dbSJung-uk Kim # endif 36821f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA 36831f13597dSJung-uk Kim case TLSEXT_hash_sha1: 36841f13597dSJung-uk Kim return EVP_sha1(); 36851f13597dSJung-uk Kim # endif 36861f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256 36871f13597dSJung-uk Kim case TLSEXT_hash_sha224: 36881f13597dSJung-uk Kim return EVP_sha224(); 36891f13597dSJung-uk Kim 36901f13597dSJung-uk Kim case TLSEXT_hash_sha256: 36911f13597dSJung-uk Kim return EVP_sha256(); 36921f13597dSJung-uk Kim # endif 36931f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512 36941f13597dSJung-uk Kim case TLSEXT_hash_sha384: 36951f13597dSJung-uk Kim return EVP_sha384(); 36961f13597dSJung-uk Kim 36971f13597dSJung-uk Kim case TLSEXT_hash_sha512: 36981f13597dSJung-uk Kim return EVP_sha512(); 36991f13597dSJung-uk Kim # endif 37001f13597dSJung-uk Kim default: 37011f13597dSJung-uk Kim return NULL; 37021f13597dSJung-uk Kim 37031f13597dSJung-uk Kim } 37041f13597dSJung-uk Kim } 37051f13597dSJung-uk Kim 37067bded2dbSJung-uk Kim static int tls12_get_pkey_idx(unsigned char sig_alg) 37077bded2dbSJung-uk Kim { 37087bded2dbSJung-uk Kim switch (sig_alg) { 37097bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA 37107bded2dbSJung-uk Kim case TLSEXT_signature_rsa: 37117bded2dbSJung-uk Kim return SSL_PKEY_RSA_SIGN; 37127bded2dbSJung-uk Kim # endif 37137bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA 37147bded2dbSJung-uk Kim case TLSEXT_signature_dsa: 37157bded2dbSJung-uk Kim return SSL_PKEY_DSA_SIGN; 37167bded2dbSJung-uk Kim # endif 37177bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA 37187bded2dbSJung-uk Kim case TLSEXT_signature_ecdsa: 37197bded2dbSJung-uk Kim return SSL_PKEY_ECC; 37207bded2dbSJung-uk Kim # endif 37217bded2dbSJung-uk Kim } 37227bded2dbSJung-uk Kim return -1; 37237bded2dbSJung-uk Kim } 37247bded2dbSJung-uk Kim 37257bded2dbSJung-uk Kim /* Convert TLS 1.2 signature algorithm extension values into NIDs */ 37267bded2dbSJung-uk Kim static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid, 37277bded2dbSJung-uk Kim int *psignhash_nid, const unsigned char *data) 37287bded2dbSJung-uk Kim { 37298180e704SJung-uk Kim int sign_nid = NID_undef, hash_nid = NID_undef; 37307bded2dbSJung-uk Kim if (!phash_nid && !psign_nid && !psignhash_nid) 37317bded2dbSJung-uk Kim return; 37327bded2dbSJung-uk Kim if (phash_nid || psignhash_nid) { 37337bded2dbSJung-uk Kim hash_nid = tls12_find_nid(data[0], tls12_md, 37347bded2dbSJung-uk Kim sizeof(tls12_md) / sizeof(tls12_lookup)); 37357bded2dbSJung-uk Kim if (phash_nid) 37367bded2dbSJung-uk Kim *phash_nid = hash_nid; 37377bded2dbSJung-uk Kim } 37387bded2dbSJung-uk Kim if (psign_nid || psignhash_nid) { 37397bded2dbSJung-uk Kim sign_nid = tls12_find_nid(data[1], tls12_sig, 37407bded2dbSJung-uk Kim sizeof(tls12_sig) / sizeof(tls12_lookup)); 37417bded2dbSJung-uk Kim if (psign_nid) 37427bded2dbSJung-uk Kim *psign_nid = sign_nid; 37437bded2dbSJung-uk Kim } 37447bded2dbSJung-uk Kim if (psignhash_nid) { 37458180e704SJung-uk Kim if (sign_nid == NID_undef || hash_nid == NID_undef 37468180e704SJung-uk Kim || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, 37478180e704SJung-uk Kim sign_nid) <= 0) 37487bded2dbSJung-uk Kim *psignhash_nid = NID_undef; 37497bded2dbSJung-uk Kim } 37507bded2dbSJung-uk Kim } 37517bded2dbSJung-uk Kim 37527bded2dbSJung-uk Kim /* Given preference and allowed sigalgs set shared sigalgs */ 37537bded2dbSJung-uk Kim static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, 37547bded2dbSJung-uk Kim const unsigned char *pref, size_t preflen, 37557bded2dbSJung-uk Kim const unsigned char *allow, 37567bded2dbSJung-uk Kim size_t allowlen) 37577bded2dbSJung-uk Kim { 37587bded2dbSJung-uk Kim const unsigned char *ptmp, *atmp; 37597bded2dbSJung-uk Kim size_t i, j, nmatch = 0; 37607bded2dbSJung-uk Kim for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) { 37617bded2dbSJung-uk Kim /* Skip disabled hashes or signature algorithms */ 37627bded2dbSJung-uk Kim if (tls12_get_hash(ptmp[0]) == NULL) 37637bded2dbSJung-uk Kim continue; 37647bded2dbSJung-uk Kim if (tls12_get_pkey_idx(ptmp[1]) == -1) 37657bded2dbSJung-uk Kim continue; 37667bded2dbSJung-uk Kim for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) { 37677bded2dbSJung-uk Kim if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) { 37687bded2dbSJung-uk Kim nmatch++; 37697bded2dbSJung-uk Kim if (shsig) { 37707bded2dbSJung-uk Kim shsig->rhash = ptmp[0]; 37717bded2dbSJung-uk Kim shsig->rsign = ptmp[1]; 37727bded2dbSJung-uk Kim tls1_lookup_sigalg(&shsig->hash_nid, 37737bded2dbSJung-uk Kim &shsig->sign_nid, 37747bded2dbSJung-uk Kim &shsig->signandhash_nid, ptmp); 37757bded2dbSJung-uk Kim shsig++; 37767bded2dbSJung-uk Kim } 37777bded2dbSJung-uk Kim break; 37787bded2dbSJung-uk Kim } 37797bded2dbSJung-uk Kim } 37807bded2dbSJung-uk Kim } 37817bded2dbSJung-uk Kim return nmatch; 37827bded2dbSJung-uk Kim } 37837bded2dbSJung-uk Kim 37847bded2dbSJung-uk Kim /* Set shared signature algorithms for SSL structures */ 37857bded2dbSJung-uk Kim static int tls1_set_shared_sigalgs(SSL *s) 37867bded2dbSJung-uk Kim { 37877bded2dbSJung-uk Kim const unsigned char *pref, *allow, *conf; 37887bded2dbSJung-uk Kim size_t preflen, allowlen, conflen; 37897bded2dbSJung-uk Kim size_t nmatch; 37907bded2dbSJung-uk Kim TLS_SIGALGS *salgs = NULL; 37917bded2dbSJung-uk Kim CERT *c = s->cert; 37927bded2dbSJung-uk Kim unsigned int is_suiteb = tls1_suiteb(s); 37937bded2dbSJung-uk Kim if (c->shared_sigalgs) { 37947bded2dbSJung-uk Kim OPENSSL_free(c->shared_sigalgs); 37957bded2dbSJung-uk Kim c->shared_sigalgs = NULL; 37967bded2dbSJung-uk Kim c->shared_sigalgslen = 0; 37977bded2dbSJung-uk Kim } 37987bded2dbSJung-uk Kim /* If client use client signature algorithms if not NULL */ 37997bded2dbSJung-uk Kim if (!s->server && c->client_sigalgs && !is_suiteb) { 38007bded2dbSJung-uk Kim conf = c->client_sigalgs; 38017bded2dbSJung-uk Kim conflen = c->client_sigalgslen; 38027bded2dbSJung-uk Kim } else if (c->conf_sigalgs && !is_suiteb) { 38037bded2dbSJung-uk Kim conf = c->conf_sigalgs; 38047bded2dbSJung-uk Kim conflen = c->conf_sigalgslen; 38057bded2dbSJung-uk Kim } else 38067bded2dbSJung-uk Kim conflen = tls12_get_psigalgs(s, &conf); 38077bded2dbSJung-uk Kim if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { 38087bded2dbSJung-uk Kim pref = conf; 38097bded2dbSJung-uk Kim preflen = conflen; 38107bded2dbSJung-uk Kim allow = c->peer_sigalgs; 38117bded2dbSJung-uk Kim allowlen = c->peer_sigalgslen; 38127bded2dbSJung-uk Kim } else { 38137bded2dbSJung-uk Kim allow = conf; 38147bded2dbSJung-uk Kim allowlen = conflen; 38157bded2dbSJung-uk Kim pref = c->peer_sigalgs; 38167bded2dbSJung-uk Kim preflen = c->peer_sigalgslen; 38177bded2dbSJung-uk Kim } 38187bded2dbSJung-uk Kim nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen); 38197bded2dbSJung-uk Kim if (nmatch) { 38207bded2dbSJung-uk Kim salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); 38217bded2dbSJung-uk Kim if (!salgs) 38227bded2dbSJung-uk Kim return 0; 38237bded2dbSJung-uk Kim nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen); 38247bded2dbSJung-uk Kim } else { 38257bded2dbSJung-uk Kim salgs = NULL; 38267bded2dbSJung-uk Kim } 38277bded2dbSJung-uk Kim c->shared_sigalgs = salgs; 38287bded2dbSJung-uk Kim c->shared_sigalgslen = nmatch; 38297bded2dbSJung-uk Kim return 1; 38307bded2dbSJung-uk Kim } 38317bded2dbSJung-uk Kim 38321f13597dSJung-uk Kim /* Set preferred digest for each key type */ 38331f13597dSJung-uk Kim 38347bded2dbSJung-uk Kim int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize) 38351f13597dSJung-uk Kim { 38361f13597dSJung-uk Kim CERT *c = s->cert; 38377bded2dbSJung-uk Kim /* Extension ignored for inappropriate versions */ 38387bded2dbSJung-uk Kim if (!SSL_USE_SIGALGS(s)) 38391f13597dSJung-uk Kim return 1; 38401f13597dSJung-uk Kim /* Should never happen */ 38411f13597dSJung-uk Kim if (!c) 38421f13597dSJung-uk Kim return 0; 38431f13597dSJung-uk Kim 38447bded2dbSJung-uk Kim if (c->peer_sigalgs) 38457bded2dbSJung-uk Kim OPENSSL_free(c->peer_sigalgs); 38467bded2dbSJung-uk Kim c->peer_sigalgs = OPENSSL_malloc(dsize); 38477bded2dbSJung-uk Kim if (!c->peer_sigalgs) 38487bded2dbSJung-uk Kim return 0; 38497bded2dbSJung-uk Kim c->peer_sigalgslen = dsize; 38507bded2dbSJung-uk Kim memcpy(c->peer_sigalgs, data, dsize); 38517bded2dbSJung-uk Kim return 1; 38521f13597dSJung-uk Kim } 38531f13597dSJung-uk Kim 38547bded2dbSJung-uk Kim int tls1_process_sigalgs(SSL *s) 38557bded2dbSJung-uk Kim { 38567bded2dbSJung-uk Kim int idx; 38577bded2dbSJung-uk Kim size_t i; 38587bded2dbSJung-uk Kim const EVP_MD *md; 38597bded2dbSJung-uk Kim CERT *c = s->cert; 38607bded2dbSJung-uk Kim TLS_SIGALGS *sigptr; 38617bded2dbSJung-uk Kim if (!tls1_set_shared_sigalgs(s)) 38627bded2dbSJung-uk Kim return 0; 38637bded2dbSJung-uk Kim 38647bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL 38657bded2dbSJung-uk Kim if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { 38667bded2dbSJung-uk Kim /* 38677bded2dbSJung-uk Kim * Use first set signature preference to force message digest, 38687bded2dbSJung-uk Kim * ignoring any peer preferences. 38697bded2dbSJung-uk Kim */ 38707bded2dbSJung-uk Kim const unsigned char *sigs = NULL; 38717bded2dbSJung-uk Kim if (s->server) 38727bded2dbSJung-uk Kim sigs = c->conf_sigalgs; 38737bded2dbSJung-uk Kim else 38747bded2dbSJung-uk Kim sigs = c->client_sigalgs; 38757bded2dbSJung-uk Kim if (sigs) { 38767bded2dbSJung-uk Kim idx = tls12_get_pkey_idx(sigs[1]); 38777bded2dbSJung-uk Kim md = tls12_get_hash(sigs[0]); 38781f13597dSJung-uk Kim c->pkeys[idx].digest = md; 38797bded2dbSJung-uk Kim c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; 38807bded2dbSJung-uk Kim if (idx == SSL_PKEY_RSA_SIGN) { 38817bded2dbSJung-uk Kim c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = 38827bded2dbSJung-uk Kim CERT_PKEY_EXPLICIT_SIGN; 38837bded2dbSJung-uk Kim c->pkeys[SSL_PKEY_RSA_ENC].digest = md; 38847bded2dbSJung-uk Kim } 38857bded2dbSJung-uk Kim } 38867bded2dbSJung-uk Kim } 38877bded2dbSJung-uk Kim # endif 38887bded2dbSJung-uk Kim 38897bded2dbSJung-uk Kim for (i = 0, sigptr = c->shared_sigalgs; 38907bded2dbSJung-uk Kim i < c->shared_sigalgslen; i++, sigptr++) { 38917bded2dbSJung-uk Kim idx = tls12_get_pkey_idx(sigptr->rsign); 38927bded2dbSJung-uk Kim if (idx > 0 && c->pkeys[idx].digest == NULL) { 38937bded2dbSJung-uk Kim md = tls12_get_hash(sigptr->rhash); 38947bded2dbSJung-uk Kim c->pkeys[idx].digest = md; 38957bded2dbSJung-uk Kim c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; 38967bded2dbSJung-uk Kim if (idx == SSL_PKEY_RSA_SIGN) { 38977bded2dbSJung-uk Kim c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = 38987bded2dbSJung-uk Kim CERT_PKEY_EXPLICIT_SIGN; 38991f13597dSJung-uk Kim c->pkeys[SSL_PKEY_RSA_ENC].digest = md; 39001f13597dSJung-uk Kim } 39011f13597dSJung-uk Kim } 39021f13597dSJung-uk Kim 39031f13597dSJung-uk Kim } 39047bded2dbSJung-uk Kim /* 39057bded2dbSJung-uk Kim * In strict mode leave unset digests as NULL to indicate we can't use 39067bded2dbSJung-uk Kim * the certificate for signing. 39077bded2dbSJung-uk Kim */ 39087bded2dbSJung-uk Kim if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { 39096f9291ceSJung-uk Kim /* 39106f9291ceSJung-uk Kim * Set any remaining keys to default values. NOTE: if alg is not 39111f13597dSJung-uk Kim * supported it stays as NULL. 3912db522d3aSSimon L. B. Nielsen */ 39131f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA 39141f13597dSJung-uk Kim if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) 391509286989SJung-uk Kim c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); 39161f13597dSJung-uk Kim # endif 39171f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA 39186f9291ceSJung-uk Kim if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { 39191f13597dSJung-uk Kim c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); 39201f13597dSJung-uk Kim c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); 39211f13597dSJung-uk Kim } 39221f13597dSJung-uk Kim # endif 39231f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA 39241f13597dSJung-uk Kim if (!c->pkeys[SSL_PKEY_ECC].digest) 392509286989SJung-uk Kim c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); 39261f13597dSJung-uk Kim # endif 39277bded2dbSJung-uk Kim } 39281f13597dSJung-uk Kim return 1; 39291f13597dSJung-uk Kim } 39301f13597dSJung-uk Kim 39317bded2dbSJung-uk Kim int SSL_get_sigalgs(SSL *s, int idx, 39327bded2dbSJung-uk Kim int *psign, int *phash, int *psignhash, 39337bded2dbSJung-uk Kim unsigned char *rsig, unsigned char *rhash) 39347bded2dbSJung-uk Kim { 39357bded2dbSJung-uk Kim const unsigned char *psig = s->cert->peer_sigalgs; 39367bded2dbSJung-uk Kim if (psig == NULL) 39377bded2dbSJung-uk Kim return 0; 39387bded2dbSJung-uk Kim if (idx >= 0) { 39397bded2dbSJung-uk Kim idx <<= 1; 39407bded2dbSJung-uk Kim if (idx >= (int)s->cert->peer_sigalgslen) 39417bded2dbSJung-uk Kim return 0; 39427bded2dbSJung-uk Kim psig += idx; 39437bded2dbSJung-uk Kim if (rhash) 39447bded2dbSJung-uk Kim *rhash = psig[0]; 39457bded2dbSJung-uk Kim if (rsig) 39467bded2dbSJung-uk Kim *rsig = psig[1]; 39477bded2dbSJung-uk Kim tls1_lookup_sigalg(phash, psign, psignhash, psig); 39487bded2dbSJung-uk Kim } 39497bded2dbSJung-uk Kim return s->cert->peer_sigalgslen / 2; 39507bded2dbSJung-uk Kim } 39517bded2dbSJung-uk Kim 39527bded2dbSJung-uk Kim int SSL_get_shared_sigalgs(SSL *s, int idx, 39537bded2dbSJung-uk Kim int *psign, int *phash, int *psignhash, 39547bded2dbSJung-uk Kim unsigned char *rsig, unsigned char *rhash) 39557bded2dbSJung-uk Kim { 39567bded2dbSJung-uk Kim TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs; 39577bded2dbSJung-uk Kim if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) 39587bded2dbSJung-uk Kim return 0; 39597bded2dbSJung-uk Kim shsigalgs += idx; 39607bded2dbSJung-uk Kim if (phash) 39617bded2dbSJung-uk Kim *phash = shsigalgs->hash_nid; 39627bded2dbSJung-uk Kim if (psign) 39637bded2dbSJung-uk Kim *psign = shsigalgs->sign_nid; 39647bded2dbSJung-uk Kim if (psignhash) 39657bded2dbSJung-uk Kim *psignhash = shsigalgs->signandhash_nid; 39667bded2dbSJung-uk Kim if (rsig) 39677bded2dbSJung-uk Kim *rsig = shsigalgs->rsign; 39687bded2dbSJung-uk Kim if (rhash) 39697bded2dbSJung-uk Kim *rhash = shsigalgs->rhash; 39707bded2dbSJung-uk Kim return s->cert->shared_sigalgslen; 39717bded2dbSJung-uk Kim } 39721f13597dSJung-uk Kim 39731f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS 39746f9291ceSJung-uk Kim int tls1_process_heartbeat(SSL *s) 39751f13597dSJung-uk Kim { 39761f13597dSJung-uk Kim unsigned char *p = &s->s3->rrec.data[0], *pl; 39771f13597dSJung-uk Kim unsigned short hbtype; 39781f13597dSJung-uk Kim unsigned int payload; 39791f13597dSJung-uk Kim unsigned int padding = 16; /* Use minimum padding */ 39801f13597dSJung-uk Kim 39811f13597dSJung-uk Kim if (s->msg_callback) 39821f13597dSJung-uk Kim s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, 39831f13597dSJung-uk Kim &s->s3->rrec.data[0], s->s3->rrec.length, 39841f13597dSJung-uk Kim s, s->msg_callback_arg); 39851f13597dSJung-uk Kim 398625bfde79SXin LI /* Read type and payload length first */ 398725bfde79SXin LI if (1 + 2 + 16 > s->s3->rrec.length) 398825bfde79SXin LI return 0; /* silently discard */ 398925bfde79SXin LI hbtype = *p++; 399025bfde79SXin LI n2s(p, payload); 399125bfde79SXin LI if (1 + 2 + payload + 16 > s->s3->rrec.length) 399225bfde79SXin LI return 0; /* silently discard per RFC 6520 sec. 4 */ 399325bfde79SXin LI pl = p; 399425bfde79SXin LI 39956f9291ceSJung-uk Kim if (hbtype == TLS1_HB_REQUEST) { 39961f13597dSJung-uk Kim unsigned char *buffer, *bp; 39971f13597dSJung-uk Kim int r; 39981f13597dSJung-uk Kim 39996f9291ceSJung-uk Kim /* 40006f9291ceSJung-uk Kim * Allocate memory for the response, size is 1 bytes message type, 40016f9291ceSJung-uk Kim * plus 2 bytes payload length, plus payload, plus padding 40021f13597dSJung-uk Kim */ 40031f13597dSJung-uk Kim buffer = OPENSSL_malloc(1 + 2 + payload + padding); 4004b8721c16SJung-uk Kim if (buffer == NULL) 4005b8721c16SJung-uk Kim return -1; 40061f13597dSJung-uk Kim bp = buffer; 40071f13597dSJung-uk Kim 40081f13597dSJung-uk Kim /* Enter response type, length and copy payload */ 40091f13597dSJung-uk Kim *bp++ = TLS1_HB_RESPONSE; 40101f13597dSJung-uk Kim s2n(payload, bp); 40111f13597dSJung-uk Kim memcpy(bp, pl, payload); 40121f13597dSJung-uk Kim bp += payload; 40131f13597dSJung-uk Kim /* Random padding */ 4014aeb5019cSJung-uk Kim if (RAND_bytes(bp, padding) <= 0) { 4015ed6b93beSJung-uk Kim OPENSSL_free(buffer); 4016ed6b93beSJung-uk Kim return -1; 4017ed6b93beSJung-uk Kim } 40181f13597dSJung-uk Kim 40196f9291ceSJung-uk Kim r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 40206f9291ceSJung-uk Kim 3 + payload + padding); 40211f13597dSJung-uk Kim 40221f13597dSJung-uk Kim if (r >= 0 && s->msg_callback) 40231f13597dSJung-uk Kim s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, 40241f13597dSJung-uk Kim buffer, 3 + payload + padding, 40251f13597dSJung-uk Kim s, s->msg_callback_arg); 40261f13597dSJung-uk Kim 40271f13597dSJung-uk Kim OPENSSL_free(buffer); 40281f13597dSJung-uk Kim 40291f13597dSJung-uk Kim if (r < 0) 40301f13597dSJung-uk Kim return r; 40316f9291ceSJung-uk Kim } else if (hbtype == TLS1_HB_RESPONSE) { 40321f13597dSJung-uk Kim unsigned int seq; 40331f13597dSJung-uk Kim 40346f9291ceSJung-uk Kim /* 40356f9291ceSJung-uk Kim * We only send sequence numbers (2 bytes unsigned int), and 16 40366f9291ceSJung-uk Kim * random bytes, so we just try to read the sequence number 40376f9291ceSJung-uk Kim */ 40381f13597dSJung-uk Kim n2s(pl, seq); 40391f13597dSJung-uk Kim 40406f9291ceSJung-uk Kim if (payload == 18 && seq == s->tlsext_hb_seq) { 40411f13597dSJung-uk Kim s->tlsext_hb_seq++; 40421f13597dSJung-uk Kim s->tlsext_hb_pending = 0; 40431f13597dSJung-uk Kim } 40441f13597dSJung-uk Kim } 40451f13597dSJung-uk Kim 4046db522d3aSSimon L. B. Nielsen return 0; 4047db522d3aSSimon L. B. Nielsen } 4048db522d3aSSimon L. B. Nielsen 40496f9291ceSJung-uk Kim int tls1_heartbeat(SSL *s) 40501f13597dSJung-uk Kim { 40511f13597dSJung-uk Kim unsigned char *buf, *p; 4052ed6b93beSJung-uk Kim int ret = -1; 40531f13597dSJung-uk Kim unsigned int payload = 18; /* Sequence number + random bytes */ 40541f13597dSJung-uk Kim unsigned int padding = 16; /* Use minimum padding */ 40551f13597dSJung-uk Kim 40561f13597dSJung-uk Kim /* Only send if peer supports and accepts HB requests... */ 40571f13597dSJung-uk Kim if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || 40586f9291ceSJung-uk Kim s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { 40591f13597dSJung-uk Kim SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); 40601f13597dSJung-uk Kim return -1; 40611f13597dSJung-uk Kim } 40621f13597dSJung-uk Kim 40631f13597dSJung-uk Kim /* ...and there is none in flight yet... */ 40646f9291ceSJung-uk Kim if (s->tlsext_hb_pending) { 40651f13597dSJung-uk Kim SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); 40661f13597dSJung-uk Kim return -1; 40671f13597dSJung-uk Kim } 40681f13597dSJung-uk Kim 40691f13597dSJung-uk Kim /* ...and no handshake in progress. */ 40706f9291ceSJung-uk Kim if (SSL_in_init(s) || s->in_handshake) { 40711f13597dSJung-uk Kim SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); 40721f13597dSJung-uk Kim return -1; 40731f13597dSJung-uk Kim } 40741f13597dSJung-uk Kim 40756f9291ceSJung-uk Kim /* 40766f9291ceSJung-uk Kim * Check if padding is too long, payload and padding must not exceed 2^14 40776f9291ceSJung-uk Kim * - 3 = 16381 bytes in total. 40781f13597dSJung-uk Kim */ 40791f13597dSJung-uk Kim OPENSSL_assert(payload + padding <= 16381); 40801f13597dSJung-uk Kim 40816f9291ceSJung-uk Kim /*- 40826f9291ceSJung-uk Kim * Create HeartBeat message, we just use a sequence number 40831f13597dSJung-uk Kim * as payload to distuingish different messages and add 40841f13597dSJung-uk Kim * some random stuff. 40851f13597dSJung-uk Kim * - Message Type, 1 byte 40861f13597dSJung-uk Kim * - Payload Length, 2 bytes (unsigned int) 40871f13597dSJung-uk Kim * - Payload, the sequence number (2 bytes uint) 40881f13597dSJung-uk Kim * - Payload, random bytes (16 bytes uint) 40891f13597dSJung-uk Kim * - Padding 40901f13597dSJung-uk Kim */ 40911f13597dSJung-uk Kim buf = OPENSSL_malloc(1 + 2 + payload + padding); 4092aeb5019cSJung-uk Kim if (buf == NULL) 4093aeb5019cSJung-uk Kim return -1; 40941f13597dSJung-uk Kim p = buf; 40951f13597dSJung-uk Kim /* Message Type */ 40961f13597dSJung-uk Kim *p++ = TLS1_HB_REQUEST; 40971f13597dSJung-uk Kim /* Payload length (18 bytes here) */ 40981f13597dSJung-uk Kim s2n(payload, p); 40991f13597dSJung-uk Kim /* Sequence number */ 41001f13597dSJung-uk Kim s2n(s->tlsext_hb_seq, p); 41011f13597dSJung-uk Kim /* 16 random bytes */ 4102aeb5019cSJung-uk Kim if (RAND_bytes(p, 16) <= 0) { 4103ed6b93beSJung-uk Kim SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); 4104ed6b93beSJung-uk Kim goto err; 4105ed6b93beSJung-uk Kim } 41061f13597dSJung-uk Kim p += 16; 41071f13597dSJung-uk Kim /* Random padding */ 4108aeb5019cSJung-uk Kim if (RAND_bytes(p, padding) <= 0) { 4109ed6b93beSJung-uk Kim SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); 4110ed6b93beSJung-uk Kim goto err; 4111ed6b93beSJung-uk Kim } 41121f13597dSJung-uk Kim 41131f13597dSJung-uk Kim ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); 41146f9291ceSJung-uk Kim if (ret >= 0) { 41151f13597dSJung-uk Kim if (s->msg_callback) 41161f13597dSJung-uk Kim s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, 41171f13597dSJung-uk Kim buf, 3 + payload + padding, 41181f13597dSJung-uk Kim s, s->msg_callback_arg); 41191f13597dSJung-uk Kim 41201f13597dSJung-uk Kim s->tlsext_hb_pending = 1; 41211f13597dSJung-uk Kim } 41221f13597dSJung-uk Kim 4123ed6b93beSJung-uk Kim err: 41241f13597dSJung-uk Kim OPENSSL_free(buf); 41251f13597dSJung-uk Kim 41261f13597dSJung-uk Kim return ret; 41271f13597dSJung-uk Kim } 4128db522d3aSSimon L. B. Nielsen # endif 41297bded2dbSJung-uk Kim 41307bded2dbSJung-uk Kim # define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) 41317bded2dbSJung-uk Kim 41327bded2dbSJung-uk Kim typedef struct { 41337bded2dbSJung-uk Kim size_t sigalgcnt; 41347bded2dbSJung-uk Kim int sigalgs[MAX_SIGALGLEN]; 41357bded2dbSJung-uk Kim } sig_cb_st; 41367bded2dbSJung-uk Kim 41377bded2dbSJung-uk Kim static int sig_cb(const char *elem, int len, void *arg) 41387bded2dbSJung-uk Kim { 41397bded2dbSJung-uk Kim sig_cb_st *sarg = arg; 41407bded2dbSJung-uk Kim size_t i; 41417bded2dbSJung-uk Kim char etmp[20], *p; 41427bded2dbSJung-uk Kim int sig_alg, hash_alg; 41437bded2dbSJung-uk Kim if (elem == NULL) 41447bded2dbSJung-uk Kim return 0; 41457bded2dbSJung-uk Kim if (sarg->sigalgcnt == MAX_SIGALGLEN) 41467bded2dbSJung-uk Kim return 0; 41477bded2dbSJung-uk Kim if (len > (int)(sizeof(etmp) - 1)) 41487bded2dbSJung-uk Kim return 0; 41497bded2dbSJung-uk Kim memcpy(etmp, elem, len); 41507bded2dbSJung-uk Kim etmp[len] = 0; 41517bded2dbSJung-uk Kim p = strchr(etmp, '+'); 41527bded2dbSJung-uk Kim if (!p) 41537bded2dbSJung-uk Kim return 0; 41547bded2dbSJung-uk Kim *p = 0; 41557bded2dbSJung-uk Kim p++; 41567bded2dbSJung-uk Kim if (!*p) 41577bded2dbSJung-uk Kim return 0; 41587bded2dbSJung-uk Kim 41597bded2dbSJung-uk Kim if (!strcmp(etmp, "RSA")) 41607bded2dbSJung-uk Kim sig_alg = EVP_PKEY_RSA; 41617bded2dbSJung-uk Kim else if (!strcmp(etmp, "DSA")) 41627bded2dbSJung-uk Kim sig_alg = EVP_PKEY_DSA; 41637bded2dbSJung-uk Kim else if (!strcmp(etmp, "ECDSA")) 41647bded2dbSJung-uk Kim sig_alg = EVP_PKEY_EC; 41657bded2dbSJung-uk Kim else 41667bded2dbSJung-uk Kim return 0; 41677bded2dbSJung-uk Kim 41687bded2dbSJung-uk Kim hash_alg = OBJ_sn2nid(p); 41697bded2dbSJung-uk Kim if (hash_alg == NID_undef) 41707bded2dbSJung-uk Kim hash_alg = OBJ_ln2nid(p); 41717bded2dbSJung-uk Kim if (hash_alg == NID_undef) 41727bded2dbSJung-uk Kim return 0; 41737bded2dbSJung-uk Kim 41747bded2dbSJung-uk Kim for (i = 0; i < sarg->sigalgcnt; i += 2) { 41757bded2dbSJung-uk Kim if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg) 41767bded2dbSJung-uk Kim return 0; 41777bded2dbSJung-uk Kim } 41787bded2dbSJung-uk Kim sarg->sigalgs[sarg->sigalgcnt++] = hash_alg; 41797bded2dbSJung-uk Kim sarg->sigalgs[sarg->sigalgcnt++] = sig_alg; 41807bded2dbSJung-uk Kim return 1; 41817bded2dbSJung-uk Kim } 41827bded2dbSJung-uk Kim 41837bded2dbSJung-uk Kim /* 41847bded2dbSJung-uk Kim * Set suppored signature algorithms based on a colon separated list of the 41857bded2dbSJung-uk Kim * form sig+hash e.g. RSA+SHA512:DSA+SHA512 41867bded2dbSJung-uk Kim */ 41877bded2dbSJung-uk Kim int tls1_set_sigalgs_list(CERT *c, const char *str, int client) 41887bded2dbSJung-uk Kim { 41897bded2dbSJung-uk Kim sig_cb_st sig; 41907bded2dbSJung-uk Kim sig.sigalgcnt = 0; 41917bded2dbSJung-uk Kim if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) 41927bded2dbSJung-uk Kim return 0; 41937bded2dbSJung-uk Kim if (c == NULL) 41947bded2dbSJung-uk Kim return 1; 41957bded2dbSJung-uk Kim return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); 41967bded2dbSJung-uk Kim } 41977bded2dbSJung-uk Kim 41987bded2dbSJung-uk Kim int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, 41997bded2dbSJung-uk Kim int client) 42007bded2dbSJung-uk Kim { 42017bded2dbSJung-uk Kim unsigned char *sigalgs, *sptr; 42027bded2dbSJung-uk Kim int rhash, rsign; 42037bded2dbSJung-uk Kim size_t i; 42047bded2dbSJung-uk Kim if (salglen & 1) 42057bded2dbSJung-uk Kim return 0; 42067bded2dbSJung-uk Kim sigalgs = OPENSSL_malloc(salglen); 42077bded2dbSJung-uk Kim if (sigalgs == NULL) 42087bded2dbSJung-uk Kim return 0; 42097bded2dbSJung-uk Kim for (i = 0, sptr = sigalgs; i < salglen; i += 2) { 42107bded2dbSJung-uk Kim rhash = tls12_find_id(*psig_nids++, tls12_md, 42117bded2dbSJung-uk Kim sizeof(tls12_md) / sizeof(tls12_lookup)); 42127bded2dbSJung-uk Kim rsign = tls12_find_id(*psig_nids++, tls12_sig, 42137bded2dbSJung-uk Kim sizeof(tls12_sig) / sizeof(tls12_lookup)); 42147bded2dbSJung-uk Kim 42157bded2dbSJung-uk Kim if (rhash == -1 || rsign == -1) 42167bded2dbSJung-uk Kim goto err; 42177bded2dbSJung-uk Kim *sptr++ = rhash; 42187bded2dbSJung-uk Kim *sptr++ = rsign; 42197bded2dbSJung-uk Kim } 42207bded2dbSJung-uk Kim 42217bded2dbSJung-uk Kim if (client) { 42227bded2dbSJung-uk Kim if (c->client_sigalgs) 42237bded2dbSJung-uk Kim OPENSSL_free(c->client_sigalgs); 42247bded2dbSJung-uk Kim c->client_sigalgs = sigalgs; 42257bded2dbSJung-uk Kim c->client_sigalgslen = salglen; 42267bded2dbSJung-uk Kim } else { 42277bded2dbSJung-uk Kim if (c->conf_sigalgs) 42287bded2dbSJung-uk Kim OPENSSL_free(c->conf_sigalgs); 42297bded2dbSJung-uk Kim c->conf_sigalgs = sigalgs; 42307bded2dbSJung-uk Kim c->conf_sigalgslen = salglen; 42317bded2dbSJung-uk Kim } 42327bded2dbSJung-uk Kim 42337bded2dbSJung-uk Kim return 1; 42347bded2dbSJung-uk Kim 42357bded2dbSJung-uk Kim err: 42367bded2dbSJung-uk Kim OPENSSL_free(sigalgs); 42377bded2dbSJung-uk Kim return 0; 42387bded2dbSJung-uk Kim } 42397bded2dbSJung-uk Kim 42407bded2dbSJung-uk Kim static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) 42417bded2dbSJung-uk Kim { 42427bded2dbSJung-uk Kim int sig_nid; 42437bded2dbSJung-uk Kim size_t i; 42447bded2dbSJung-uk Kim if (default_nid == -1) 42457bded2dbSJung-uk Kim return 1; 42467bded2dbSJung-uk Kim sig_nid = X509_get_signature_nid(x); 42477bded2dbSJung-uk Kim if (default_nid) 42487bded2dbSJung-uk Kim return sig_nid == default_nid ? 1 : 0; 42497bded2dbSJung-uk Kim for (i = 0; i < c->shared_sigalgslen; i++) 42507bded2dbSJung-uk Kim if (sig_nid == c->shared_sigalgs[i].signandhash_nid) 42517bded2dbSJung-uk Kim return 1; 42527bded2dbSJung-uk Kim return 0; 42537bded2dbSJung-uk Kim } 42547bded2dbSJung-uk Kim 42557bded2dbSJung-uk Kim /* Check to see if a certificate issuer name matches list of CA names */ 42567bded2dbSJung-uk Kim static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) 42577bded2dbSJung-uk Kim { 42587bded2dbSJung-uk Kim X509_NAME *nm; 42597bded2dbSJung-uk Kim int i; 42607bded2dbSJung-uk Kim nm = X509_get_issuer_name(x); 42617bded2dbSJung-uk Kim for (i = 0; i < sk_X509_NAME_num(names); i++) { 42627bded2dbSJung-uk Kim if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i))) 42637bded2dbSJung-uk Kim return 1; 42647bded2dbSJung-uk Kim } 42657bded2dbSJung-uk Kim return 0; 42667bded2dbSJung-uk Kim } 42677bded2dbSJung-uk Kim 42687bded2dbSJung-uk Kim /* 42697bded2dbSJung-uk Kim * Check certificate chain is consistent with TLS extensions and is usable by 42707bded2dbSJung-uk Kim * server. This servers two purposes: it allows users to check chains before 42717bded2dbSJung-uk Kim * passing them to the server and it allows the server to check chains before 42727bded2dbSJung-uk Kim * attempting to use them. 42737bded2dbSJung-uk Kim */ 42747bded2dbSJung-uk Kim 42757bded2dbSJung-uk Kim /* Flags which need to be set for a certificate when stict mode not set */ 42767bded2dbSJung-uk Kim 42777bded2dbSJung-uk Kim # define CERT_PKEY_VALID_FLAGS \ 42787bded2dbSJung-uk Kim (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM) 42797bded2dbSJung-uk Kim /* Strict mode flags */ 42807bded2dbSJung-uk Kim # define CERT_PKEY_STRICT_FLAGS \ 42817bded2dbSJung-uk Kim (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \ 42827bded2dbSJung-uk Kim | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE) 42837bded2dbSJung-uk Kim 42847bded2dbSJung-uk Kim int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, 42857bded2dbSJung-uk Kim int idx) 42867bded2dbSJung-uk Kim { 42877bded2dbSJung-uk Kim int i; 42887bded2dbSJung-uk Kim int rv = 0; 42897bded2dbSJung-uk Kim int check_flags = 0, strict_mode; 42907bded2dbSJung-uk Kim CERT_PKEY *cpk = NULL; 42917bded2dbSJung-uk Kim CERT *c = s->cert; 42927bded2dbSJung-uk Kim unsigned int suiteb_flags = tls1_suiteb(s); 42937bded2dbSJung-uk Kim /* idx == -1 means checking server chains */ 42947bded2dbSJung-uk Kim if (idx != -1) { 42957bded2dbSJung-uk Kim /* idx == -2 means checking client certificate chains */ 42967bded2dbSJung-uk Kim if (idx == -2) { 42977bded2dbSJung-uk Kim cpk = c->key; 42987bded2dbSJung-uk Kim idx = cpk - c->pkeys; 42997bded2dbSJung-uk Kim } else 43007bded2dbSJung-uk Kim cpk = c->pkeys + idx; 43017bded2dbSJung-uk Kim x = cpk->x509; 43027bded2dbSJung-uk Kim pk = cpk->privatekey; 43037bded2dbSJung-uk Kim chain = cpk->chain; 43047bded2dbSJung-uk Kim strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT; 43057bded2dbSJung-uk Kim /* If no cert or key, forget it */ 43067bded2dbSJung-uk Kim if (!x || !pk) 43077bded2dbSJung-uk Kim goto end; 43087bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL 43097bded2dbSJung-uk Kim /* Allow any certificate to pass test */ 43107bded2dbSJung-uk Kim if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { 43117bded2dbSJung-uk Kim rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN | 43127bded2dbSJung-uk Kim CERT_PKEY_VALID | CERT_PKEY_SIGN; 43137bded2dbSJung-uk Kim cpk->valid_flags = rv; 43147bded2dbSJung-uk Kim return rv; 43157bded2dbSJung-uk Kim } 43167bded2dbSJung-uk Kim # endif 43177bded2dbSJung-uk Kim } else { 43187bded2dbSJung-uk Kim if (!x || !pk) 43197bded2dbSJung-uk Kim return 0; 43207bded2dbSJung-uk Kim idx = ssl_cert_type(x, pk); 43217bded2dbSJung-uk Kim if (idx == -1) 43227bded2dbSJung-uk Kim return 0; 43237bded2dbSJung-uk Kim cpk = c->pkeys + idx; 43247bded2dbSJung-uk Kim if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) 43257bded2dbSJung-uk Kim check_flags = CERT_PKEY_STRICT_FLAGS; 43267bded2dbSJung-uk Kim else 43277bded2dbSJung-uk Kim check_flags = CERT_PKEY_VALID_FLAGS; 43287bded2dbSJung-uk Kim strict_mode = 1; 43297bded2dbSJung-uk Kim } 43307bded2dbSJung-uk Kim 43317bded2dbSJung-uk Kim if (suiteb_flags) { 43327bded2dbSJung-uk Kim int ok; 43337bded2dbSJung-uk Kim if (check_flags) 43347bded2dbSJung-uk Kim check_flags |= CERT_PKEY_SUITEB; 43357bded2dbSJung-uk Kim ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags); 43367bded2dbSJung-uk Kim if (ok == X509_V_OK) 43377bded2dbSJung-uk Kim rv |= CERT_PKEY_SUITEB; 43387bded2dbSJung-uk Kim else if (!check_flags) 43397bded2dbSJung-uk Kim goto end; 43407bded2dbSJung-uk Kim } 43417bded2dbSJung-uk Kim 43427bded2dbSJung-uk Kim /* 43437bded2dbSJung-uk Kim * Check all signature algorithms are consistent with signature 43447bded2dbSJung-uk Kim * algorithms extension if TLS 1.2 or later and strict mode. 43457bded2dbSJung-uk Kim */ 43467bded2dbSJung-uk Kim if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { 43477bded2dbSJung-uk Kim int default_nid; 43487bded2dbSJung-uk Kim unsigned char rsign = 0; 43497bded2dbSJung-uk Kim if (c->peer_sigalgs) 43507bded2dbSJung-uk Kim default_nid = 0; 43517bded2dbSJung-uk Kim /* If no sigalgs extension use defaults from RFC5246 */ 43527bded2dbSJung-uk Kim else { 43537bded2dbSJung-uk Kim switch (idx) { 43547bded2dbSJung-uk Kim case SSL_PKEY_RSA_ENC: 43557bded2dbSJung-uk Kim case SSL_PKEY_RSA_SIGN: 43567bded2dbSJung-uk Kim case SSL_PKEY_DH_RSA: 43577bded2dbSJung-uk Kim rsign = TLSEXT_signature_rsa; 43587bded2dbSJung-uk Kim default_nid = NID_sha1WithRSAEncryption; 43597bded2dbSJung-uk Kim break; 43607bded2dbSJung-uk Kim 43617bded2dbSJung-uk Kim case SSL_PKEY_DSA_SIGN: 43627bded2dbSJung-uk Kim case SSL_PKEY_DH_DSA: 43637bded2dbSJung-uk Kim rsign = TLSEXT_signature_dsa; 43647bded2dbSJung-uk Kim default_nid = NID_dsaWithSHA1; 43657bded2dbSJung-uk Kim break; 43667bded2dbSJung-uk Kim 43677bded2dbSJung-uk Kim case SSL_PKEY_ECC: 43687bded2dbSJung-uk Kim rsign = TLSEXT_signature_ecdsa; 43697bded2dbSJung-uk Kim default_nid = NID_ecdsa_with_SHA1; 43707bded2dbSJung-uk Kim break; 43717bded2dbSJung-uk Kim 43727bded2dbSJung-uk Kim default: 43737bded2dbSJung-uk Kim default_nid = -1; 43747bded2dbSJung-uk Kim break; 43757bded2dbSJung-uk Kim } 43767bded2dbSJung-uk Kim } 43777bded2dbSJung-uk Kim /* 43787bded2dbSJung-uk Kim * If peer sent no signature algorithms extension and we have set 43797bded2dbSJung-uk Kim * preferred signature algorithms check we support sha1. 43807bded2dbSJung-uk Kim */ 43817bded2dbSJung-uk Kim if (default_nid > 0 && c->conf_sigalgs) { 43827bded2dbSJung-uk Kim size_t j; 43837bded2dbSJung-uk Kim const unsigned char *p = c->conf_sigalgs; 43847bded2dbSJung-uk Kim for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) { 43857bded2dbSJung-uk Kim if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign) 43867bded2dbSJung-uk Kim break; 43877bded2dbSJung-uk Kim } 43887bded2dbSJung-uk Kim if (j == c->conf_sigalgslen) { 43897bded2dbSJung-uk Kim if (check_flags) 43907bded2dbSJung-uk Kim goto skip_sigs; 43917bded2dbSJung-uk Kim else 43927bded2dbSJung-uk Kim goto end; 43937bded2dbSJung-uk Kim } 43947bded2dbSJung-uk Kim } 43957bded2dbSJung-uk Kim /* Check signature algorithm of each cert in chain */ 43967bded2dbSJung-uk Kim if (!tls1_check_sig_alg(c, x, default_nid)) { 43977bded2dbSJung-uk Kim if (!check_flags) 43987bded2dbSJung-uk Kim goto end; 43997bded2dbSJung-uk Kim } else 44007bded2dbSJung-uk Kim rv |= CERT_PKEY_EE_SIGNATURE; 44017bded2dbSJung-uk Kim rv |= CERT_PKEY_CA_SIGNATURE; 44027bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(chain); i++) { 44037bded2dbSJung-uk Kim if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) { 44047bded2dbSJung-uk Kim if (check_flags) { 44057bded2dbSJung-uk Kim rv &= ~CERT_PKEY_CA_SIGNATURE; 44067bded2dbSJung-uk Kim break; 44077bded2dbSJung-uk Kim } else 44087bded2dbSJung-uk Kim goto end; 44097bded2dbSJung-uk Kim } 44107bded2dbSJung-uk Kim } 44117bded2dbSJung-uk Kim } 44127bded2dbSJung-uk Kim /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */ 44137bded2dbSJung-uk Kim else if (check_flags) 44147bded2dbSJung-uk Kim rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE; 44157bded2dbSJung-uk Kim skip_sigs: 44167bded2dbSJung-uk Kim /* Check cert parameters are consistent */ 44177bded2dbSJung-uk Kim if (tls1_check_cert_param(s, x, check_flags ? 1 : 2)) 44187bded2dbSJung-uk Kim rv |= CERT_PKEY_EE_PARAM; 44197bded2dbSJung-uk Kim else if (!check_flags) 44207bded2dbSJung-uk Kim goto end; 44217bded2dbSJung-uk Kim if (!s->server) 44227bded2dbSJung-uk Kim rv |= CERT_PKEY_CA_PARAM; 44237bded2dbSJung-uk Kim /* In strict mode check rest of chain too */ 44247bded2dbSJung-uk Kim else if (strict_mode) { 44257bded2dbSJung-uk Kim rv |= CERT_PKEY_CA_PARAM; 44267bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(chain); i++) { 44277bded2dbSJung-uk Kim X509 *ca = sk_X509_value(chain, i); 44287bded2dbSJung-uk Kim if (!tls1_check_cert_param(s, ca, 0)) { 44297bded2dbSJung-uk Kim if (check_flags) { 44307bded2dbSJung-uk Kim rv &= ~CERT_PKEY_CA_PARAM; 44317bded2dbSJung-uk Kim break; 44327bded2dbSJung-uk Kim } else 44337bded2dbSJung-uk Kim goto end; 44347bded2dbSJung-uk Kim } 44357bded2dbSJung-uk Kim } 44367bded2dbSJung-uk Kim } 44377bded2dbSJung-uk Kim if (!s->server && strict_mode) { 44387bded2dbSJung-uk Kim STACK_OF(X509_NAME) *ca_dn; 44397bded2dbSJung-uk Kim int check_type = 0; 44407bded2dbSJung-uk Kim switch (pk->type) { 44417bded2dbSJung-uk Kim case EVP_PKEY_RSA: 44427bded2dbSJung-uk Kim check_type = TLS_CT_RSA_SIGN; 44437bded2dbSJung-uk Kim break; 44447bded2dbSJung-uk Kim case EVP_PKEY_DSA: 44457bded2dbSJung-uk Kim check_type = TLS_CT_DSS_SIGN; 44467bded2dbSJung-uk Kim break; 44477bded2dbSJung-uk Kim case EVP_PKEY_EC: 44487bded2dbSJung-uk Kim check_type = TLS_CT_ECDSA_SIGN; 44497bded2dbSJung-uk Kim break; 44507bded2dbSJung-uk Kim case EVP_PKEY_DH: 44517bded2dbSJung-uk Kim case EVP_PKEY_DHX: 44527bded2dbSJung-uk Kim { 44537bded2dbSJung-uk Kim int cert_type = X509_certificate_type(x, pk); 44547bded2dbSJung-uk Kim if (cert_type & EVP_PKS_RSA) 44557bded2dbSJung-uk Kim check_type = TLS_CT_RSA_FIXED_DH; 44567bded2dbSJung-uk Kim if (cert_type & EVP_PKS_DSA) 44577bded2dbSJung-uk Kim check_type = TLS_CT_DSS_FIXED_DH; 44587bded2dbSJung-uk Kim } 44597bded2dbSJung-uk Kim } 44607bded2dbSJung-uk Kim if (check_type) { 44617bded2dbSJung-uk Kim const unsigned char *ctypes; 44627bded2dbSJung-uk Kim int ctypelen; 44637bded2dbSJung-uk Kim if (c->ctypes) { 44647bded2dbSJung-uk Kim ctypes = c->ctypes; 44657bded2dbSJung-uk Kim ctypelen = (int)c->ctype_num; 44667bded2dbSJung-uk Kim } else { 44677bded2dbSJung-uk Kim ctypes = (unsigned char *)s->s3->tmp.ctype; 44687bded2dbSJung-uk Kim ctypelen = s->s3->tmp.ctype_num; 44697bded2dbSJung-uk Kim } 44707bded2dbSJung-uk Kim for (i = 0; i < ctypelen; i++) { 44717bded2dbSJung-uk Kim if (ctypes[i] == check_type) { 44727bded2dbSJung-uk Kim rv |= CERT_PKEY_CERT_TYPE; 44737bded2dbSJung-uk Kim break; 44747bded2dbSJung-uk Kim } 44757bded2dbSJung-uk Kim } 44767bded2dbSJung-uk Kim if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags) 44777bded2dbSJung-uk Kim goto end; 44787bded2dbSJung-uk Kim } else 44797bded2dbSJung-uk Kim rv |= CERT_PKEY_CERT_TYPE; 44807bded2dbSJung-uk Kim 44817bded2dbSJung-uk Kim ca_dn = s->s3->tmp.ca_names; 44827bded2dbSJung-uk Kim 44837bded2dbSJung-uk Kim if (!sk_X509_NAME_num(ca_dn)) 44847bded2dbSJung-uk Kim rv |= CERT_PKEY_ISSUER_NAME; 44857bded2dbSJung-uk Kim 44867bded2dbSJung-uk Kim if (!(rv & CERT_PKEY_ISSUER_NAME)) { 44877bded2dbSJung-uk Kim if (ssl_check_ca_name(ca_dn, x)) 44887bded2dbSJung-uk Kim rv |= CERT_PKEY_ISSUER_NAME; 44897bded2dbSJung-uk Kim } 44907bded2dbSJung-uk Kim if (!(rv & CERT_PKEY_ISSUER_NAME)) { 44917bded2dbSJung-uk Kim for (i = 0; i < sk_X509_num(chain); i++) { 44927bded2dbSJung-uk Kim X509 *xtmp = sk_X509_value(chain, i); 44937bded2dbSJung-uk Kim if (ssl_check_ca_name(ca_dn, xtmp)) { 44947bded2dbSJung-uk Kim rv |= CERT_PKEY_ISSUER_NAME; 44957bded2dbSJung-uk Kim break; 44967bded2dbSJung-uk Kim } 44977bded2dbSJung-uk Kim } 44987bded2dbSJung-uk Kim } 44997bded2dbSJung-uk Kim if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME)) 45007bded2dbSJung-uk Kim goto end; 45017bded2dbSJung-uk Kim } else 45027bded2dbSJung-uk Kim rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE; 45037bded2dbSJung-uk Kim 45047bded2dbSJung-uk Kim if (!check_flags || (rv & check_flags) == check_flags) 45057bded2dbSJung-uk Kim rv |= CERT_PKEY_VALID; 45067bded2dbSJung-uk Kim 45077bded2dbSJung-uk Kim end: 45087bded2dbSJung-uk Kim 45097bded2dbSJung-uk Kim if (TLS1_get_version(s) >= TLS1_2_VERSION) { 45107bded2dbSJung-uk Kim if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN) 45117bded2dbSJung-uk Kim rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; 45127bded2dbSJung-uk Kim else if (cpk->digest) 45137bded2dbSJung-uk Kim rv |= CERT_PKEY_SIGN; 45147bded2dbSJung-uk Kim } else 45157bded2dbSJung-uk Kim rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN; 45167bded2dbSJung-uk Kim 45177bded2dbSJung-uk Kim /* 45187bded2dbSJung-uk Kim * When checking a CERT_PKEY structure all flags are irrelevant if the 45197bded2dbSJung-uk Kim * chain is invalid. 45207bded2dbSJung-uk Kim */ 45217bded2dbSJung-uk Kim if (!check_flags) { 45227bded2dbSJung-uk Kim if (rv & CERT_PKEY_VALID) 45237bded2dbSJung-uk Kim cpk->valid_flags = rv; 45247bded2dbSJung-uk Kim else { 45257bded2dbSJung-uk Kim /* Preserve explicit sign flag, clear rest */ 45267bded2dbSJung-uk Kim cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; 45277bded2dbSJung-uk Kim return 0; 45287bded2dbSJung-uk Kim } 45297bded2dbSJung-uk Kim } 45307bded2dbSJung-uk Kim return rv; 45317bded2dbSJung-uk Kim } 45327bded2dbSJung-uk Kim 45337bded2dbSJung-uk Kim /* Set validity of certificates in an SSL structure */ 45347bded2dbSJung-uk Kim void tls1_set_cert_validity(SSL *s) 45357bded2dbSJung-uk Kim { 45367bded2dbSJung-uk Kim tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC); 45377bded2dbSJung-uk Kim tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN); 45387bded2dbSJung-uk Kim tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN); 45397bded2dbSJung-uk Kim tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA); 45407bded2dbSJung-uk Kim tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA); 45417bded2dbSJung-uk Kim tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC); 45427bded2dbSJung-uk Kim } 45437bded2dbSJung-uk Kim 45447bded2dbSJung-uk Kim /* User level utiity function to check a chain is suitable */ 45457bded2dbSJung-uk Kim int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) 45467bded2dbSJung-uk Kim { 45477bded2dbSJung-uk Kim return tls1_check_chain(s, x, pk, chain, -1); 45487bded2dbSJung-uk Kim } 45497bded2dbSJung-uk Kim 45507bded2dbSJung-uk Kim #endif 4551