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