xref: /freebsd/crypto/openssl/ssl/t1_lib.c (revision 7bded2db17780f5b59bc532689d8a9541f06901e)
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>
116*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
117*7bded2dbSJung-uk Kim #ifdef OPENSSL_NO_EC2M
118*7bded2dbSJung-uk Kim # include <openssl/ec.h>
119*7bded2dbSJung-uk Kim #endif
120*7bded2dbSJung-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);
131*7bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s);
132*7bded2dbSJung-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,
148*7bded2dbSJung-uk Kim     0,
149*7bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
150*7bded2dbSJung-uk Kim     ssl3_set_handshake_header,
151*7bded2dbSJung-uk Kim     ssl3_handshake_write
152*7bded2dbSJung-uk Kim };
153*7bded2dbSJung-uk Kim 
154*7bded2dbSJung-uk Kim SSL3_ENC_METHOD TLSv1_1_enc_data = {
155*7bded2dbSJung-uk Kim     tls1_enc,
156*7bded2dbSJung-uk Kim     tls1_mac,
157*7bded2dbSJung-uk Kim     tls1_setup_key_block,
158*7bded2dbSJung-uk Kim     tls1_generate_master_secret,
159*7bded2dbSJung-uk Kim     tls1_change_cipher_state,
160*7bded2dbSJung-uk Kim     tls1_final_finish_mac,
161*7bded2dbSJung-uk Kim     TLS1_FINISH_MAC_LENGTH,
162*7bded2dbSJung-uk Kim     tls1_cert_verify_mac,
163*7bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
164*7bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
165*7bded2dbSJung-uk Kim     tls1_alert_code,
166*7bded2dbSJung-uk Kim     tls1_export_keying_material,
167*7bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV,
168*7bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
169*7bded2dbSJung-uk Kim     ssl3_set_handshake_header,
170*7bded2dbSJung-uk Kim     ssl3_handshake_write
171*7bded2dbSJung-uk Kim };
172*7bded2dbSJung-uk Kim 
173*7bded2dbSJung-uk Kim SSL3_ENC_METHOD TLSv1_2_enc_data = {
174*7bded2dbSJung-uk Kim     tls1_enc,
175*7bded2dbSJung-uk Kim     tls1_mac,
176*7bded2dbSJung-uk Kim     tls1_setup_key_block,
177*7bded2dbSJung-uk Kim     tls1_generate_master_secret,
178*7bded2dbSJung-uk Kim     tls1_change_cipher_state,
179*7bded2dbSJung-uk Kim     tls1_final_finish_mac,
180*7bded2dbSJung-uk Kim     TLS1_FINISH_MAC_LENGTH,
181*7bded2dbSJung-uk Kim     tls1_cert_verify_mac,
182*7bded2dbSJung-uk Kim     TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
183*7bded2dbSJung-uk Kim     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
184*7bded2dbSJung-uk Kim     tls1_alert_code,
185*7bded2dbSJung-uk Kim     tls1_export_keying_material,
186*7bded2dbSJung-uk Kim     SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
187*7bded2dbSJung-uk Kim         | SSL_ENC_FLAG_TLS1_2_CIPHERS,
188*7bded2dbSJung-uk Kim     SSL3_HM_HEADER_LENGTH,
189*7bded2dbSJung-uk Kim     ssl3_set_handshake_header,
190*7bded2dbSJung-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) */
253*7bded2dbSJung-uk Kim     NID_secp521r1,              /* secp521r1 (25) */
254*7bded2dbSJung-uk Kim     NID_brainpoolP256r1,        /* brainpoolP256r1 (26) */
255*7bded2dbSJung-uk Kim     NID_brainpoolP384r1,        /* brainpoolP384r1 (27) */
256*7bded2dbSJung-uk Kim     NID_brainpoolP512r1         /* brainpool512r1 (28) */
2571f13597dSJung-uk Kim };
2581f13597dSJung-uk Kim 
259*7bded2dbSJung-uk Kim static const unsigned char ecformats_default[] = {
260*7bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_uncompressed,
261*7bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
262*7bded2dbSJung-uk Kim     TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
2631f13597dSJung-uk Kim };
2641f13597dSJung-uk Kim 
265*7bded2dbSJung-uk Kim /* The client's default curves / the server's 'auto' curves. */
266*7bded2dbSJung-uk Kim static const unsigned char eccurves_auto[] = {
267*7bded2dbSJung-uk Kim     /* Prefer P-256 which has the fastest and most secure implementations. */
268*7bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
269*7bded2dbSJung-uk Kim     /* Other >= 256-bit prime curves. */
270*7bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
271*7bded2dbSJung-uk Kim     0, 28,                      /* brainpool512r1 (28) */
272*7bded2dbSJung-uk Kim     0, 27,                      /* brainpoolP384r1 (27) */
273*7bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
274*7bded2dbSJung-uk Kim     0, 26,                      /* brainpoolP256r1 (26) */
275*7bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
276*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
277*7bded2dbSJung-uk Kim     /* >= 256-bit binary curves. */
278*7bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
279*7bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
280*7bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
281*7bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
282*7bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
283*7bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
284*7bded2dbSJung-uk Kim # endif
285*7bded2dbSJung-uk Kim };
286*7bded2dbSJung-uk Kim 
287*7bded2dbSJung-uk Kim static const unsigned char eccurves_all[] = {
288*7bded2dbSJung-uk Kim     /* Prefer P-256 which has the fastest and most secure implementations. */
289*7bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
290*7bded2dbSJung-uk Kim     /* Other >= 256-bit prime curves. */
291*7bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
292*7bded2dbSJung-uk Kim     0, 28,                      /* brainpool512r1 (28) */
293*7bded2dbSJung-uk Kim     0, 27,                      /* brainpoolP384r1 (27) */
294*7bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
295*7bded2dbSJung-uk Kim     0, 26,                      /* brainpoolP256r1 (26) */
296*7bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
297*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
298*7bded2dbSJung-uk Kim     /* >= 256-bit binary curves. */
299*7bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
300*7bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
301*7bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
302*7bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
303*7bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
304*7bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
305*7bded2dbSJung-uk Kim # endif
306*7bded2dbSJung-uk Kim     /*
307*7bded2dbSJung-uk Kim      * Remaining curves disabled by default but still permitted if set
308*7bded2dbSJung-uk Kim      * via an explicit callback or parameters.
309*7bded2dbSJung-uk Kim      */
310*7bded2dbSJung-uk Kim     0, 20,                      /* secp224k1 (20) */
311*7bded2dbSJung-uk Kim     0, 21,                      /* secp224r1 (21) */
312*7bded2dbSJung-uk Kim     0, 18,                      /* secp192k1 (18) */
313*7bded2dbSJung-uk Kim     0, 19,                      /* secp192r1 (19) */
314*7bded2dbSJung-uk Kim     0, 15,                      /* secp160k1 (15) */
315*7bded2dbSJung-uk Kim     0, 16,                      /* secp160r1 (16) */
316*7bded2dbSJung-uk Kim     0, 17,                      /* secp160r2 (17) */
317*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC2M
318*7bded2dbSJung-uk Kim     0, 8,                       /* sect239k1 (8) */
319*7bded2dbSJung-uk Kim     0, 6,                       /* sect233k1 (6) */
320*7bded2dbSJung-uk Kim     0, 7,                       /* sect233r1 (7) */
321*7bded2dbSJung-uk Kim     0, 4,                       /* sect193r1 (4) */
322*7bded2dbSJung-uk Kim     0, 5,                       /* sect193r2 (5) */
323*7bded2dbSJung-uk Kim     0, 1,                       /* sect163k1 (1) */
324*7bded2dbSJung-uk Kim     0, 2,                       /* sect163r1 (2) */
325*7bded2dbSJung-uk Kim     0, 3,                       /* sect163r2 (3) */
326*7bded2dbSJung-uk Kim # endif
327*7bded2dbSJung-uk Kim };
328*7bded2dbSJung-uk Kim 
329*7bded2dbSJung-uk Kim static const unsigned char suiteb_curves[] = {
330*7bded2dbSJung-uk Kim     0, TLSEXT_curve_P_256,
331*7bded2dbSJung-uk Kim     0, TLSEXT_curve_P_384
332*7bded2dbSJung-uk Kim };
333*7bded2dbSJung-uk Kim 
334*7bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
335*7bded2dbSJung-uk Kim /* Brainpool not allowed in FIPS mode */
336*7bded2dbSJung-uk Kim static const unsigned char fips_curves_default[] = {
337*7bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
338*7bded2dbSJung-uk Kim     0, 14,                      /* sect571r1 (14) */
339*7bded2dbSJung-uk Kim     0, 13,                      /* sect571k1 (13) */
340*7bded2dbSJung-uk Kim #  endif
341*7bded2dbSJung-uk Kim     0, 25,                      /* secp521r1 (25) */
342*7bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
343*7bded2dbSJung-uk Kim     0, 11,                      /* sect409k1 (11) */
344*7bded2dbSJung-uk Kim     0, 12,                      /* sect409r1 (12) */
345*7bded2dbSJung-uk Kim #  endif
346*7bded2dbSJung-uk Kim     0, 24,                      /* secp384r1 (24) */
347*7bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
348*7bded2dbSJung-uk Kim     0, 9,                       /* sect283k1 (9) */
349*7bded2dbSJung-uk Kim     0, 10,                      /* sect283r1 (10) */
350*7bded2dbSJung-uk Kim #  endif
351*7bded2dbSJung-uk Kim     0, 22,                      /* secp256k1 (22) */
352*7bded2dbSJung-uk Kim     0, 23,                      /* secp256r1 (23) */
353*7bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
354*7bded2dbSJung-uk Kim     0, 8,                       /* sect239k1 (8) */
355*7bded2dbSJung-uk Kim     0, 6,                       /* sect233k1 (6) */
356*7bded2dbSJung-uk Kim     0, 7,                       /* sect233r1 (7) */
357*7bded2dbSJung-uk Kim #  endif
358*7bded2dbSJung-uk Kim     0, 20,                      /* secp224k1 (20) */
359*7bded2dbSJung-uk Kim     0, 21,                      /* secp224r1 (21) */
360*7bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
361*7bded2dbSJung-uk Kim     0, 4,                       /* sect193r1 (4) */
362*7bded2dbSJung-uk Kim     0, 5,                       /* sect193r2 (5) */
363*7bded2dbSJung-uk Kim #  endif
364*7bded2dbSJung-uk Kim     0, 18,                      /* secp192k1 (18) */
365*7bded2dbSJung-uk Kim     0, 19,                      /* secp192r1 (19) */
366*7bded2dbSJung-uk Kim #  ifndef OPENSSL_NO_EC2M
367*7bded2dbSJung-uk Kim     0, 1,                       /* sect163k1 (1) */
368*7bded2dbSJung-uk Kim     0, 2,                       /* sect163r1 (2) */
369*7bded2dbSJung-uk Kim     0, 3,                       /* sect163r2 (3) */
370*7bded2dbSJung-uk Kim #  endif
371*7bded2dbSJung-uk Kim     0, 15,                      /* secp160k1 (15) */
372*7bded2dbSJung-uk Kim     0, 16,                      /* secp160r1 (16) */
373*7bded2dbSJung-uk Kim     0, 17,                      /* secp160r2 (17) */
374*7bded2dbSJung-uk Kim };
375*7bded2dbSJung-uk Kim # endif
376*7bded2dbSJung-uk Kim 
3771f13597dSJung-uk Kim int tls1_ec_curve_id2nid(int curve_id)
3781f13597dSJung-uk Kim {
379*7bded2dbSJung-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 {
388*7bded2dbSJung-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;
440*7bded2dbSJung-uk Kim     case NID_brainpoolP256r1:  /* brainpoolP256r1 (26) */
441*7bded2dbSJung-uk Kim         return 26;
442*7bded2dbSJung-uk Kim     case NID_brainpoolP384r1:  /* brainpoolP384r1 (27) */
443*7bded2dbSJung-uk Kim         return 27;
444*7bded2dbSJung-uk Kim     case NID_brainpoolP512r1:  /* brainpool512r1 (28) */
445*7bded2dbSJung-uk Kim         return 28;
4461f13597dSJung-uk Kim     default:
4471f13597dSJung-uk Kim         return 0;
448f579bf8eSKris Kennaway     }
4491f13597dSJung-uk Kim }
450*7bded2dbSJung-uk Kim 
451*7bded2dbSJung-uk Kim /*
452*7bded2dbSJung-uk Kim  * Get curves list, if "sess" is set return client curves otherwise
453*7bded2dbSJung-uk Kim  * preferred list.
454*7bded2dbSJung-uk Kim  * Sets |num_curves| to the number of curves in the list, i.e.,
455*7bded2dbSJung-uk Kim  * the length of |pcurves| is 2 * num_curves.
456*7bded2dbSJung-uk Kim  * Returns 1 on success and 0 if the client curves list has invalid format.
457*7bded2dbSJung-uk Kim  * The latter indicates an internal error: we should not be accepting such
458*7bded2dbSJung-uk Kim  * lists in the first place.
459*7bded2dbSJung-uk Kim  * TODO(emilia): we should really be storing the curves list in explicitly
460*7bded2dbSJung-uk Kim  * parsed form instead. (However, this would affect binary compatibility
461*7bded2dbSJung-uk Kim  * so cannot happen in the 1.0.x series.)
462*7bded2dbSJung-uk Kim  */
463*7bded2dbSJung-uk Kim static int tls1_get_curvelist(SSL *s, int sess,
464*7bded2dbSJung-uk Kim                               const unsigned char **pcurves,
465*7bded2dbSJung-uk Kim                               size_t *num_curves)
466*7bded2dbSJung-uk Kim {
467*7bded2dbSJung-uk Kim     size_t pcurveslen = 0;
468*7bded2dbSJung-uk Kim     if (sess) {
469*7bded2dbSJung-uk Kim         *pcurves = s->session->tlsext_ellipticcurvelist;
470*7bded2dbSJung-uk Kim         pcurveslen = s->session->tlsext_ellipticcurvelist_length;
471*7bded2dbSJung-uk Kim     } else {
472*7bded2dbSJung-uk Kim         /* For Suite B mode only include P-256, P-384 */
473*7bded2dbSJung-uk Kim         switch (tls1_suiteb(s)) {
474*7bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_128_LOS:
475*7bded2dbSJung-uk Kim             *pcurves = suiteb_curves;
476*7bded2dbSJung-uk Kim             pcurveslen = sizeof(suiteb_curves);
477*7bded2dbSJung-uk Kim             break;
478*7bded2dbSJung-uk Kim 
479*7bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
480*7bded2dbSJung-uk Kim             *pcurves = suiteb_curves;
481*7bded2dbSJung-uk Kim             pcurveslen = 2;
482*7bded2dbSJung-uk Kim             break;
483*7bded2dbSJung-uk Kim 
484*7bded2dbSJung-uk Kim         case SSL_CERT_FLAG_SUITEB_192_LOS:
485*7bded2dbSJung-uk Kim             *pcurves = suiteb_curves + 2;
486*7bded2dbSJung-uk Kim             pcurveslen = 2;
487*7bded2dbSJung-uk Kim             break;
488*7bded2dbSJung-uk Kim         default:
489*7bded2dbSJung-uk Kim             *pcurves = s->tlsext_ellipticcurvelist;
490*7bded2dbSJung-uk Kim             pcurveslen = s->tlsext_ellipticcurvelist_length;
491*7bded2dbSJung-uk Kim         }
492*7bded2dbSJung-uk Kim         if (!*pcurves) {
493*7bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
494*7bded2dbSJung-uk Kim             if (FIPS_mode()) {
495*7bded2dbSJung-uk Kim                 *pcurves = fips_curves_default;
496*7bded2dbSJung-uk Kim                 pcurveslen = sizeof(fips_curves_default);
497*7bded2dbSJung-uk Kim             } else
498*7bded2dbSJung-uk Kim # endif
499*7bded2dbSJung-uk Kim             {
500*7bded2dbSJung-uk Kim                 if (!s->server || (s->cert && s->cert->ecdh_tmp_auto)) {
501*7bded2dbSJung-uk Kim                     *pcurves = eccurves_auto;
502*7bded2dbSJung-uk Kim                     pcurveslen = sizeof(eccurves_auto);
503*7bded2dbSJung-uk Kim                 } else {
504*7bded2dbSJung-uk Kim                     *pcurves = eccurves_all;
505*7bded2dbSJung-uk Kim                     pcurveslen = sizeof(eccurves_all);
506*7bded2dbSJung-uk Kim                 }
507*7bded2dbSJung-uk Kim             }
508*7bded2dbSJung-uk Kim         }
509*7bded2dbSJung-uk Kim     }
510*7bded2dbSJung-uk Kim     /* We do not allow odd length arrays to enter the system. */
511*7bded2dbSJung-uk Kim     if (pcurveslen & 1) {
512*7bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR);
513*7bded2dbSJung-uk Kim         *num_curves = 0;
514*7bded2dbSJung-uk Kim         return 0;
515*7bded2dbSJung-uk Kim     } else {
516*7bded2dbSJung-uk Kim         *num_curves = pcurveslen / 2;
517*7bded2dbSJung-uk Kim         return 1;
518*7bded2dbSJung-uk Kim     }
519*7bded2dbSJung-uk Kim }
520*7bded2dbSJung-uk Kim 
521*7bded2dbSJung-uk Kim /* Check a curve is one of our preferences */
522*7bded2dbSJung-uk Kim int tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
523*7bded2dbSJung-uk Kim {
524*7bded2dbSJung-uk Kim     const unsigned char *curves;
525*7bded2dbSJung-uk Kim     size_t num_curves, i;
526*7bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
527*7bded2dbSJung-uk Kim     if (len != 3 || p[0] != NAMED_CURVE_TYPE)
528*7bded2dbSJung-uk Kim         return 0;
529*7bded2dbSJung-uk Kim     /* Check curve matches Suite B preferences */
530*7bded2dbSJung-uk Kim     if (suiteb_flags) {
531*7bded2dbSJung-uk Kim         unsigned long cid = s->s3->tmp.new_cipher->id;
532*7bded2dbSJung-uk Kim         if (p[1])
533*7bded2dbSJung-uk Kim             return 0;
534*7bded2dbSJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) {
535*7bded2dbSJung-uk Kim             if (p[2] != TLSEXT_curve_P_256)
536*7bded2dbSJung-uk Kim                 return 0;
537*7bded2dbSJung-uk Kim         } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) {
538*7bded2dbSJung-uk Kim             if (p[2] != TLSEXT_curve_P_384)
539*7bded2dbSJung-uk Kim                 return 0;
540*7bded2dbSJung-uk Kim         } else                  /* Should never happen */
541*7bded2dbSJung-uk Kim             return 0;
542*7bded2dbSJung-uk Kim     }
543*7bded2dbSJung-uk Kim     if (!tls1_get_curvelist(s, 0, &curves, &num_curves))
544*7bded2dbSJung-uk Kim         return 0;
545*7bded2dbSJung-uk Kim     for (i = 0; i < num_curves; i++, curves += 2) {
546*7bded2dbSJung-uk Kim         if (p[1] == curves[0] && p[2] == curves[1])
547*7bded2dbSJung-uk Kim             return 1;
548*7bded2dbSJung-uk Kim     }
549*7bded2dbSJung-uk Kim     return 0;
550*7bded2dbSJung-uk Kim }
551*7bded2dbSJung-uk Kim 
552*7bded2dbSJung-uk Kim /*-
553*7bded2dbSJung-uk Kim  * Return |nmatch|th shared curve or NID_undef if there is no match.
554*7bded2dbSJung-uk Kim  * For nmatch == -1, return number of  matches
555*7bded2dbSJung-uk Kim  * For nmatch == -2, return the NID of the curve to use for
556*7bded2dbSJung-uk Kim  * an EC tmp key, or NID_undef if there is no match.
557*7bded2dbSJung-uk Kim  */
558*7bded2dbSJung-uk Kim int tls1_shared_curve(SSL *s, int nmatch)
559*7bded2dbSJung-uk Kim {
560*7bded2dbSJung-uk Kim     const unsigned char *pref, *supp;
561*7bded2dbSJung-uk Kim     size_t num_pref, num_supp, i, j;
562*7bded2dbSJung-uk Kim     int k;
563*7bded2dbSJung-uk Kim     /* Can't do anything on client side */
564*7bded2dbSJung-uk Kim     if (s->server == 0)
565*7bded2dbSJung-uk Kim         return -1;
566*7bded2dbSJung-uk Kim     if (nmatch == -2) {
567*7bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
568*7bded2dbSJung-uk Kim             /*
569*7bded2dbSJung-uk Kim              * For Suite B ciphersuite determines curve: we already know
570*7bded2dbSJung-uk Kim              * these are acceptable due to previous checks.
571*7bded2dbSJung-uk Kim              */
572*7bded2dbSJung-uk Kim             unsigned long cid = s->s3->tmp.new_cipher->id;
573*7bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
574*7bded2dbSJung-uk Kim                 return NID_X9_62_prime256v1; /* P-256 */
575*7bded2dbSJung-uk Kim             if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
576*7bded2dbSJung-uk Kim                 return NID_secp384r1; /* P-384 */
577*7bded2dbSJung-uk Kim             /* Should never happen */
578*7bded2dbSJung-uk Kim             return NID_undef;
579*7bded2dbSJung-uk Kim         }
580*7bded2dbSJung-uk Kim         /* If not Suite B just return first preference shared curve */
581*7bded2dbSJung-uk Kim         nmatch = 0;
582*7bded2dbSJung-uk Kim     }
583*7bded2dbSJung-uk Kim     /*
584*7bded2dbSJung-uk Kim      * Avoid truncation. tls1_get_curvelist takes an int
585*7bded2dbSJung-uk Kim      * but s->options is a long...
586*7bded2dbSJung-uk Kim      */
587*7bded2dbSJung-uk Kim     if (!tls1_get_curvelist
588*7bded2dbSJung-uk Kim         (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp,
589*7bded2dbSJung-uk Kim          &num_supp))
590*7bded2dbSJung-uk Kim         /* In practice, NID_undef == 0 but let's be precise. */
591*7bded2dbSJung-uk Kim         return nmatch == -1 ? 0 : NID_undef;
592*7bded2dbSJung-uk Kim     if (!tls1_get_curvelist
593*7bded2dbSJung-uk Kim         (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref,
594*7bded2dbSJung-uk Kim          &num_pref))
595*7bded2dbSJung-uk Kim         return nmatch == -1 ? 0 : NID_undef;
596*7bded2dbSJung-uk Kim 
597*7bded2dbSJung-uk Kim     /*
598*7bded2dbSJung-uk Kim      * If the client didn't send the elliptic_curves extension all of them
599*7bded2dbSJung-uk Kim      * are allowed.
600*7bded2dbSJung-uk Kim      */
601*7bded2dbSJung-uk Kim     if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) {
602*7bded2dbSJung-uk Kim         supp = eccurves_all;
603*7bded2dbSJung-uk Kim         num_supp = sizeof(eccurves_all) / 2;
604*7bded2dbSJung-uk Kim     } else if (num_pref == 0 &&
605*7bded2dbSJung-uk Kim         (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) {
606*7bded2dbSJung-uk Kim         pref = eccurves_all;
607*7bded2dbSJung-uk Kim         num_pref = sizeof(eccurves_all) / 2;
608*7bded2dbSJung-uk Kim     }
609*7bded2dbSJung-uk Kim 
610*7bded2dbSJung-uk Kim     k = 0;
611*7bded2dbSJung-uk Kim     for (i = 0; i < num_pref; i++, pref += 2) {
612*7bded2dbSJung-uk Kim         const unsigned char *tsupp = supp;
613*7bded2dbSJung-uk Kim         for (j = 0; j < num_supp; j++, tsupp += 2) {
614*7bded2dbSJung-uk Kim             if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) {
615*7bded2dbSJung-uk Kim                 if (nmatch == k) {
616*7bded2dbSJung-uk Kim                     int id = (pref[0] << 8) | pref[1];
617*7bded2dbSJung-uk Kim                     return tls1_ec_curve_id2nid(id);
618*7bded2dbSJung-uk Kim                 }
619*7bded2dbSJung-uk Kim                 k++;
620*7bded2dbSJung-uk Kim             }
621*7bded2dbSJung-uk Kim         }
622*7bded2dbSJung-uk Kim     }
623*7bded2dbSJung-uk Kim     if (nmatch == -1)
624*7bded2dbSJung-uk Kim         return k;
625*7bded2dbSJung-uk Kim     /* Out of range (nmatch > k). */
626*7bded2dbSJung-uk Kim     return NID_undef;
627*7bded2dbSJung-uk Kim }
628*7bded2dbSJung-uk Kim 
629*7bded2dbSJung-uk Kim int tls1_set_curves(unsigned char **pext, size_t *pextlen,
630*7bded2dbSJung-uk Kim                     int *curves, size_t ncurves)
631*7bded2dbSJung-uk Kim {
632*7bded2dbSJung-uk Kim     unsigned char *clist, *p;
633*7bded2dbSJung-uk Kim     size_t i;
634*7bded2dbSJung-uk Kim     /*
635*7bded2dbSJung-uk Kim      * Bitmap of curves included to detect duplicates: only works while curve
636*7bded2dbSJung-uk Kim      * ids < 32
637*7bded2dbSJung-uk Kim      */
638*7bded2dbSJung-uk Kim     unsigned long dup_list = 0;
639*7bded2dbSJung-uk Kim # ifdef OPENSSL_NO_EC2M
640*7bded2dbSJung-uk Kim     EC_GROUP *curve;
641*7bded2dbSJung-uk Kim # endif
642*7bded2dbSJung-uk Kim 
643*7bded2dbSJung-uk Kim     clist = OPENSSL_malloc(ncurves * 2);
644*7bded2dbSJung-uk Kim     if (!clist)
645*7bded2dbSJung-uk Kim         return 0;
646*7bded2dbSJung-uk Kim     for (i = 0, p = clist; i < ncurves; i++) {
647*7bded2dbSJung-uk Kim         unsigned long idmask;
648*7bded2dbSJung-uk Kim         int id;
649*7bded2dbSJung-uk Kim         id = tls1_ec_nid2curve_id(curves[i]);
650*7bded2dbSJung-uk Kim # ifdef OPENSSL_FIPS
651*7bded2dbSJung-uk Kim         /* NB: 25 is last curve ID supported by FIPS module */
652*7bded2dbSJung-uk Kim         if (FIPS_mode() && id > 25) {
653*7bded2dbSJung-uk Kim             OPENSSL_free(clist);
654*7bded2dbSJung-uk Kim             return 0;
655*7bded2dbSJung-uk Kim         }
656*7bded2dbSJung-uk Kim # endif
657*7bded2dbSJung-uk Kim # ifdef OPENSSL_NO_EC2M
658*7bded2dbSJung-uk Kim         curve = EC_GROUP_new_by_curve_name(curves[i]);
659*7bded2dbSJung-uk Kim         if (!curve || EC_METHOD_get_field_type(EC_GROUP_method_of(curve))
660*7bded2dbSJung-uk Kim             == NID_X9_62_characteristic_two_field) {
661*7bded2dbSJung-uk Kim             if (curve)
662*7bded2dbSJung-uk Kim                 EC_GROUP_free(curve);
663*7bded2dbSJung-uk Kim             OPENSSL_free(clist);
664*7bded2dbSJung-uk Kim             return 0;
665*7bded2dbSJung-uk Kim         } else
666*7bded2dbSJung-uk Kim             EC_GROUP_free(curve);
667*7bded2dbSJung-uk Kim # endif
668*7bded2dbSJung-uk Kim         idmask = 1L << id;
669*7bded2dbSJung-uk Kim         if (!id || (dup_list & idmask)) {
670*7bded2dbSJung-uk Kim             OPENSSL_free(clist);
671*7bded2dbSJung-uk Kim             return 0;
672*7bded2dbSJung-uk Kim         }
673*7bded2dbSJung-uk Kim         dup_list |= idmask;
674*7bded2dbSJung-uk Kim         s2n(id, p);
675*7bded2dbSJung-uk Kim     }
676*7bded2dbSJung-uk Kim     if (*pext)
677*7bded2dbSJung-uk Kim         OPENSSL_free(*pext);
678*7bded2dbSJung-uk Kim     *pext = clist;
679*7bded2dbSJung-uk Kim     *pextlen = ncurves * 2;
680*7bded2dbSJung-uk Kim     return 1;
681*7bded2dbSJung-uk Kim }
682*7bded2dbSJung-uk Kim 
683*7bded2dbSJung-uk Kim # define MAX_CURVELIST   28
684*7bded2dbSJung-uk Kim 
685*7bded2dbSJung-uk Kim typedef struct {
686*7bded2dbSJung-uk Kim     size_t nidcnt;
687*7bded2dbSJung-uk Kim     int nid_arr[MAX_CURVELIST];
688*7bded2dbSJung-uk Kim } nid_cb_st;
689*7bded2dbSJung-uk Kim 
690*7bded2dbSJung-uk Kim static int nid_cb(const char *elem, int len, void *arg)
691*7bded2dbSJung-uk Kim {
692*7bded2dbSJung-uk Kim     nid_cb_st *narg = arg;
693*7bded2dbSJung-uk Kim     size_t i;
694*7bded2dbSJung-uk Kim     int nid;
695*7bded2dbSJung-uk Kim     char etmp[20];
696*7bded2dbSJung-uk Kim     if (elem == NULL)
697*7bded2dbSJung-uk Kim         return 0;
698*7bded2dbSJung-uk Kim     if (narg->nidcnt == MAX_CURVELIST)
699*7bded2dbSJung-uk Kim         return 0;
700*7bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
701*7bded2dbSJung-uk Kim         return 0;
702*7bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
703*7bded2dbSJung-uk Kim     etmp[len] = 0;
704*7bded2dbSJung-uk Kim     nid = EC_curve_nist2nid(etmp);
705*7bded2dbSJung-uk Kim     if (nid == NID_undef)
706*7bded2dbSJung-uk Kim         nid = OBJ_sn2nid(etmp);
707*7bded2dbSJung-uk Kim     if (nid == NID_undef)
708*7bded2dbSJung-uk Kim         nid = OBJ_ln2nid(etmp);
709*7bded2dbSJung-uk Kim     if (nid == NID_undef)
710*7bded2dbSJung-uk Kim         return 0;
711*7bded2dbSJung-uk Kim     for (i = 0; i < narg->nidcnt; i++)
712*7bded2dbSJung-uk Kim         if (narg->nid_arr[i] == nid)
713*7bded2dbSJung-uk Kim             return 0;
714*7bded2dbSJung-uk Kim     narg->nid_arr[narg->nidcnt++] = nid;
715*7bded2dbSJung-uk Kim     return 1;
716*7bded2dbSJung-uk Kim }
717*7bded2dbSJung-uk Kim 
718*7bded2dbSJung-uk Kim /* Set curves based on a colon separate list */
719*7bded2dbSJung-uk Kim int tls1_set_curves_list(unsigned char **pext, size_t *pextlen,
720*7bded2dbSJung-uk Kim                          const char *str)
721*7bded2dbSJung-uk Kim {
722*7bded2dbSJung-uk Kim     nid_cb_st ncb;
723*7bded2dbSJung-uk Kim     ncb.nidcnt = 0;
724*7bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb))
725*7bded2dbSJung-uk Kim         return 0;
726*7bded2dbSJung-uk Kim     if (pext == NULL)
727*7bded2dbSJung-uk Kim         return 1;
728*7bded2dbSJung-uk Kim     return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt);
729*7bded2dbSJung-uk Kim }
730*7bded2dbSJung-uk Kim 
731*7bded2dbSJung-uk Kim /* For an EC key set TLS id and required compression based on parameters */
732*7bded2dbSJung-uk Kim static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id,
733*7bded2dbSJung-uk Kim                           EC_KEY *ec)
734*7bded2dbSJung-uk Kim {
735*7bded2dbSJung-uk Kim     int is_prime, id;
736*7bded2dbSJung-uk Kim     const EC_GROUP *grp;
737*7bded2dbSJung-uk Kim     const EC_METHOD *meth;
738*7bded2dbSJung-uk Kim     if (!ec)
739*7bded2dbSJung-uk Kim         return 0;
740*7bded2dbSJung-uk Kim     /* Determine if it is a prime field */
741*7bded2dbSJung-uk Kim     grp = EC_KEY_get0_group(ec);
742*7bded2dbSJung-uk Kim     if (!grp)
743*7bded2dbSJung-uk Kim         return 0;
744*7bded2dbSJung-uk Kim     meth = EC_GROUP_method_of(grp);
745*7bded2dbSJung-uk Kim     if (!meth)
746*7bded2dbSJung-uk Kim         return 0;
747*7bded2dbSJung-uk Kim     if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
748*7bded2dbSJung-uk Kim         is_prime = 1;
749*7bded2dbSJung-uk Kim     else
750*7bded2dbSJung-uk Kim         is_prime = 0;
751*7bded2dbSJung-uk Kim     /* Determine curve ID */
752*7bded2dbSJung-uk Kim     id = EC_GROUP_get_curve_name(grp);
753*7bded2dbSJung-uk Kim     id = tls1_ec_nid2curve_id(id);
754*7bded2dbSJung-uk Kim     /* If we have an ID set it, otherwise set arbitrary explicit curve */
755*7bded2dbSJung-uk Kim     if (id) {
756*7bded2dbSJung-uk Kim         curve_id[0] = 0;
757*7bded2dbSJung-uk Kim         curve_id[1] = (unsigned char)id;
758*7bded2dbSJung-uk Kim     } else {
759*7bded2dbSJung-uk Kim         curve_id[0] = 0xff;
760*7bded2dbSJung-uk Kim         if (is_prime)
761*7bded2dbSJung-uk Kim             curve_id[1] = 0x01;
762*7bded2dbSJung-uk Kim         else
763*7bded2dbSJung-uk Kim             curve_id[1] = 0x02;
764*7bded2dbSJung-uk Kim     }
765*7bded2dbSJung-uk Kim     if (comp_id) {
766*7bded2dbSJung-uk Kim         if (EC_KEY_get0_public_key(ec) == NULL)
767*7bded2dbSJung-uk Kim             return 0;
768*7bded2dbSJung-uk Kim         if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
769*7bded2dbSJung-uk Kim             if (is_prime)
770*7bded2dbSJung-uk Kim                 *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
771*7bded2dbSJung-uk Kim             else
772*7bded2dbSJung-uk Kim                 *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
773*7bded2dbSJung-uk Kim         } else
774*7bded2dbSJung-uk Kim             *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
775*7bded2dbSJung-uk Kim     }
776*7bded2dbSJung-uk Kim     return 1;
777*7bded2dbSJung-uk Kim }
778*7bded2dbSJung-uk Kim 
779*7bded2dbSJung-uk Kim /* Check an EC key is compatible with extensions */
780*7bded2dbSJung-uk Kim static int tls1_check_ec_key(SSL *s,
781*7bded2dbSJung-uk Kim                              unsigned char *curve_id, unsigned char *comp_id)
782*7bded2dbSJung-uk Kim {
783*7bded2dbSJung-uk Kim     const unsigned char *pformats, *pcurves;
784*7bded2dbSJung-uk Kim     size_t num_formats, num_curves, i;
785*7bded2dbSJung-uk Kim     int j;
786*7bded2dbSJung-uk Kim     /*
787*7bded2dbSJung-uk Kim      * If point formats extension present check it, otherwise everything is
788*7bded2dbSJung-uk Kim      * supported (see RFC4492).
789*7bded2dbSJung-uk Kim      */
790*7bded2dbSJung-uk Kim     if (comp_id && s->session->tlsext_ecpointformatlist) {
791*7bded2dbSJung-uk Kim         pformats = s->session->tlsext_ecpointformatlist;
792*7bded2dbSJung-uk Kim         num_formats = s->session->tlsext_ecpointformatlist_length;
793*7bded2dbSJung-uk Kim         for (i = 0; i < num_formats; i++, pformats++) {
794*7bded2dbSJung-uk Kim             if (*comp_id == *pformats)
795*7bded2dbSJung-uk Kim                 break;
796*7bded2dbSJung-uk Kim         }
797*7bded2dbSJung-uk Kim         if (i == num_formats)
798*7bded2dbSJung-uk Kim             return 0;
799*7bded2dbSJung-uk Kim     }
800*7bded2dbSJung-uk Kim     if (!curve_id)
801*7bded2dbSJung-uk Kim         return 1;
802*7bded2dbSJung-uk Kim     /* Check curve is consistent with client and server preferences */
803*7bded2dbSJung-uk Kim     for (j = 0; j <= 1; j++) {
804*7bded2dbSJung-uk Kim         if (!tls1_get_curvelist(s, j, &pcurves, &num_curves))
805*7bded2dbSJung-uk Kim             return 0;
806*7bded2dbSJung-uk Kim         if (j == 1 && num_curves == 0) {
807*7bded2dbSJung-uk Kim             /*
808*7bded2dbSJung-uk Kim              * If we've not received any curves then skip this check.
809*7bded2dbSJung-uk Kim              * RFC 4492 does not require the supported elliptic curves extension
810*7bded2dbSJung-uk Kim              * so if it is not sent we can just choose any curve.
811*7bded2dbSJung-uk Kim              * It is invalid to send an empty list in the elliptic curves
812*7bded2dbSJung-uk Kim              * extension, so num_curves == 0 always means no extension.
813*7bded2dbSJung-uk Kim              */
814*7bded2dbSJung-uk Kim             break;
815*7bded2dbSJung-uk Kim         }
816*7bded2dbSJung-uk Kim         for (i = 0; i < num_curves; i++, pcurves += 2) {
817*7bded2dbSJung-uk Kim             if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1])
818*7bded2dbSJung-uk Kim                 break;
819*7bded2dbSJung-uk Kim         }
820*7bded2dbSJung-uk Kim         if (i == num_curves)
821*7bded2dbSJung-uk Kim             return 0;
822*7bded2dbSJung-uk Kim         /* For clients can only check sent curve list */
823*7bded2dbSJung-uk Kim         if (!s->server)
824*7bded2dbSJung-uk Kim             return 1;
825*7bded2dbSJung-uk Kim     }
826*7bded2dbSJung-uk Kim     return 1;
827*7bded2dbSJung-uk Kim }
828*7bded2dbSJung-uk Kim 
829*7bded2dbSJung-uk Kim static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
830*7bded2dbSJung-uk Kim                                 size_t *num_formats)
831*7bded2dbSJung-uk Kim {
832*7bded2dbSJung-uk Kim     /*
833*7bded2dbSJung-uk Kim      * If we have a custom point format list use it otherwise use default
834*7bded2dbSJung-uk Kim      */
835*7bded2dbSJung-uk Kim     if (s->tlsext_ecpointformatlist) {
836*7bded2dbSJung-uk Kim         *pformats = s->tlsext_ecpointformatlist;
837*7bded2dbSJung-uk Kim         *num_formats = s->tlsext_ecpointformatlist_length;
838*7bded2dbSJung-uk Kim     } else {
839*7bded2dbSJung-uk Kim         *pformats = ecformats_default;
840*7bded2dbSJung-uk Kim         /* For Suite B we don't support char2 fields */
841*7bded2dbSJung-uk Kim         if (tls1_suiteb(s))
842*7bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default) - 1;
843*7bded2dbSJung-uk Kim         else
844*7bded2dbSJung-uk Kim             *num_formats = sizeof(ecformats_default);
845*7bded2dbSJung-uk Kim     }
846*7bded2dbSJung-uk Kim }
847*7bded2dbSJung-uk Kim 
848*7bded2dbSJung-uk Kim /*
849*7bded2dbSJung-uk Kim  * Check cert parameters compatible with extensions: currently just checks EC
850*7bded2dbSJung-uk Kim  * certificates have compatible curves and compression.
851*7bded2dbSJung-uk Kim  */
852*7bded2dbSJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
853*7bded2dbSJung-uk Kim {
854*7bded2dbSJung-uk Kim     unsigned char comp_id, curve_id[2];
855*7bded2dbSJung-uk Kim     EVP_PKEY *pkey;
856*7bded2dbSJung-uk Kim     int rv;
857*7bded2dbSJung-uk Kim     pkey = X509_get_pubkey(x);
858*7bded2dbSJung-uk Kim     if (!pkey)
859*7bded2dbSJung-uk Kim         return 0;
860*7bded2dbSJung-uk Kim     /* If not EC nothing to do */
861*7bded2dbSJung-uk Kim     if (pkey->type != EVP_PKEY_EC) {
862*7bded2dbSJung-uk Kim         EVP_PKEY_free(pkey);
863*7bded2dbSJung-uk Kim         return 1;
864*7bded2dbSJung-uk Kim     }
865*7bded2dbSJung-uk Kim     rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec);
866*7bded2dbSJung-uk Kim     EVP_PKEY_free(pkey);
867*7bded2dbSJung-uk Kim     if (!rv)
868*7bded2dbSJung-uk Kim         return 0;
869*7bded2dbSJung-uk Kim     /*
870*7bded2dbSJung-uk Kim      * Can't check curve_id for client certs as we don't have a supported
871*7bded2dbSJung-uk Kim      * curves extension.
872*7bded2dbSJung-uk Kim      */
873*7bded2dbSJung-uk Kim     rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id);
874*7bded2dbSJung-uk Kim     if (!rv)
875*7bded2dbSJung-uk Kim         return 0;
876*7bded2dbSJung-uk Kim     /*
877*7bded2dbSJung-uk Kim      * Special case for suite B. We *MUST* sign using SHA256+P-256 or
878*7bded2dbSJung-uk Kim      * SHA384+P-384, adjust digest if necessary.
879*7bded2dbSJung-uk Kim      */
880*7bded2dbSJung-uk Kim     if (set_ee_md && tls1_suiteb(s)) {
881*7bded2dbSJung-uk Kim         int check_md;
882*7bded2dbSJung-uk Kim         size_t i;
883*7bded2dbSJung-uk Kim         CERT *c = s->cert;
884*7bded2dbSJung-uk Kim         if (curve_id[0])
885*7bded2dbSJung-uk Kim             return 0;
886*7bded2dbSJung-uk Kim         /* Check to see we have necessary signing algorithm */
887*7bded2dbSJung-uk Kim         if (curve_id[1] == TLSEXT_curve_P_256)
888*7bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA256;
889*7bded2dbSJung-uk Kim         else if (curve_id[1] == TLSEXT_curve_P_384)
890*7bded2dbSJung-uk Kim             check_md = NID_ecdsa_with_SHA384;
891*7bded2dbSJung-uk Kim         else
892*7bded2dbSJung-uk Kim             return 0;           /* Should never happen */
893*7bded2dbSJung-uk Kim         for (i = 0; i < c->shared_sigalgslen; i++)
894*7bded2dbSJung-uk Kim             if (check_md == c->shared_sigalgs[i].signandhash_nid)
895*7bded2dbSJung-uk Kim                 break;
896*7bded2dbSJung-uk Kim         if (i == c->shared_sigalgslen)
897*7bded2dbSJung-uk Kim             return 0;
898*7bded2dbSJung-uk Kim         if (set_ee_md == 2) {
899*7bded2dbSJung-uk Kim             if (check_md == NID_ecdsa_with_SHA256)
900*7bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256();
901*7bded2dbSJung-uk Kim             else
902*7bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384();
903*7bded2dbSJung-uk Kim         }
904*7bded2dbSJung-uk Kim     }
905*7bded2dbSJung-uk Kim     return rv;
906*7bded2dbSJung-uk Kim }
907*7bded2dbSJung-uk Kim 
908*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDH
909*7bded2dbSJung-uk Kim /* Check EC temporary key is compatible with client extensions */
910*7bded2dbSJung-uk Kim int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
911*7bded2dbSJung-uk Kim {
912*7bded2dbSJung-uk Kim     unsigned char curve_id[2];
913*7bded2dbSJung-uk Kim     EC_KEY *ec = s->cert->ecdh_tmp;
914*7bded2dbSJung-uk Kim #  ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
915*7bded2dbSJung-uk Kim     /* Allow any curve: not just those peer supports */
916*7bded2dbSJung-uk Kim     if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
917*7bded2dbSJung-uk Kim         return 1;
918*7bded2dbSJung-uk Kim #  endif
919*7bded2dbSJung-uk Kim     /*
920*7bded2dbSJung-uk Kim      * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other
921*7bded2dbSJung-uk Kim      * curves permitted.
922*7bded2dbSJung-uk Kim      */
923*7bded2dbSJung-uk Kim     if (tls1_suiteb(s)) {
924*7bded2dbSJung-uk Kim         /* Curve to check determined by ciphersuite */
925*7bded2dbSJung-uk Kim         if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
926*7bded2dbSJung-uk Kim             curve_id[1] = TLSEXT_curve_P_256;
927*7bded2dbSJung-uk Kim         else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
928*7bded2dbSJung-uk Kim             curve_id[1] = TLSEXT_curve_P_384;
929*7bded2dbSJung-uk Kim         else
930*7bded2dbSJung-uk Kim             return 0;
931*7bded2dbSJung-uk Kim         curve_id[0] = 0;
932*7bded2dbSJung-uk Kim         /* Check this curve is acceptable */
933*7bded2dbSJung-uk Kim         if (!tls1_check_ec_key(s, curve_id, NULL))
934*7bded2dbSJung-uk Kim             return 0;
935*7bded2dbSJung-uk Kim         /* If auto or setting curve from callback assume OK */
936*7bded2dbSJung-uk Kim         if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb)
937*7bded2dbSJung-uk Kim             return 1;
938*7bded2dbSJung-uk Kim         /* Otherwise check curve is acceptable */
939*7bded2dbSJung-uk Kim         else {
940*7bded2dbSJung-uk Kim             unsigned char curve_tmp[2];
941*7bded2dbSJung-uk Kim             if (!ec)
942*7bded2dbSJung-uk Kim                 return 0;
943*7bded2dbSJung-uk Kim             if (!tls1_set_ec_id(curve_tmp, NULL, ec))
944*7bded2dbSJung-uk Kim                 return 0;
945*7bded2dbSJung-uk Kim             if (!curve_tmp[0] || curve_tmp[1] == curve_id[1])
946*7bded2dbSJung-uk Kim                 return 1;
947*7bded2dbSJung-uk Kim             return 0;
948*7bded2dbSJung-uk Kim         }
949*7bded2dbSJung-uk Kim 
950*7bded2dbSJung-uk Kim     }
951*7bded2dbSJung-uk Kim     if (s->cert->ecdh_tmp_auto) {
952*7bded2dbSJung-uk Kim         /* Need a shared curve */
953*7bded2dbSJung-uk Kim         if (tls1_shared_curve(s, 0))
954*7bded2dbSJung-uk Kim             return 1;
955*7bded2dbSJung-uk Kim         else
956*7bded2dbSJung-uk Kim             return 0;
957*7bded2dbSJung-uk Kim     }
958*7bded2dbSJung-uk Kim     if (!ec) {
959*7bded2dbSJung-uk Kim         if (s->cert->ecdh_tmp_cb)
960*7bded2dbSJung-uk Kim             return 1;
961*7bded2dbSJung-uk Kim         else
962*7bded2dbSJung-uk Kim             return 0;
963*7bded2dbSJung-uk Kim     }
964*7bded2dbSJung-uk Kim     if (!tls1_set_ec_id(curve_id, NULL, ec))
965*7bded2dbSJung-uk Kim         return 0;
966*7bded2dbSJung-uk Kim /* Set this to allow use of invalid curves for testing */
967*7bded2dbSJung-uk Kim #  if 0
968*7bded2dbSJung-uk Kim     return 1;
969*7bded2dbSJung-uk Kim #  else
970*7bded2dbSJung-uk Kim     return tls1_check_ec_key(s, curve_id, NULL);
971*7bded2dbSJung-uk Kim #  endif
972*7bded2dbSJung-uk Kim }
973*7bded2dbSJung-uk Kim # endif                         /* OPENSSL_NO_ECDH */
974*7bded2dbSJung-uk Kim 
975*7bded2dbSJung-uk Kim #else
976*7bded2dbSJung-uk Kim 
977*7bded2dbSJung-uk Kim static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
978*7bded2dbSJung-uk Kim {
979*7bded2dbSJung-uk Kim     return 1;
980*7bded2dbSJung-uk Kim }
981*7bded2dbSJung-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 
1029*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
1030*7bded2dbSJung-uk Kim static unsigned char suiteb_sigalgs[] = {
1031*7bded2dbSJung-uk Kim     tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
1032*7bded2dbSJung-uk Kim         tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
1033*7bded2dbSJung-uk Kim };
1034*7bded2dbSJung-uk Kim # endif
1035*7bded2dbSJung-uk Kim size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
10361f13597dSJung-uk Kim {
1037*7bded2dbSJung-uk Kim     /*
1038*7bded2dbSJung-uk Kim      * If Suite B mode use Suite B sigalgs only, ignore any other
1039*7bded2dbSJung-uk Kim      * preferences.
1040*7bded2dbSJung-uk Kim      */
1041*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
1042*7bded2dbSJung-uk Kim     switch (tls1_suiteb(s)) {
1043*7bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
1044*7bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
1045*7bded2dbSJung-uk Kim         return sizeof(suiteb_sigalgs);
1046*7bded2dbSJung-uk Kim 
1047*7bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
1048*7bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs;
1049*7bded2dbSJung-uk Kim         return 2;
1050*7bded2dbSJung-uk Kim 
1051*7bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
1052*7bded2dbSJung-uk Kim         *psigs = suiteb_sigalgs + 2;
1053*7bded2dbSJung-uk Kim         return 2;
1054*7bded2dbSJung-uk Kim     }
1055*7bded2dbSJung-uk Kim # endif
1056*7bded2dbSJung-uk Kim     /* If server use client authentication sigalgs if not NULL */
1057*7bded2dbSJung-uk Kim     if (s->server && s->cert->client_sigalgs) {
1058*7bded2dbSJung-uk Kim         *psigs = s->cert->client_sigalgs;
1059*7bded2dbSJung-uk Kim         return s->cert->client_sigalgslen;
1060*7bded2dbSJung-uk Kim     } else if (s->cert->conf_sigalgs) {
1061*7bded2dbSJung-uk Kim         *psigs = s->cert->conf_sigalgs;
1062*7bded2dbSJung-uk Kim         return s->cert->conf_sigalgslen;
1063*7bded2dbSJung-uk Kim     } else {
1064*7bded2dbSJung-uk Kim         *psigs = tls12_sigalgs;
1065*7bded2dbSJung-uk Kim         return sizeof(tls12_sigalgs);
1066*7bded2dbSJung-uk Kim     }
1067*7bded2dbSJung-uk Kim }
1068*7bded2dbSJung-uk Kim 
1069*7bded2dbSJung-uk Kim /*
1070*7bded2dbSJung-uk Kim  * Check signature algorithm is consistent with sent supported signature
1071*7bded2dbSJung-uk Kim  * algorithms and if so return relevant digest.
1072*7bded2dbSJung-uk Kim  */
1073*7bded2dbSJung-uk Kim int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
1074*7bded2dbSJung-uk Kim                             const unsigned char *sig, EVP_PKEY *pkey)
1075*7bded2dbSJung-uk Kim {
1076*7bded2dbSJung-uk Kim     const unsigned char *sent_sigs;
1077*7bded2dbSJung-uk Kim     size_t sent_sigslen, i;
1078*7bded2dbSJung-uk Kim     int sigalg = tls12_get_sigid(pkey);
1079*7bded2dbSJung-uk Kim     /* Should never happen */
1080*7bded2dbSJung-uk Kim     if (sigalg == -1)
1081*7bded2dbSJung-uk Kim         return -1;
1082*7bded2dbSJung-uk Kim     /* Check key type is consistent with signature */
1083*7bded2dbSJung-uk Kim     if (sigalg != (int)sig[1]) {
1084*7bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
1085*7bded2dbSJung-uk Kim         return 0;
1086*7bded2dbSJung-uk Kim     }
1087*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
1088*7bded2dbSJung-uk Kim     if (pkey->type == EVP_PKEY_EC) {
1089*7bded2dbSJung-uk Kim         unsigned char curve_id[2], comp_id;
1090*7bded2dbSJung-uk Kim         /* Check compression and curve matches extensions */
1091*7bded2dbSJung-uk Kim         if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec))
1092*7bded2dbSJung-uk Kim             return 0;
1093*7bded2dbSJung-uk Kim         if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
1094*7bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
1095*7bded2dbSJung-uk Kim             return 0;
1096*7bded2dbSJung-uk Kim         }
1097*7bded2dbSJung-uk Kim         /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
1098*7bded2dbSJung-uk Kim         if (tls1_suiteb(s)) {
1099*7bded2dbSJung-uk Kim             if (curve_id[0])
1100*7bded2dbSJung-uk Kim                 return 0;
1101*7bded2dbSJung-uk Kim             if (curve_id[1] == TLSEXT_curve_P_256) {
1102*7bded2dbSJung-uk Kim                 if (sig[0] != TLSEXT_hash_sha256) {
1103*7bded2dbSJung-uk Kim                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
1104*7bded2dbSJung-uk Kim                            SSL_R_ILLEGAL_SUITEB_DIGEST);
1105*7bded2dbSJung-uk Kim                     return 0;
1106*7bded2dbSJung-uk Kim                 }
1107*7bded2dbSJung-uk Kim             } else if (curve_id[1] == TLSEXT_curve_P_384) {
1108*7bded2dbSJung-uk Kim                 if (sig[0] != TLSEXT_hash_sha384) {
1109*7bded2dbSJung-uk Kim                     SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
1110*7bded2dbSJung-uk Kim                            SSL_R_ILLEGAL_SUITEB_DIGEST);
1111*7bded2dbSJung-uk Kim                     return 0;
1112*7bded2dbSJung-uk Kim                 }
1113*7bded2dbSJung-uk Kim             } else
1114*7bded2dbSJung-uk Kim                 return 0;
1115*7bded2dbSJung-uk Kim         }
1116*7bded2dbSJung-uk Kim     } else if (tls1_suiteb(s))
1117*7bded2dbSJung-uk Kim         return 0;
1118*7bded2dbSJung-uk Kim # endif
1119*7bded2dbSJung-uk Kim 
1120*7bded2dbSJung-uk Kim     /* Check signature matches a type we sent */
1121*7bded2dbSJung-uk Kim     sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
1122*7bded2dbSJung-uk Kim     for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
1123*7bded2dbSJung-uk Kim         if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1])
1124*7bded2dbSJung-uk Kim             break;
1125*7bded2dbSJung-uk Kim     }
1126*7bded2dbSJung-uk Kim     /* Allow fallback to SHA1 if not strict mode */
1127*7bded2dbSJung-uk Kim     if (i == sent_sigslen
1128*7bded2dbSJung-uk Kim         && (sig[0] != TLSEXT_hash_sha1
1129*7bded2dbSJung-uk Kim             || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
1130*7bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
1131*7bded2dbSJung-uk Kim         return 0;
1132*7bded2dbSJung-uk Kim     }
1133*7bded2dbSJung-uk Kim     *pmd = tls12_get_hash(sig[0]);
1134*7bded2dbSJung-uk Kim     if (*pmd == NULL) {
1135*7bded2dbSJung-uk Kim         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
1136*7bded2dbSJung-uk Kim         return 0;
1137*7bded2dbSJung-uk Kim     }
1138*7bded2dbSJung-uk Kim     /*
1139*7bded2dbSJung-uk Kim      * Store the digest used so applications can retrieve it if they wish.
1140*7bded2dbSJung-uk Kim      */
1141*7bded2dbSJung-uk Kim     if (s->session && s->session->sess_cert)
1142*7bded2dbSJung-uk Kim         s->session->sess_cert->peer_key->digest = *pmd;
1143*7bded2dbSJung-uk Kim     return 1;
1144*7bded2dbSJung-uk Kim }
1145*7bded2dbSJung-uk Kim 
1146*7bded2dbSJung-uk Kim /*
1147*7bded2dbSJung-uk Kim  * Get a mask of disabled algorithms: an algorithm is disabled if it isn't
1148*7bded2dbSJung-uk Kim  * supported or doesn't appear in supported signature algorithms. Unlike
1149*7bded2dbSJung-uk Kim  * ssl_cipher_get_disabled this applies to a specific session and not global
1150*7bded2dbSJung-uk Kim  * settings.
1151*7bded2dbSJung-uk Kim  */
1152*7bded2dbSJung-uk Kim void ssl_set_client_disabled(SSL *s)
1153*7bded2dbSJung-uk Kim {
1154*7bded2dbSJung-uk Kim     CERT *c = s->cert;
1155*7bded2dbSJung-uk Kim     const unsigned char *sigalgs;
1156*7bded2dbSJung-uk Kim     size_t i, sigalgslen;
1157*7bded2dbSJung-uk Kim     int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
1158*7bded2dbSJung-uk Kim     c->mask_a = 0;
1159*7bded2dbSJung-uk Kim     c->mask_k = 0;
1160*7bded2dbSJung-uk Kim     /* Don't allow TLS 1.2 only ciphers if we don't suppport them */
1161*7bded2dbSJung-uk Kim     if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s))
1162*7bded2dbSJung-uk Kim         c->mask_ssl = SSL_TLSV1_2;
1163*7bded2dbSJung-uk Kim     else
1164*7bded2dbSJung-uk Kim         c->mask_ssl = 0;
1165*7bded2dbSJung-uk Kim     /*
1166*7bded2dbSJung-uk Kim      * Now go through all signature algorithms seeing if we support any for
1167*7bded2dbSJung-uk Kim      * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2.
1168*7bded2dbSJung-uk Kim      */
1169*7bded2dbSJung-uk Kim     sigalgslen = tls12_get_psigalgs(s, &sigalgs);
1170*7bded2dbSJung-uk Kim     for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
1171*7bded2dbSJung-uk Kim         switch (sigalgs[1]) {
1172*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA
1173*7bded2dbSJung-uk Kim         case TLSEXT_signature_rsa:
1174*7bded2dbSJung-uk Kim             have_rsa = 1;
1175*7bded2dbSJung-uk Kim             break;
1176*7bded2dbSJung-uk Kim # endif
1177*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA
1178*7bded2dbSJung-uk Kim         case TLSEXT_signature_dsa:
1179*7bded2dbSJung-uk Kim             have_dsa = 1;
1180*7bded2dbSJung-uk Kim             break;
1181*7bded2dbSJung-uk Kim # endif
1182*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
1183*7bded2dbSJung-uk Kim         case TLSEXT_signature_ecdsa:
1184*7bded2dbSJung-uk Kim             have_ecdsa = 1;
1185*7bded2dbSJung-uk Kim             break;
1186*7bded2dbSJung-uk Kim # endif
1187*7bded2dbSJung-uk Kim         }
1188*7bded2dbSJung-uk Kim     }
1189*7bded2dbSJung-uk Kim     /*
1190*7bded2dbSJung-uk Kim      * Disable auth and static DH if we don't include any appropriate
1191*7bded2dbSJung-uk Kim      * signature algorithms.
1192*7bded2dbSJung-uk Kim      */
1193*7bded2dbSJung-uk Kim     if (!have_rsa) {
1194*7bded2dbSJung-uk Kim         c->mask_a |= SSL_aRSA;
1195*7bded2dbSJung-uk Kim         c->mask_k |= SSL_kDHr | SSL_kECDHr;
1196*7bded2dbSJung-uk Kim     }
1197*7bded2dbSJung-uk Kim     if (!have_dsa) {
1198*7bded2dbSJung-uk Kim         c->mask_a |= SSL_aDSS;
1199*7bded2dbSJung-uk Kim         c->mask_k |= SSL_kDHd;
1200*7bded2dbSJung-uk Kim     }
1201*7bded2dbSJung-uk Kim     if (!have_ecdsa) {
1202*7bded2dbSJung-uk Kim         c->mask_a |= SSL_aECDSA;
1203*7bded2dbSJung-uk Kim         c->mask_k |= SSL_kECDHe;
1204*7bded2dbSJung-uk Kim     }
1205*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_KRB5
1206*7bded2dbSJung-uk Kim     if (!kssl_tgt_is_available(s->kssl_ctx)) {
1207*7bded2dbSJung-uk Kim         c->mask_a |= SSL_aKRB5;
1208*7bded2dbSJung-uk Kim         c->mask_k |= SSL_kKRB5;
1209*7bded2dbSJung-uk Kim     }
1210*7bded2dbSJung-uk Kim # endif
1211*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_PSK
1212*7bded2dbSJung-uk Kim     /* with PSK there must be client callback set */
1213*7bded2dbSJung-uk Kim     if (!s->psk_client_callback) {
1214*7bded2dbSJung-uk Kim         c->mask_a |= SSL_aPSK;
1215*7bded2dbSJung-uk Kim         c->mask_k |= SSL_kPSK;
1216*7bded2dbSJung-uk Kim     }
1217*7bded2dbSJung-uk Kim # endif                         /* OPENSSL_NO_PSK */
1218*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_SRP
1219*7bded2dbSJung-uk Kim     if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
1220*7bded2dbSJung-uk Kim         c->mask_a |= SSL_aSRP;
1221*7bded2dbSJung-uk Kim         c->mask_k |= SSL_kSRP;
1222*7bded2dbSJung-uk Kim     }
1223*7bded2dbSJung-uk Kim # endif
1224*7bded2dbSJung-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,
1228*7bded2dbSJung-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;
1233*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
1234*7bded2dbSJung-uk Kim     /* See if we support any ECC ciphersuites */
1235*7bded2dbSJung-uk Kim     int using_ecc = 0;
1236*7bded2dbSJung-uk Kim     if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
1237*7bded2dbSJung-uk Kim         int i;
1238*7bded2dbSJung-uk Kim         unsigned long alg_k, alg_a;
1239*7bded2dbSJung-uk Kim         STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
1240*7bded2dbSJung-uk Kim 
1241*7bded2dbSJung-uk Kim         for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
1242*7bded2dbSJung-uk Kim             SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
1243*7bded2dbSJung-uk Kim 
1244*7bded2dbSJung-uk Kim             alg_k = c->algorithm_mkey;
1245*7bded2dbSJung-uk Kim             alg_a = c->algorithm_auth;
1246*7bded2dbSJung-uk Kim             if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)
1247*7bded2dbSJung-uk Kim                  || (alg_a & SSL_aECDSA))) {
1248*7bded2dbSJung-uk Kim                 using_ecc = 1;
1249*7bded2dbSJung-uk Kim                 break;
1250*7bded2dbSJung-uk Kim             }
1251*7bded2dbSJung-uk Kim         }
1252*7bded2dbSJung-uk Kim     }
1253*7bded2dbSJung-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
1349*7bded2dbSJung-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;
1354*7bded2dbSJung-uk Kim         const unsigned char *pcurves, *pformats;
1355*7bded2dbSJung-uk Kim         size_t num_curves, num_formats, curves_list_len;
1356*7bded2dbSJung-uk Kim 
1357*7bded2dbSJung-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;
1361*7bded2dbSJung-uk Kim         if (num_formats > (size_t)lenmax)
13626f9291ceSJung-uk Kim             return NULL;
1363*7bded2dbSJung-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);
1369*7bded2dbSJung-uk Kim         /* The point format list has 1-byte length. */
1370*7bded2dbSJung-uk Kim         s2n(num_formats + 1, ret);
1371*7bded2dbSJung-uk Kim         *(ret++) = (unsigned char)num_formats;
1372*7bded2dbSJung-uk Kim         memcpy(ret, pformats, num_formats);
1373*7bded2dbSJung-uk Kim         ret += num_formats;
1374*7bded2dbSJung-uk Kim 
13756f9291ceSJung-uk Kim         /*
13766f9291ceSJung-uk Kim          * Add TLS extension EllipticCurves to the ClientHello message
13776f9291ceSJung-uk Kim          */
1378*7bded2dbSJung-uk Kim         pcurves = s->tlsext_ellipticcurvelist;
1379*7bded2dbSJung-uk Kim         if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
1380*7bded2dbSJung-uk Kim             return NULL;
13811f13597dSJung-uk Kim 
13826f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 6) < 0)
13836f9291ceSJung-uk Kim             return NULL;
1384*7bded2dbSJung-uk Kim         if (num_curves > (size_t)lenmax / 2)
13856f9291ceSJung-uk Kim             return NULL;
1386*7bded2dbSJung-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         }
1390*7bded2dbSJung-uk Kim         curves_list_len = 2 * num_curves;
13911f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_elliptic_curves, ret);
1392*7bded2dbSJung-uk Kim         s2n(curves_list_len + 2, ret);
1393*7bded2dbSJung-uk Kim         s2n(curves_list_len, ret);
1394*7bded2dbSJung-uk Kim         memcpy(ret, pcurves, curves_list_len);
1395*7bded2dbSJung-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*7bded2dbSJung-uk Kim     if (SSL_USE_SIGALGS(s)) {
1433*7bded2dbSJung-uk Kim         size_t salglen;
1434*7bded2dbSJung-uk Kim         const unsigned char *salg;
1435*7bded2dbSJung-uk Kim         salglen = tls12_get_psigalgs(s, &salg);
1436*7bded2dbSJung-uk Kim         if ((size_t)(limit - ret) < salglen + 6)
14371f13597dSJung-uk Kim             return NULL;
14381f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_signature_algorithms, ret);
1439*7bded2dbSJung-uk Kim         s2n(salglen + 2, ret);
1440*7bded2dbSJung-uk Kim         s2n(salglen, ret);
1441*7bded2dbSJung-uk Kim         memcpy(ret, salg, salglen);
1442*7bded2dbSJung-uk Kim         ret += salglen;
14431f13597dSJung-uk Kim     }
14441f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
1445*7bded2dbSJung-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 
1461*7bded2dbSJung-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 
1534*7bded2dbSJung-uk Kim     if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
1535*7bded2dbSJung-uk Kim         if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
1536*7bded2dbSJung-uk Kim             return NULL;
1537*7bded2dbSJung-uk Kim         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
1538*7bded2dbSJung-uk Kim         s2n(2 + s->alpn_client_proto_list_len, ret);
1539*7bded2dbSJung-uk Kim         s2n(s->alpn_client_proto_list_len, ret);
1540*7bded2dbSJung-uk Kim         memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
1541*7bded2dbSJung-uk Kim         ret += s->alpn_client_proto_list_len;
1542*7bded2dbSJung-uk Kim     }
154309286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
15446f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
15451f13597dSJung-uk Kim         int el;
15461f13597dSJung-uk Kim 
15471f13597dSJung-uk Kim         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
15481f13597dSJung-uk Kim 
15496f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
15506f9291ceSJung-uk Kim             return NULL;
15511f13597dSJung-uk Kim 
15521f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
15531f13597dSJung-uk Kim         s2n(el, ret);
15541f13597dSJung-uk Kim 
15556f9291ceSJung-uk Kim         if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
15561f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
15571f13597dSJung-uk Kim             return NULL;
15581f13597dSJung-uk Kim         }
15591f13597dSJung-uk Kim         ret += el;
15601f13597dSJung-uk Kim     }
156109286989SJung-uk Kim # endif
1562*7bded2dbSJung-uk Kim     custom_ext_init(&s->cert->cli_ext);
1563*7bded2dbSJung-uk Kim     /* Add custom TLS Extensions to ClientHello */
1564*7bded2dbSJung-uk Kim     if (!custom_ext_add(s, 0, &ret, limit, al))
1565*7bded2dbSJung-uk Kim         return NULL;
1566*7bded2dbSJung-uk Kim 
15676f9291ceSJung-uk Kim     /*
15686f9291ceSJung-uk Kim      * Add padding to workaround bugs in F5 terminators. See
15696f9291ceSJung-uk Kim      * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
15706f9291ceSJung-uk Kim      * code works out the length of all existing extensions it MUST always
15716f9291ceSJung-uk Kim      * appear last.
1572560ede85SJung-uk Kim      */
15736f9291ceSJung-uk Kim     if (s->options & SSL_OP_TLSEXT_PADDING) {
1574560ede85SJung-uk Kim         int hlen = ret - (unsigned char *)s->init_buf->data;
15756f9291ceSJung-uk Kim         /*
15766f9291ceSJung-uk Kim          * The code in s23_clnt.c to build ClientHello messages includes the
15776f9291ceSJung-uk Kim          * 5-byte record header in the buffer, while the code in s3_clnt.c
15786f9291ceSJung-uk Kim          * does not.
157994ad176cSJung-uk Kim          */
1580560ede85SJung-uk Kim         if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
1581560ede85SJung-uk Kim             hlen -= 5;
15826f9291ceSJung-uk Kim         if (hlen > 0xff && hlen < 0x200) {
1583560ede85SJung-uk Kim             hlen = 0x200 - hlen;
1584560ede85SJung-uk Kim             if (hlen >= 4)
1585560ede85SJung-uk Kim                 hlen -= 4;
1586560ede85SJung-uk Kim             else
1587560ede85SJung-uk Kim                 hlen = 0;
1588560ede85SJung-uk Kim 
1589560ede85SJung-uk Kim             s2n(TLSEXT_TYPE_padding, ret);
1590560ede85SJung-uk Kim             s2n(hlen, ret);
1591560ede85SJung-uk Kim             memset(ret, 0, hlen);
1592560ede85SJung-uk Kim             ret += hlen;
1593560ede85SJung-uk Kim         }
1594560ede85SJung-uk Kim     }
1595560ede85SJung-uk Kim 
1596a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
1597a93cbc2bSJung-uk Kim         return orig;
1598db522d3aSSimon L. B. Nielsen 
1599a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
1600db522d3aSSimon L. B. Nielsen     return ret;
1601db522d3aSSimon L. B. Nielsen }
1602db522d3aSSimon L. B. Nielsen 
16036f9291ceSJung-uk Kim unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
1604*7bded2dbSJung-uk Kim                                           unsigned char *limit, int *al)
1605db522d3aSSimon L. B. Nielsen {
1606db522d3aSSimon L. B. Nielsen     int extdatalen = 0;
1607a93cbc2bSJung-uk Kim     unsigned char *orig = buf;
1608a93cbc2bSJung-uk Kim     unsigned char *ret = buf;
16091f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
16101f13597dSJung-uk Kim     int next_proto_neg_seen;
16111f13597dSJung-uk Kim # endif
1612*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_EC
1613*7bded2dbSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
1614*7bded2dbSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
1615*7bded2dbSJung-uk Kim     int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
1616*7bded2dbSJung-uk Kim         || (alg_a & SSL_aECDSA);
1617*7bded2dbSJung-uk Kim     using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
1618*7bded2dbSJung-uk Kim # endif
16196f9291ceSJung-uk Kim     /*
16206f9291ceSJung-uk Kim      * don't add extensions for SSLv3, unless doing secure renegotiation
16216f9291ceSJung-uk Kim      */
16226a599222SSimon L. B. Nielsen     if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
1623a93cbc2bSJung-uk Kim         return orig;
16246a599222SSimon L. B. Nielsen 
1625db522d3aSSimon L. B. Nielsen     ret += 2;
16266f9291ceSJung-uk Kim     if (ret >= limit)
16276f9291ceSJung-uk Kim         return NULL;            /* this really never occurs, but ... */
1628db522d3aSSimon L. B. Nielsen 
16296f9291ceSJung-uk Kim     if (!s->hit && s->servername_done == 1
16306f9291ceSJung-uk Kim         && s->session->tlsext_hostname != NULL) {
16316f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
16326f9291ceSJung-uk Kim             return NULL;
1633db522d3aSSimon L. B. Nielsen 
1634db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_server_name, ret);
1635db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1636db522d3aSSimon L. B. Nielsen     }
1637db522d3aSSimon L. B. Nielsen 
16386f9291ceSJung-uk Kim     if (s->s3->send_connection_binding) {
16396a599222SSimon L. B. Nielsen         int el;
16406a599222SSimon L. B. Nielsen 
16416f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
16426a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16436a599222SSimon L. B. Nielsen             return NULL;
16446a599222SSimon L. B. Nielsen         }
16456a599222SSimon L. B. Nielsen 
16466f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
16476f9291ceSJung-uk Kim             return NULL;
16486a599222SSimon L. B. Nielsen 
16496a599222SSimon L. B. Nielsen         s2n(TLSEXT_TYPE_renegotiate, ret);
16506a599222SSimon L. B. Nielsen         s2n(el, ret);
16516a599222SSimon L. B. Nielsen 
16526f9291ceSJung-uk Kim         if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
16536a599222SSimon L. B. Nielsen             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16546a599222SSimon L. B. Nielsen             return NULL;
16556a599222SSimon L. B. Nielsen         }
16566a599222SSimon L. B. Nielsen 
16576a599222SSimon L. B. Nielsen         ret += el;
16586a599222SSimon L. B. Nielsen     }
16591f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
1660*7bded2dbSJung-uk Kim     if (using_ecc) {
1661*7bded2dbSJung-uk Kim         const unsigned char *plist;
1662*7bded2dbSJung-uk Kim         size_t plistlen;
16636f9291ceSJung-uk Kim         /*
16646f9291ceSJung-uk Kim          * Add TLS extension ECPointFormats to the ServerHello message
16656f9291ceSJung-uk Kim          */
16661f13597dSJung-uk Kim         long lenmax;
16671f13597dSJung-uk Kim 
1668*7bded2dbSJung-uk Kim         tls1_get_formatlist(s, &plist, &plistlen);
1669*7bded2dbSJung-uk Kim 
16706f9291ceSJung-uk Kim         if ((lenmax = limit - ret - 5) < 0)
16716f9291ceSJung-uk Kim             return NULL;
1672*7bded2dbSJung-uk Kim         if (plistlen > (size_t)lenmax)
16736f9291ceSJung-uk Kim             return NULL;
1674*7bded2dbSJung-uk Kim         if (plistlen > 255) {
16751f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
16761f13597dSJung-uk Kim             return NULL;
16771f13597dSJung-uk Kim         }
16781f13597dSJung-uk Kim 
16791f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_ec_point_formats, ret);
1680*7bded2dbSJung-uk Kim         s2n(plistlen + 1, ret);
1681*7bded2dbSJung-uk Kim         *(ret++) = (unsigned char)plistlen;
1682*7bded2dbSJung-uk Kim         memcpy(ret, plist, plistlen);
1683*7bded2dbSJung-uk Kim         ret += plistlen;
16841f13597dSJung-uk Kim 
16851f13597dSJung-uk Kim     }
16866f9291ceSJung-uk Kim     /*
16876f9291ceSJung-uk Kim      * Currently the server should not respond with a SupportedCurves
16886f9291ceSJung-uk Kim      * extension
16896f9291ceSJung-uk Kim      */
16901f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
16911f13597dSJung-uk Kim 
16926f9291ceSJung-uk Kim     if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
16936f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
16946f9291ceSJung-uk Kim             return NULL;
1695db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_session_ticket, ret);
1696db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1697db522d3aSSimon L. B. Nielsen     }
1698db522d3aSSimon L. B. Nielsen 
16996f9291ceSJung-uk Kim     if (s->tlsext_status_expected) {
17006f9291ceSJung-uk Kim         if ((long)(limit - ret - 4) < 0)
17016f9291ceSJung-uk Kim             return NULL;
1702db522d3aSSimon L. B. Nielsen         s2n(TLSEXT_TYPE_status_request, ret);
1703db522d3aSSimon L. B. Nielsen         s2n(0, ret);
1704db522d3aSSimon L. B. Nielsen     }
17051f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
1706*7bded2dbSJung-uk Kim     if (s->s3->server_opaque_prf_input != NULL) {
17071f13597dSJung-uk Kim         size_t sol = s->s3->server_opaque_prf_input_len;
17081f13597dSJung-uk Kim 
17091f13597dSJung-uk Kim         if ((long)(limit - ret - 6 - sol) < 0)
17101f13597dSJung-uk Kim             return NULL;
17111f13597dSJung-uk Kim         if (sol > 0xFFFD)       /* can't happen */
17121f13597dSJung-uk Kim             return NULL;
17131f13597dSJung-uk Kim 
17141f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_opaque_prf_input, ret);
17151f13597dSJung-uk Kim         s2n(sol + 2, ret);
17161f13597dSJung-uk Kim         s2n(sol, ret);
17171f13597dSJung-uk Kim         memcpy(ret, s->s3->server_opaque_prf_input, sol);
17181f13597dSJung-uk Kim         ret += sol;
17191f13597dSJung-uk Kim     }
17201f13597dSJung-uk Kim # endif
17211f13597dSJung-uk Kim 
172209286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
17236f9291ceSJung-uk Kim     if (SSL_IS_DTLS(s) && s->srtp_profile) {
17241f13597dSJung-uk Kim         int el;
17251f13597dSJung-uk Kim 
17261f13597dSJung-uk Kim         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
17271f13597dSJung-uk Kim 
17286f9291ceSJung-uk Kim         if ((limit - ret - 4 - el) < 0)
17296f9291ceSJung-uk Kim             return NULL;
17301f13597dSJung-uk Kim 
17311f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_use_srtp, ret);
17321f13597dSJung-uk Kim         s2n(el, ret);
17331f13597dSJung-uk Kim 
17346f9291ceSJung-uk Kim         if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
17351f13597dSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
17361f13597dSJung-uk Kim             return NULL;
17371f13597dSJung-uk Kim         }
17381f13597dSJung-uk Kim         ret += el;
17391f13597dSJung-uk Kim     }
174009286989SJung-uk Kim # endif
17411f13597dSJung-uk Kim 
17426f9291ceSJung-uk Kim     if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
17436f9291ceSJung-uk Kim          || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
17446f9291ceSJung-uk Kim         && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
17456f9291ceSJung-uk Kim         const unsigned char cryptopro_ext[36] = {
17461f13597dSJung-uk Kim             0xfd, 0xe8,         /* 65000 */
17471f13597dSJung-uk Kim             0x00, 0x20,         /* 32 bytes length */
17481f13597dSJung-uk Kim             0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
17491f13597dSJung-uk Kim             0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
17501f13597dSJung-uk Kim             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
17516f9291ceSJung-uk Kim             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
17526f9291ceSJung-uk Kim         };
17536f9291ceSJung-uk Kim         if (limit - ret < 36)
17546f9291ceSJung-uk Kim             return NULL;
17551f13597dSJung-uk Kim         memcpy(ret, cryptopro_ext, 36);
17561f13597dSJung-uk Kim         ret += 36;
17571f13597dSJung-uk Kim 
17581f13597dSJung-uk Kim     }
17591f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
17601f13597dSJung-uk Kim     /* Add Heartbeat extension if we've received one */
17616f9291ceSJung-uk Kim     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
176294ad176cSJung-uk Kim         if ((limit - ret - 4 - 1) < 0)
176394ad176cSJung-uk Kim             return NULL;
17641f13597dSJung-uk Kim         s2n(TLSEXT_TYPE_heartbeat, ret);
17651f13597dSJung-uk Kim         s2n(1, ret);
17666f9291ceSJung-uk Kim         /*-
17676f9291ceSJung-uk Kim          * Set mode:
17681f13597dSJung-uk Kim          * 1: peer may send requests
17691f13597dSJung-uk Kim          * 2: peer not allowed to send requests
17701f13597dSJung-uk Kim          */
17711f13597dSJung-uk Kim         if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
17721f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
17731f13597dSJung-uk Kim         else
17741f13597dSJung-uk Kim             *(ret++) = SSL_TLSEXT_HB_ENABLED;
17751f13597dSJung-uk Kim 
17761f13597dSJung-uk Kim     }
17771f13597dSJung-uk Kim # endif
17781f13597dSJung-uk Kim 
17791f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
17801f13597dSJung-uk Kim     next_proto_neg_seen = s->s3->next_proto_neg_seen;
17811f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
17826f9291ceSJung-uk Kim     if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
17831f13597dSJung-uk Kim         const unsigned char *npa;
17841f13597dSJung-uk Kim         unsigned int npalen;
17851f13597dSJung-uk Kim         int r;
17861f13597dSJung-uk Kim 
17876f9291ceSJung-uk Kim         r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
17886f9291ceSJung-uk Kim                                               s->
17896f9291ceSJung-uk Kim                                               ctx->next_protos_advertised_cb_arg);
17906f9291ceSJung-uk Kim         if (r == SSL_TLSEXT_ERR_OK) {
17916f9291ceSJung-uk Kim             if ((long)(limit - ret - 4 - npalen) < 0)
17926f9291ceSJung-uk Kim                 return NULL;
17931f13597dSJung-uk Kim             s2n(TLSEXT_TYPE_next_proto_neg, ret);
17941f13597dSJung-uk Kim             s2n(npalen, ret);
17951f13597dSJung-uk Kim             memcpy(ret, npa, npalen);
17961f13597dSJung-uk Kim             ret += npalen;
17971f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
17981f13597dSJung-uk Kim         }
17991f13597dSJung-uk Kim     }
18001f13597dSJung-uk Kim # endif
1801*7bded2dbSJung-uk Kim     if (!custom_ext_add(s, 1, &ret, limit, al))
1802*7bded2dbSJung-uk Kim         return NULL;
1803*7bded2dbSJung-uk Kim 
1804*7bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
1805*7bded2dbSJung-uk Kim         const unsigned char *selected = s->s3->alpn_selected;
1806*7bded2dbSJung-uk Kim         unsigned len = s->s3->alpn_selected_len;
1807*7bded2dbSJung-uk Kim 
1808*7bded2dbSJung-uk Kim         if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
1809*7bded2dbSJung-uk Kim             return NULL;
1810*7bded2dbSJung-uk Kim         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
1811*7bded2dbSJung-uk Kim         s2n(3 + len, ret);
1812*7bded2dbSJung-uk Kim         s2n(1 + len, ret);
1813*7bded2dbSJung-uk Kim         *ret++ = len;
1814*7bded2dbSJung-uk Kim         memcpy(ret, selected, len);
1815*7bded2dbSJung-uk Kim         ret += len;
1816*7bded2dbSJung-uk Kim     }
18171f13597dSJung-uk Kim 
1818a93cbc2bSJung-uk Kim     if ((extdatalen = ret - orig - 2) == 0)
1819a93cbc2bSJung-uk Kim         return orig;
1820db522d3aSSimon L. B. Nielsen 
1821a93cbc2bSJung-uk Kim     s2n(extdatalen, orig);
1822db522d3aSSimon L. B. Nielsen     return ret;
1823db522d3aSSimon L. B. Nielsen }
1824db522d3aSSimon L. B. Nielsen 
1825de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
18266f9291ceSJung-uk Kim /*-
18276f9291ceSJung-uk Kim  * ssl_check_for_safari attempts to fingerprint Safari using OS X
1828de78d5d8SJung-uk Kim  * SecureTransport using the TLS extension block in |d|, of length |n|.
1829de78d5d8SJung-uk Kim  * Safari, since 10.6, sends exactly these extensions, in this order:
1830de78d5d8SJung-uk Kim  *   SNI,
1831de78d5d8SJung-uk Kim  *   elliptic_curves
1832de78d5d8SJung-uk Kim  *   ec_point_formats
1833de78d5d8SJung-uk Kim  *
1834de78d5d8SJung-uk Kim  * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
1835de78d5d8SJung-uk Kim  * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
1836de78d5d8SJung-uk Kim  * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
1837de78d5d8SJung-uk Kim  * 10.8..10.8.3 (which don't work).
1838de78d5d8SJung-uk Kim  */
18396f9291ceSJung-uk Kim static void ssl_check_for_safari(SSL *s, const unsigned char *data,
18406f9291ceSJung-uk Kim                                  const unsigned char *d, int n)
18416f9291ceSJung-uk Kim {
1842de78d5d8SJung-uk Kim     unsigned short type, size;
1843de78d5d8SJung-uk Kim     static const unsigned char kSafariExtensionsBlock[] = {
1844de78d5d8SJung-uk Kim         0x00, 0x0a,             /* elliptic_curves extension */
1845de78d5d8SJung-uk Kim         0x00, 0x08,             /* 8 bytes */
1846de78d5d8SJung-uk Kim         0x00, 0x06,             /* 6 bytes of curve ids */
1847de78d5d8SJung-uk Kim         0x00, 0x17,             /* P-256 */
1848de78d5d8SJung-uk Kim         0x00, 0x18,             /* P-384 */
1849de78d5d8SJung-uk Kim         0x00, 0x19,             /* P-521 */
1850de78d5d8SJung-uk Kim 
1851de78d5d8SJung-uk Kim         0x00, 0x0b,             /* ec_point_formats */
1852de78d5d8SJung-uk Kim         0x00, 0x02,             /* 2 bytes */
1853de78d5d8SJung-uk Kim         0x01,                   /* 1 point format */
1854de78d5d8SJung-uk Kim         0x00,                   /* uncompressed */
1855de78d5d8SJung-uk Kim     };
1856de78d5d8SJung-uk Kim 
1857de78d5d8SJung-uk Kim     /* The following is only present in TLS 1.2 */
1858de78d5d8SJung-uk Kim     static const unsigned char kSafariTLS12ExtensionsBlock[] = {
1859de78d5d8SJung-uk Kim         0x00, 0x0d,             /* signature_algorithms */
1860de78d5d8SJung-uk Kim         0x00, 0x0c,             /* 12 bytes */
1861de78d5d8SJung-uk Kim         0x00, 0x0a,             /* 10 bytes */
1862de78d5d8SJung-uk Kim         0x05, 0x01,             /* SHA-384/RSA */
1863de78d5d8SJung-uk Kim         0x04, 0x01,             /* SHA-256/RSA */
1864de78d5d8SJung-uk Kim         0x02, 0x01,             /* SHA-1/RSA */
1865de78d5d8SJung-uk Kim         0x04, 0x03,             /* SHA-256/ECDSA */
1866de78d5d8SJung-uk Kim         0x02, 0x03,             /* SHA-1/ECDSA */
1867de78d5d8SJung-uk Kim     };
1868de78d5d8SJung-uk Kim 
1869de78d5d8SJung-uk Kim     if (data >= (d + n - 2))
1870de78d5d8SJung-uk Kim         return;
1871de78d5d8SJung-uk Kim     data += 2;
1872de78d5d8SJung-uk Kim 
1873de78d5d8SJung-uk Kim     if (data > (d + n - 4))
1874de78d5d8SJung-uk Kim         return;
1875de78d5d8SJung-uk Kim     n2s(data, type);
1876de78d5d8SJung-uk Kim     n2s(data, size);
1877de78d5d8SJung-uk Kim 
1878de78d5d8SJung-uk Kim     if (type != TLSEXT_TYPE_server_name)
1879de78d5d8SJung-uk Kim         return;
1880de78d5d8SJung-uk Kim 
1881de78d5d8SJung-uk Kim     if (data + size > d + n)
1882de78d5d8SJung-uk Kim         return;
1883de78d5d8SJung-uk Kim     data += size;
1884de78d5d8SJung-uk Kim 
18856f9291ceSJung-uk Kim     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
1886de78d5d8SJung-uk Kim         const size_t len1 = sizeof(kSafariExtensionsBlock);
1887de78d5d8SJung-uk Kim         const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
1888de78d5d8SJung-uk Kim 
1889de78d5d8SJung-uk Kim         if (data + len1 + len2 != d + n)
1890de78d5d8SJung-uk Kim             return;
1891de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
1892de78d5d8SJung-uk Kim             return;
1893de78d5d8SJung-uk Kim         if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
1894de78d5d8SJung-uk Kim             return;
18956f9291ceSJung-uk Kim     } else {
1896de78d5d8SJung-uk Kim         const size_t len = sizeof(kSafariExtensionsBlock);
1897de78d5d8SJung-uk Kim 
1898de78d5d8SJung-uk Kim         if (data + len != d + n)
1899de78d5d8SJung-uk Kim             return;
1900de78d5d8SJung-uk Kim         if (memcmp(data, kSafariExtensionsBlock, len) != 0)
1901de78d5d8SJung-uk Kim             return;
1902de78d5d8SJung-uk Kim     }
1903de78d5d8SJung-uk Kim 
1904de78d5d8SJung-uk Kim     s->s3->is_probably_safari = 1;
1905de78d5d8SJung-uk Kim }
1906de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
1907de78d5d8SJung-uk Kim 
1908*7bded2dbSJung-uk Kim /*
1909*7bded2dbSJung-uk Kim  * tls1_alpn_handle_client_hello is called to process the ALPN extension in a
1910*7bded2dbSJung-uk Kim  * ClientHello.  data: the contents of the extension, not including the type
1911*7bded2dbSJung-uk Kim  * and length.  data_len: the number of bytes in |data| al: a pointer to the
1912*7bded2dbSJung-uk Kim  * alert value to send in the event of a non-zero return.  returns: 0 on
1913*7bded2dbSJung-uk Kim  * success.
1914*7bded2dbSJung-uk Kim  */
1915*7bded2dbSJung-uk Kim static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
1916*7bded2dbSJung-uk Kim                                          unsigned data_len, int *al)
1917*7bded2dbSJung-uk Kim {
1918*7bded2dbSJung-uk Kim     unsigned i;
1919*7bded2dbSJung-uk Kim     unsigned proto_len;
1920*7bded2dbSJung-uk Kim     const unsigned char *selected;
1921*7bded2dbSJung-uk Kim     unsigned char selected_len;
1922*7bded2dbSJung-uk Kim     int r;
1923*7bded2dbSJung-uk Kim 
1924*7bded2dbSJung-uk Kim     if (s->ctx->alpn_select_cb == NULL)
1925*7bded2dbSJung-uk Kim         return 0;
1926*7bded2dbSJung-uk Kim 
1927*7bded2dbSJung-uk Kim     if (data_len < 2)
1928*7bded2dbSJung-uk Kim         goto parse_error;
1929*7bded2dbSJung-uk Kim 
1930*7bded2dbSJung-uk Kim     /*
1931*7bded2dbSJung-uk Kim      * data should contain a uint16 length followed by a series of 8-bit,
1932*7bded2dbSJung-uk Kim      * length-prefixed strings.
1933*7bded2dbSJung-uk Kim      */
1934*7bded2dbSJung-uk Kim     i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]);
1935*7bded2dbSJung-uk Kim     data_len -= 2;
1936*7bded2dbSJung-uk Kim     data += 2;
1937*7bded2dbSJung-uk Kim     if (data_len != i)
1938*7bded2dbSJung-uk Kim         goto parse_error;
1939*7bded2dbSJung-uk Kim 
1940*7bded2dbSJung-uk Kim     if (data_len < 2)
1941*7bded2dbSJung-uk Kim         goto parse_error;
1942*7bded2dbSJung-uk Kim 
1943*7bded2dbSJung-uk Kim     for (i = 0; i < data_len;) {
1944*7bded2dbSJung-uk Kim         proto_len = data[i];
1945*7bded2dbSJung-uk Kim         i++;
1946*7bded2dbSJung-uk Kim 
1947*7bded2dbSJung-uk Kim         if (proto_len == 0)
1948*7bded2dbSJung-uk Kim             goto parse_error;
1949*7bded2dbSJung-uk Kim 
1950*7bded2dbSJung-uk Kim         if (i + proto_len < i || i + proto_len > data_len)
1951*7bded2dbSJung-uk Kim             goto parse_error;
1952*7bded2dbSJung-uk Kim 
1953*7bded2dbSJung-uk Kim         i += proto_len;
1954*7bded2dbSJung-uk Kim     }
1955*7bded2dbSJung-uk Kim 
1956*7bded2dbSJung-uk Kim     r = s->ctx->alpn_select_cb(s, &selected, &selected_len, data, data_len,
1957*7bded2dbSJung-uk Kim                                s->ctx->alpn_select_cb_arg);
1958*7bded2dbSJung-uk Kim     if (r == SSL_TLSEXT_ERR_OK) {
1959*7bded2dbSJung-uk Kim         if (s->s3->alpn_selected)
1960*7bded2dbSJung-uk Kim             OPENSSL_free(s->s3->alpn_selected);
1961*7bded2dbSJung-uk Kim         s->s3->alpn_selected = OPENSSL_malloc(selected_len);
1962*7bded2dbSJung-uk Kim         if (!s->s3->alpn_selected) {
1963*7bded2dbSJung-uk Kim             *al = SSL_AD_INTERNAL_ERROR;
1964*7bded2dbSJung-uk Kim             return -1;
1965*7bded2dbSJung-uk Kim         }
1966*7bded2dbSJung-uk Kim         memcpy(s->s3->alpn_selected, selected, selected_len);
1967*7bded2dbSJung-uk Kim         s->s3->alpn_selected_len = selected_len;
1968*7bded2dbSJung-uk Kim     }
1969*7bded2dbSJung-uk Kim     return 0;
1970*7bded2dbSJung-uk Kim 
1971*7bded2dbSJung-uk Kim  parse_error:
1972*7bded2dbSJung-uk Kim     *al = SSL_AD_DECODE_ERROR;
1973*7bded2dbSJung-uk Kim     return -1;
1974*7bded2dbSJung-uk Kim }
1975*7bded2dbSJung-uk Kim 
1976*7bded2dbSJung-uk Kim static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
1977*7bded2dbSJung-uk Kim                                        unsigned char *d, int n, int *al)
1978db522d3aSSimon L. B. Nielsen {
1979db522d3aSSimon L. B. Nielsen     unsigned short type;
1980db522d3aSSimon L. B. Nielsen     unsigned short size;
1981db522d3aSSimon L. B. Nielsen     unsigned short len;
1982db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
19836a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
19846a599222SSimon L. B. Nielsen 
1985db522d3aSSimon L. B. Nielsen     s->servername_done = 0;
1986db522d3aSSimon L. B. Nielsen     s->tlsext_status_type = -1;
19871f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
19881f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
19891f13597dSJung-uk Kim # endif
19901f13597dSJung-uk Kim 
1991*7bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
1992*7bded2dbSJung-uk Kim         OPENSSL_free(s->s3->alpn_selected);
1993*7bded2dbSJung-uk Kim         s->s3->alpn_selected = NULL;
1994*7bded2dbSJung-uk Kim     }
19951f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
19961f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
19971f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
19981f13597dSJung-uk Kim # endif
1999db522d3aSSimon L. B. Nielsen 
2000de78d5d8SJung-uk Kim # ifndef OPENSSL_NO_EC
2001de78d5d8SJung-uk Kim     if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
2002de78d5d8SJung-uk Kim         ssl_check_for_safari(s, data, d, n);
2003de78d5d8SJung-uk Kim # endif                         /* !OPENSSL_NO_EC */
2004de78d5d8SJung-uk Kim 
2005*7bded2dbSJung-uk Kim     /* Clear any signature algorithms extension received */
2006*7bded2dbSJung-uk Kim     if (s->cert->peer_sigalgs) {
2007*7bded2dbSJung-uk Kim         OPENSSL_free(s->cert->peer_sigalgs);
2008*7bded2dbSJung-uk Kim         s->cert->peer_sigalgs = NULL;
2009*7bded2dbSJung-uk Kim     }
2010751d2991SJung-uk Kim # ifndef OPENSSL_NO_SRP
20116f9291ceSJung-uk Kim     if (s->srp_ctx.login != NULL) {
2012751d2991SJung-uk Kim         OPENSSL_free(s->srp_ctx.login);
2013751d2991SJung-uk Kim         s->srp_ctx.login = NULL;
2014751d2991SJung-uk Kim     }
2015751d2991SJung-uk Kim # endif
2016751d2991SJung-uk Kim 
2017751d2991SJung-uk Kim     s->srtp_profile = NULL;
2018751d2991SJung-uk Kim 
2019d47910c6SJung-uk Kim     if (data == d + n)
20206a599222SSimon L. B. Nielsen         goto ri_check;
2021d47910c6SJung-uk Kim 
2022d47910c6SJung-uk Kim     if (data > (d + n - 2))
2023d47910c6SJung-uk Kim         goto err;
2024d47910c6SJung-uk Kim 
2025db522d3aSSimon L. B. Nielsen     n2s(data, len);
2026db522d3aSSimon L. B. Nielsen 
2027db522d3aSSimon L. B. Nielsen     if (data > (d + n - len))
2028ed6b93beSJung-uk Kim         goto err;
2029db522d3aSSimon L. B. Nielsen 
20306f9291ceSJung-uk Kim     while (data <= (d + n - 4)) {
2031db522d3aSSimon L. B. Nielsen         n2s(data, type);
2032db522d3aSSimon L. B. Nielsen         n2s(data, size);
2033db522d3aSSimon L. B. Nielsen 
2034db522d3aSSimon L. B. Nielsen         if (data + size > (d + n))
2035ed6b93beSJung-uk Kim             goto err;
20361f13597dSJung-uk Kim # if 0
20371f13597dSJung-uk Kim         fprintf(stderr, "Received extension type %d size %d\n", type, size);
20381f13597dSJung-uk Kim # endif
2039db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
20406f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
20416f9291ceSJung-uk Kim /*-
20426f9291ceSJung-uk Kim  * The servername extension is treated as follows:
20436f9291ceSJung-uk Kim  *
20446f9291ceSJung-uk Kim  * - Only the hostname type is supported with a maximum length of 255.
20456f9291ceSJung-uk Kim  * - The servername is rejected if too long or if it contains zeros,
20466f9291ceSJung-uk Kim  *   in which case an fatal alert is generated.
20476f9291ceSJung-uk Kim  * - The servername field is maintained together with the session cache.
20486f9291ceSJung-uk Kim  * - When a session is resumed, the servername call back invoked in order
20496f9291ceSJung-uk Kim  *   to allow the application to position itself to the right context.
20506f9291ceSJung-uk Kim  * - The servername is acknowledged if it is new for a session or when
20516f9291ceSJung-uk Kim  *   it is identical to a previously used for the same session.
20526f9291ceSJung-uk Kim  *   Applications can control the behaviour.  They can at any time
20536f9291ceSJung-uk Kim  *   set a 'desirable' servername for a new SSL object. This can be the
20546f9291ceSJung-uk Kim  *   case for example with HTTPS when a Host: header field is received and
20556f9291ceSJung-uk Kim  *   a renegotiation is requested. In this case, a possible servername
20566f9291ceSJung-uk Kim  *   presented in the new client hello is only acknowledged if it matches
20576f9291ceSJung-uk Kim  *   the value of the Host: field.
20586f9291ceSJung-uk Kim  * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
20596f9291ceSJung-uk Kim  *   if they provide for changing an explicit servername context for the
20606f9291ceSJung-uk Kim  *   session, i.e. when the session has been established with a servername
20616f9291ceSJung-uk Kim  *   extension.
20626f9291ceSJung-uk Kim  * - On session reconnect, the servername extension may be absent.
20636f9291ceSJung-uk Kim  *
2064db522d3aSSimon L. B. Nielsen  */
2065db522d3aSSimon L. B. Nielsen 
20666f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
2067db522d3aSSimon L. B. Nielsen             unsigned char *sdata;
2068db522d3aSSimon L. B. Nielsen             int servname_type;
2069db522d3aSSimon L. B. Nielsen             int dsize;
2070db522d3aSSimon L. B. Nielsen 
2071ed6b93beSJung-uk Kim             if (size < 2)
2072ed6b93beSJung-uk Kim                 goto err;
2073db522d3aSSimon L. B. Nielsen             n2s(data, dsize);
2074db522d3aSSimon L. B. Nielsen             size -= 2;
2075ed6b93beSJung-uk Kim             if (dsize > size)
2076ed6b93beSJung-uk Kim                 goto err;
2077db522d3aSSimon L. B. Nielsen 
2078db522d3aSSimon L. B. Nielsen             sdata = data;
20796f9291ceSJung-uk Kim             while (dsize > 3) {
2080db522d3aSSimon L. B. Nielsen                 servname_type = *(sdata++);
2081db522d3aSSimon L. B. Nielsen                 n2s(sdata, len);
2082db522d3aSSimon L. B. Nielsen                 dsize -= 3;
2083db522d3aSSimon L. B. Nielsen 
2084ed6b93beSJung-uk Kim                 if (len > dsize)
2085ed6b93beSJung-uk Kim                     goto err;
2086ed6b93beSJung-uk Kim 
2087db522d3aSSimon L. B. Nielsen                 if (s->servername_done == 0)
20886f9291ceSJung-uk Kim                     switch (servname_type) {
2089db522d3aSSimon L. B. Nielsen                     case TLSEXT_NAMETYPE_host_name:
20906f9291ceSJung-uk Kim                         if (!s->hit) {
2091ed6b93beSJung-uk Kim                             if (s->session->tlsext_hostname)
2092ed6b93beSJung-uk Kim                                 goto err;
2093ed6b93beSJung-uk Kim 
20946f9291ceSJung-uk Kim                             if (len > TLSEXT_MAXLEN_host_name) {
2095db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2096db522d3aSSimon L. B. Nielsen                                 return 0;
2097db522d3aSSimon L. B. Nielsen                             }
20986f9291ceSJung-uk Kim                             if ((s->session->tlsext_hostname =
20996f9291ceSJung-uk Kim                                  OPENSSL_malloc(len + 1)) == NULL) {
2100a3ddd25aSSimon L. B. Nielsen                                 *al = TLS1_AD_INTERNAL_ERROR;
2101a3ddd25aSSimon L. B. Nielsen                                 return 0;
2102a3ddd25aSSimon L. B. Nielsen                             }
2103db522d3aSSimon L. B. Nielsen                             memcpy(s->session->tlsext_hostname, sdata, len);
2104db522d3aSSimon L. B. Nielsen                             s->session->tlsext_hostname[len] = '\0';
2105db522d3aSSimon L. B. Nielsen                             if (strlen(s->session->tlsext_hostname) != len) {
2106db522d3aSSimon L. B. Nielsen                                 OPENSSL_free(s->session->tlsext_hostname);
2107db522d3aSSimon L. B. Nielsen                                 s->session->tlsext_hostname = NULL;
2108db522d3aSSimon L. B. Nielsen                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2109db522d3aSSimon L. B. Nielsen                                 return 0;
2110db522d3aSSimon L. B. Nielsen                             }
2111db522d3aSSimon L. B. Nielsen                             s->servername_done = 1;
2112db522d3aSSimon L. B. Nielsen 
21136f9291ceSJung-uk Kim                         } else
2114a3ddd25aSSimon L. B. Nielsen                             s->servername_done = s->session->tlsext_hostname
2115a3ddd25aSSimon L. B. Nielsen                                 && strlen(s->session->tlsext_hostname) == len
21166f9291ceSJung-uk Kim                                 && strncmp(s->session->tlsext_hostname,
21176f9291ceSJung-uk Kim                                            (char *)sdata, len) == 0;
2118db522d3aSSimon L. B. Nielsen 
2119db522d3aSSimon L. B. Nielsen                         break;
2120db522d3aSSimon L. B. Nielsen 
2121db522d3aSSimon L. B. Nielsen                     default:
2122db522d3aSSimon L. B. Nielsen                         break;
2123db522d3aSSimon L. B. Nielsen                     }
2124db522d3aSSimon L. B. Nielsen 
2125db522d3aSSimon L. B. Nielsen                 dsize -= len;
2126db522d3aSSimon L. B. Nielsen             }
2127ed6b93beSJung-uk Kim             if (dsize != 0)
2128ed6b93beSJung-uk Kim                 goto err;
2129db522d3aSSimon L. B. Nielsen 
2130db522d3aSSimon L. B. Nielsen         }
21311f13597dSJung-uk Kim # ifndef OPENSSL_NO_SRP
21326f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_srp) {
2133ed6b93beSJung-uk Kim             if (size == 0 || ((len = data[0])) != (size - 1))
2134ed6b93beSJung-uk Kim                 goto err;
2135ed6b93beSJung-uk Kim             if (s->srp_ctx.login != NULL)
2136ed6b93beSJung-uk Kim                 goto err;
21371f13597dSJung-uk Kim             if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
21381f13597dSJung-uk Kim                 return -1;
21391f13597dSJung-uk Kim             memcpy(s->srp_ctx.login, &data[1], len);
21401f13597dSJung-uk Kim             s->srp_ctx.login[len] = '\0';
21411f13597dSJung-uk Kim 
2142ed6b93beSJung-uk Kim             if (strlen(s->srp_ctx.login) != len)
2143ed6b93beSJung-uk Kim                 goto err;
21441f13597dSJung-uk Kim         }
21451f13597dSJung-uk Kim # endif
21461f13597dSJung-uk Kim 
21471f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
21486f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
21491f13597dSJung-uk Kim             unsigned char *sdata = data;
21501f13597dSJung-uk Kim             int ecpointformatlist_length = *(sdata++);
21511f13597dSJung-uk Kim 
2152*7bded2dbSJung-uk Kim             if (ecpointformatlist_length != size - 1 ||
2153*7bded2dbSJung-uk Kim                 ecpointformatlist_length < 1)
2154ed6b93beSJung-uk Kim                 goto err;
21556f9291ceSJung-uk Kim             if (!s->hit) {
21566f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist) {
21571f13597dSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
21581f13597dSJung-uk Kim                     s->session->tlsext_ecpointformatlist = NULL;
21591f13597dSJung-uk Kim                 }
21601f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
21616f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
21626f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
21631f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
21641f13597dSJung-uk Kim                     return 0;
21651f13597dSJung-uk Kim                 }
21666f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
21676f9291ceSJung-uk Kim                     ecpointformatlist_length;
21686f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
21696f9291ceSJung-uk Kim                        ecpointformatlist_length);
21701f13597dSJung-uk Kim             }
21711f13597dSJung-uk Kim #  if 0
21726f9291ceSJung-uk Kim             fprintf(stderr,
21736f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ",
21746f9291ceSJung-uk Kim                     s->session->tlsext_ecpointformatlist_length);
21751f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
21761f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
21771f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
21781f13597dSJung-uk Kim             fprintf(stderr, "\n");
21791f13597dSJung-uk Kim #  endif
21806f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_elliptic_curves) {
21811f13597dSJung-uk Kim             unsigned char *sdata = data;
21821f13597dSJung-uk Kim             int ellipticcurvelist_length = (*(sdata++) << 8);
21831f13597dSJung-uk Kim             ellipticcurvelist_length += (*(sdata++));
21841f13597dSJung-uk Kim 
218509286989SJung-uk Kim             if (ellipticcurvelist_length != size - 2 ||
2186751d2991SJung-uk Kim                 ellipticcurvelist_length < 1 ||
2187751d2991SJung-uk Kim                 /* Each NamedCurve is 2 bytes. */
2188ed6b93beSJung-uk Kim                 ellipticcurvelist_length & 1)
2189ed6b93beSJung-uk Kim                     goto err;
2190ed6b93beSJung-uk Kim 
21916f9291ceSJung-uk Kim             if (!s->hit) {
2192ed6b93beSJung-uk Kim                 if (s->session->tlsext_ellipticcurvelist)
2193ed6b93beSJung-uk Kim                     goto err;
2194ed6b93beSJung-uk Kim 
21951f13597dSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length = 0;
21966f9291ceSJung-uk Kim                 if ((s->session->tlsext_ellipticcurvelist =
21976f9291ceSJung-uk Kim                      OPENSSL_malloc(ellipticcurvelist_length)) == NULL) {
21981f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
21991f13597dSJung-uk Kim                     return 0;
22001f13597dSJung-uk Kim                 }
22016f9291ceSJung-uk Kim                 s->session->tlsext_ellipticcurvelist_length =
22026f9291ceSJung-uk Kim                     ellipticcurvelist_length;
22036f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ellipticcurvelist, sdata,
22046f9291ceSJung-uk Kim                        ellipticcurvelist_length);
22051f13597dSJung-uk Kim             }
22061f13597dSJung-uk Kim #  if 0
22076f9291ceSJung-uk Kim             fprintf(stderr,
22086f9291ceSJung-uk Kim                     "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ",
22096f9291ceSJung-uk Kim                     s->session->tlsext_ellipticcurvelist_length);
22101f13597dSJung-uk Kim             sdata = s->session->tlsext_ellipticcurvelist;
22111f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
22121f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
22131f13597dSJung-uk Kim             fprintf(stderr, "\n");
22141f13597dSJung-uk Kim #  endif
22151f13597dSJung-uk Kim         }
22161f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
22171f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
2218*7bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input) {
22191f13597dSJung-uk Kim             unsigned char *sdata = data;
22201f13597dSJung-uk Kim 
22216f9291ceSJung-uk Kim             if (size < 2) {
22221f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
22231f13597dSJung-uk Kim                 return 0;
22241f13597dSJung-uk Kim             }
22251f13597dSJung-uk Kim             n2s(sdata, s->s3->client_opaque_prf_input_len);
22266f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input_len != size - 2) {
22271f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
22281f13597dSJung-uk Kim                 return 0;
22291f13597dSJung-uk Kim             }
22301f13597dSJung-uk Kim 
22316f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
22326f9291ceSJung-uk Kim                 /* shouldn't really happen */
22331f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
22346f9291ceSJung-uk Kim             }
22356f9291ceSJung-uk Kim 
22366f9291ceSJung-uk Kim             /* dummy byte just to get non-NULL */
22371f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input_len == 0)
22386f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
22391f13597dSJung-uk Kim             else
22406f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
22416f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
22426f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
22431f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
22441f13597dSJung-uk Kim                 return 0;
22451f13597dSJung-uk Kim             }
22461f13597dSJung-uk Kim         }
22471f13597dSJung-uk Kim # endif
22486f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
22491f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
22506f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
22516f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
22521f13597dSJung-uk Kim             {
22531f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
22541f13597dSJung-uk Kim                 return 0;
22551f13597dSJung-uk Kim             }
22566f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_renegotiate) {
22576a599222SSimon L. B. Nielsen             if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
22586a599222SSimon L. B. Nielsen                 return 0;
22596a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
22606f9291ceSJung-uk Kim         } else if (type == TLSEXT_TYPE_signature_algorithms) {
22611f13597dSJung-uk Kim             int dsize;
2262*7bded2dbSJung-uk Kim             if (s->cert->peer_sigalgs || size < 2)
2263ed6b93beSJung-uk Kim                 goto err;
22641f13597dSJung-uk Kim             n2s(data, dsize);
22651f13597dSJung-uk Kim             size -= 2;
2266*7bded2dbSJung-uk Kim             if (dsize != size || dsize & 1 || !dsize)
2267ed6b93beSJung-uk Kim                 goto err;
2268*7bded2dbSJung-uk Kim             if (!tls1_save_sigalgs(s, data, dsize))
2269ed6b93beSJung-uk Kim                 goto err;
2270*7bded2dbSJung-uk Kim         } else if (type == TLSEXT_TYPE_status_request) {
2271db522d3aSSimon L. B. Nielsen 
2272ed6b93beSJung-uk Kim             if (size < 5)
2273ed6b93beSJung-uk Kim                 goto err;
2274db522d3aSSimon L. B. Nielsen 
2275db522d3aSSimon L. B. Nielsen             s->tlsext_status_type = *data++;
2276db522d3aSSimon L. B. Nielsen             size--;
22776f9291ceSJung-uk Kim             if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
2278db522d3aSSimon L. B. Nielsen                 const unsigned char *sdata;
2279db522d3aSSimon L. B. Nielsen                 int dsize;
2280db522d3aSSimon L. B. Nielsen                 /* Read in responder_id_list */
2281db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
2282db522d3aSSimon L. B. Nielsen                 size -= 2;
2283ed6b93beSJung-uk Kim                 if (dsize > size)
2284ed6b93beSJung-uk Kim                     goto err;
22856f9291ceSJung-uk Kim                 while (dsize > 0) {
2286db522d3aSSimon L. B. Nielsen                     OCSP_RESPID *id;
2287db522d3aSSimon L. B. Nielsen                     int idsize;
2288ed6b93beSJung-uk Kim                     if (dsize < 4)
2289ed6b93beSJung-uk Kim                         goto err;
2290db522d3aSSimon L. B. Nielsen                     n2s(data, idsize);
2291db522d3aSSimon L. B. Nielsen                     dsize -= 2 + idsize;
22920a704568SSimon L. B. Nielsen                     size -= 2 + idsize;
2293ed6b93beSJung-uk Kim                     if (dsize < 0)
2294ed6b93beSJung-uk Kim                         goto err;
2295db522d3aSSimon L. B. Nielsen                     sdata = data;
2296db522d3aSSimon L. B. Nielsen                     data += idsize;
22976f9291ceSJung-uk Kim                     id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
2298ed6b93beSJung-uk Kim                     if (!id)
2299ed6b93beSJung-uk Kim                         goto err;
23006f9291ceSJung-uk Kim                     if (data != sdata) {
2301db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2302ed6b93beSJung-uk Kim                         goto err;
2303db522d3aSSimon L. B. Nielsen                     }
2304db522d3aSSimon L. B. Nielsen                     if (!s->tlsext_ocsp_ids
2305db522d3aSSimon L. B. Nielsen                         && !(s->tlsext_ocsp_ids =
23066f9291ceSJung-uk Kim                              sk_OCSP_RESPID_new_null())) {
2307db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2308db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_INTERNAL_ERROR;
2309db522d3aSSimon L. B. Nielsen                         return 0;
2310db522d3aSSimon L. B. Nielsen                     }
23116f9291ceSJung-uk Kim                     if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
2312db522d3aSSimon L. B. Nielsen                         OCSP_RESPID_free(id);
2313db522d3aSSimon L. B. Nielsen                         *al = SSL_AD_INTERNAL_ERROR;
2314db522d3aSSimon L. B. Nielsen                         return 0;
2315db522d3aSSimon L. B. Nielsen                     }
2316db522d3aSSimon L. B. Nielsen                 }
2317db522d3aSSimon L. B. Nielsen 
2318db522d3aSSimon L. B. Nielsen                 /* Read in request_extensions */
2319ed6b93beSJung-uk Kim                 if (size < 2)
2320ed6b93beSJung-uk Kim                     goto err;
2321db522d3aSSimon L. B. Nielsen                 n2s(data, dsize);
2322db522d3aSSimon L. B. Nielsen                 size -= 2;
2323ed6b93beSJung-uk Kim                 if (dsize != size)
2324ed6b93beSJung-uk Kim                     goto err;
2325db522d3aSSimon L. B. Nielsen                 sdata = data;
23266f9291ceSJung-uk Kim                 if (dsize > 0) {
23276f9291ceSJung-uk Kim                     if (s->tlsext_ocsp_exts) {
232812de4ed2SJung-uk Kim                         sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
232912de4ed2SJung-uk Kim                                                    X509_EXTENSION_free);
233012de4ed2SJung-uk Kim                     }
233112de4ed2SJung-uk Kim 
2332db522d3aSSimon L. B. Nielsen                     s->tlsext_ocsp_exts =
23336f9291ceSJung-uk Kim                         d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
2334ed6b93beSJung-uk Kim                     if (!s->tlsext_ocsp_exts || (data + dsize != sdata))
2335ed6b93beSJung-uk Kim                         goto err;
2336db522d3aSSimon L. B. Nielsen                 }
2337db522d3aSSimon L. B. Nielsen             }
23386f9291ceSJung-uk Kim             /*
23396f9291ceSJung-uk Kim              * We don't know what to do with any other type * so ignore it.
2340db522d3aSSimon L. B. Nielsen              */
2341db522d3aSSimon L. B. Nielsen             else
2342db522d3aSSimon L. B. Nielsen                 s->tlsext_status_type = -1;
2343db522d3aSSimon L. B. Nielsen         }
23441f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
23456f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
23466f9291ceSJung-uk Kim             switch (data[0]) {
23471f13597dSJung-uk Kim             case 0x01:         /* Client allows us to send HB requests */
23481f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
23491f13597dSJung-uk Kim                 break;
23501f13597dSJung-uk Kim             case 0x02:         /* Client doesn't accept HB requests */
23511f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
23521f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
23531f13597dSJung-uk Kim                 break;
23546f9291ceSJung-uk Kim             default:
23556f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
23561f13597dSJung-uk Kim                 return 0;
23571f13597dSJung-uk Kim             }
23581f13597dSJung-uk Kim         }
23591f13597dSJung-uk Kim # endif
23601f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
23611f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
2362*7bded2dbSJung-uk Kim                  s->s3->tmp.finish_md_len == 0 &&
2363*7bded2dbSJung-uk Kim                  s->s3->alpn_selected == NULL) {
23646f9291ceSJung-uk Kim             /*-
23656f9291ceSJung-uk Kim              * We shouldn't accept this extension on a
23661f13597dSJung-uk Kim              * renegotiation.
23671f13597dSJung-uk Kim              *
23681f13597dSJung-uk Kim              * s->new_session will be set on renegotiation, but we
23691f13597dSJung-uk Kim              * probably shouldn't rely that it couldn't be set on
23701f13597dSJung-uk Kim              * the initial renegotation too in certain cases (when
23711f13597dSJung-uk Kim              * there's some other reason to disallow resuming an
23721f13597dSJung-uk Kim              * earlier session -- the current code won't be doing
23731f13597dSJung-uk Kim              * anything like that, but this might change).
23746f9291ceSJung-uk Kim              *
23751f13597dSJung-uk Kim              * A valid sign that there's been a previous handshake
23761f13597dSJung-uk Kim              * in this connection is if s->s3->tmp.finish_md_len >
23771f13597dSJung-uk Kim              * 0.  (We are talking about a check that will happen
23781f13597dSJung-uk Kim              * in the Hello protocol round, well before a new
23796f9291ceSJung-uk Kim              * Finished message could have been computed.)
23806f9291ceSJung-uk Kim              */
23811f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
23821f13597dSJung-uk Kim         }
23831f13597dSJung-uk Kim # endif
23846a599222SSimon L. B. Nielsen 
2385*7bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
2386*7bded2dbSJung-uk Kim                  s->ctx->alpn_select_cb && s->s3->tmp.finish_md_len == 0) {
2387*7bded2dbSJung-uk Kim             if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
2388*7bded2dbSJung-uk Kim                 return 0;
2389*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
2390*7bded2dbSJung-uk Kim             /* ALPN takes precedence over NPN. */
2391*7bded2dbSJung-uk Kim             s->s3->next_proto_neg_seen = 0;
2392*7bded2dbSJung-uk Kim # endif
2393*7bded2dbSJung-uk Kim         }
2394*7bded2dbSJung-uk Kim 
2395db522d3aSSimon L. B. Nielsen         /* session ticket processed earlier */
239609286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
2397fa5fddf1SJung-uk Kim         else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
23986f9291ceSJung-uk Kim                  && type == TLSEXT_TYPE_use_srtp) {
23996f9291ceSJung-uk Kim             if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al))
24001f13597dSJung-uk Kim                 return 0;
24011f13597dSJung-uk Kim         }
240209286989SJung-uk Kim # endif
2403db522d3aSSimon L. B. Nielsen 
2404db522d3aSSimon L. B. Nielsen         data += size;
2405db522d3aSSimon L. B. Nielsen     }
24061f13597dSJung-uk Kim 
2407ed6b93beSJung-uk Kim     /* Spurious data on the end */
2408ed6b93beSJung-uk Kim     if (data != d + n)
2409ed6b93beSJung-uk Kim         goto err;
2410ed6b93beSJung-uk Kim 
2411db522d3aSSimon L. B. Nielsen     *p = data;
24126a599222SSimon L. B. Nielsen 
24136a599222SSimon L. B. Nielsen  ri_check:
24146a599222SSimon L. B. Nielsen 
24156a599222SSimon L. B. Nielsen     /* Need RI if renegotiating */
24166a599222SSimon L. B. Nielsen 
24171f13597dSJung-uk Kim     if (!renegotiate_seen && s->renegotiate &&
24186f9291ceSJung-uk Kim         !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
24196a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
2420*7bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
24216a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
24226a599222SSimon L. B. Nielsen         return 0;
24236a599222SSimon L. B. Nielsen     }
24246a599222SSimon L. B. Nielsen 
2425db522d3aSSimon L. B. Nielsen     return 1;
2426ed6b93beSJung-uk Kim err:
2427ed6b93beSJung-uk Kim     *al = SSL_AD_DECODE_ERROR;
2428ed6b93beSJung-uk Kim     return 0;
2429db522d3aSSimon L. B. Nielsen }
2430db522d3aSSimon L. B. Nielsen 
2431*7bded2dbSJung-uk Kim /*
2432*7bded2dbSJung-uk Kim  * Parse any custom extensions found.  "data" is the start of the extension data
2433*7bded2dbSJung-uk Kim  * and "limit" is the end of the record. TODO: add strict syntax checking.
2434*7bded2dbSJung-uk Kim  */
2435*7bded2dbSJung-uk Kim 
2436*7bded2dbSJung-uk Kim static int ssl_scan_clienthello_custom_tlsext(SSL *s,
2437*7bded2dbSJung-uk Kim                                               const unsigned char *data,
2438*7bded2dbSJung-uk Kim                                               const unsigned char *limit,
2439*7bded2dbSJung-uk Kim                                               int *al)
2440*7bded2dbSJung-uk Kim {
2441*7bded2dbSJung-uk Kim     unsigned short type, size, len;
2442*7bded2dbSJung-uk Kim     /* If resumed session or no custom extensions nothing to do */
2443*7bded2dbSJung-uk Kim     if (s->hit || s->cert->srv_ext.meths_count == 0)
2444*7bded2dbSJung-uk Kim         return 1;
2445*7bded2dbSJung-uk Kim 
2446*7bded2dbSJung-uk Kim     if (data >= limit - 2)
2447*7bded2dbSJung-uk Kim         return 1;
2448*7bded2dbSJung-uk Kim     n2s(data, len);
2449*7bded2dbSJung-uk Kim 
2450*7bded2dbSJung-uk Kim     if (data > limit - len)
2451*7bded2dbSJung-uk Kim         return 1;
2452*7bded2dbSJung-uk Kim 
2453*7bded2dbSJung-uk Kim     while (data <= limit - 4) {
2454*7bded2dbSJung-uk Kim         n2s(data, type);
2455*7bded2dbSJung-uk Kim         n2s(data, size);
2456*7bded2dbSJung-uk Kim 
2457*7bded2dbSJung-uk Kim         if (data + size > limit)
2458*7bded2dbSJung-uk Kim             return 1;
2459*7bded2dbSJung-uk Kim         if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0)
2460*7bded2dbSJung-uk Kim             return 0;
2461*7bded2dbSJung-uk Kim 
2462*7bded2dbSJung-uk Kim         data += size;
2463*7bded2dbSJung-uk Kim     }
2464*7bded2dbSJung-uk Kim 
2465*7bded2dbSJung-uk Kim     return 1;
2466*7bded2dbSJung-uk Kim }
2467*7bded2dbSJung-uk Kim 
2468*7bded2dbSJung-uk Kim int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
2469*7bded2dbSJung-uk Kim                                  int n)
2470*7bded2dbSJung-uk Kim {
2471*7bded2dbSJung-uk Kim     int al = -1;
2472*7bded2dbSJung-uk Kim     unsigned char *ptmp = *p;
2473*7bded2dbSJung-uk Kim     /*
2474*7bded2dbSJung-uk Kim      * Internally supported extensions are parsed first so SNI can be handled
2475*7bded2dbSJung-uk Kim      * before custom extensions. An application processing SNI will typically
2476*7bded2dbSJung-uk Kim      * switch the parent context using SSL_set_SSL_CTX and custom extensions
2477*7bded2dbSJung-uk Kim      * need to be handled by the new SSL_CTX structure.
2478*7bded2dbSJung-uk Kim      */
2479*7bded2dbSJung-uk Kim     if (ssl_scan_clienthello_tlsext(s, p, d, n, &al) <= 0) {
2480*7bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
2481*7bded2dbSJung-uk Kim         return 0;
2482*7bded2dbSJung-uk Kim     }
2483*7bded2dbSJung-uk Kim 
2484*7bded2dbSJung-uk Kim     if (ssl_check_clienthello_tlsext_early(s) <= 0) {
2485*7bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT);
2486*7bded2dbSJung-uk Kim         return 0;
2487*7bded2dbSJung-uk Kim     }
2488*7bded2dbSJung-uk Kim 
2489*7bded2dbSJung-uk Kim     custom_ext_init(&s->cert->srv_ext);
2490*7bded2dbSJung-uk Kim     if (ssl_scan_clienthello_custom_tlsext(s, ptmp, d + n, &al) <= 0) {
2491*7bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
2492*7bded2dbSJung-uk Kim         return 0;
2493*7bded2dbSJung-uk Kim     }
2494*7bded2dbSJung-uk Kim 
2495*7bded2dbSJung-uk Kim     return 1;
2496*7bded2dbSJung-uk Kim }
2497*7bded2dbSJung-uk Kim 
24981f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
24996f9291ceSJung-uk Kim /*
25006f9291ceSJung-uk Kim  * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
25016f9291ceSJung-uk Kim  * elements of zero length are allowed and the set of elements must exactly
25026f9291ceSJung-uk Kim  * fill the length of the block.
25036f9291ceSJung-uk Kim  */
25041f13597dSJung-uk Kim static char ssl_next_proto_validate(unsigned char *d, unsigned len)
25051f13597dSJung-uk Kim {
25061f13597dSJung-uk Kim     unsigned int off = 0;
25071f13597dSJung-uk Kim 
25086f9291ceSJung-uk Kim     while (off < len) {
25091f13597dSJung-uk Kim         if (d[off] == 0)
25101f13597dSJung-uk Kim             return 0;
25111f13597dSJung-uk Kim         off += d[off];
25121f13597dSJung-uk Kim         off++;
25131f13597dSJung-uk Kim     }
25141f13597dSJung-uk Kim 
25151f13597dSJung-uk Kim     return off == len;
25161f13597dSJung-uk Kim }
25171f13597dSJung-uk Kim # endif
25181f13597dSJung-uk Kim 
2519*7bded2dbSJung-uk Kim static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
2520*7bded2dbSJung-uk Kim                                        unsigned char *d, int n, int *al)
2521db522d3aSSimon L. B. Nielsen {
2522a3ddd25aSSimon L. B. Nielsen     unsigned short length;
2523db522d3aSSimon L. B. Nielsen     unsigned short type;
2524db522d3aSSimon L. B. Nielsen     unsigned short size;
2525db522d3aSSimon L. B. Nielsen     unsigned char *data = *p;
2526db522d3aSSimon L. B. Nielsen     int tlsext_servername = 0;
25276a599222SSimon L. B. Nielsen     int renegotiate_seen = 0;
2528db522d3aSSimon L. B. Nielsen 
25291f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
25301f13597dSJung-uk Kim     s->s3->next_proto_neg_seen = 0;
25311f13597dSJung-uk Kim # endif
2532751d2991SJung-uk Kim     s->tlsext_ticket_expected = 0;
25331f13597dSJung-uk Kim 
2534*7bded2dbSJung-uk Kim     if (s->s3->alpn_selected) {
2535*7bded2dbSJung-uk Kim         OPENSSL_free(s->s3->alpn_selected);
2536*7bded2dbSJung-uk Kim         s->s3->alpn_selected = NULL;
2537*7bded2dbSJung-uk Kim     }
25381f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
25391f13597dSJung-uk Kim     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
25401f13597dSJung-uk Kim                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
25411f13597dSJung-uk Kim # endif
25421f13597dSJung-uk Kim 
2543db522d3aSSimon L. B. Nielsen     if (data >= (d + n - 2))
25446a599222SSimon L. B. Nielsen         goto ri_check;
2545db522d3aSSimon L. B. Nielsen 
2546a3ddd25aSSimon L. B. Nielsen     n2s(data, length);
25476f9291ceSJung-uk Kim     if (data + length != d + n) {
2548a3ddd25aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
2549a3ddd25aSSimon L. B. Nielsen         return 0;
2550a3ddd25aSSimon L. B. Nielsen     }
2551db522d3aSSimon L. B. Nielsen 
25526f9291ceSJung-uk Kim     while (data <= (d + n - 4)) {
2553db522d3aSSimon L. B. Nielsen         n2s(data, type);
2554db522d3aSSimon L. B. Nielsen         n2s(data, size);
2555db522d3aSSimon L. B. Nielsen 
2556db522d3aSSimon L. B. Nielsen         if (data + size > (d + n))
25576a599222SSimon L. B. Nielsen             goto ri_check;
2558db522d3aSSimon L. B. Nielsen 
2559db522d3aSSimon L. B. Nielsen         if (s->tlsext_debug_cb)
25606f9291ceSJung-uk Kim             s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
2561db522d3aSSimon L. B. Nielsen 
25626f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_server_name) {
25636f9291ceSJung-uk Kim             if (s->tlsext_hostname == NULL || size > 0) {
2564db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNRECOGNIZED_NAME;
2565db522d3aSSimon L. B. Nielsen                 return 0;
2566db522d3aSSimon L. B. Nielsen             }
2567db522d3aSSimon L. B. Nielsen             tlsext_servername = 1;
2568db522d3aSSimon L. B. Nielsen         }
25691f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
25706f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_ec_point_formats) {
25711f13597dSJung-uk Kim             unsigned char *sdata = data;
25721f13597dSJung-uk Kim             int ecpointformatlist_length = *(sdata++);
25731f13597dSJung-uk Kim 
2574*7bded2dbSJung-uk Kim             if (ecpointformatlist_length != size - 1) {
25751f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
25761f13597dSJung-uk Kim                 return 0;
25771f13597dSJung-uk Kim             }
25786f9291ceSJung-uk Kim             if (!s->hit) {
25791f13597dSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length = 0;
25806f9291ceSJung-uk Kim                 if (s->session->tlsext_ecpointformatlist != NULL)
25816f9291ceSJung-uk Kim                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
25826f9291ceSJung-uk Kim                 if ((s->session->tlsext_ecpointformatlist =
25836f9291ceSJung-uk Kim                      OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
25841f13597dSJung-uk Kim                     *al = TLS1_AD_INTERNAL_ERROR;
25851f13597dSJung-uk Kim                     return 0;
25861f13597dSJung-uk Kim                 }
25876f9291ceSJung-uk Kim                 s->session->tlsext_ecpointformatlist_length =
25886f9291ceSJung-uk Kim                     ecpointformatlist_length;
25896f9291ceSJung-uk Kim                 memcpy(s->session->tlsext_ecpointformatlist, sdata,
25906f9291ceSJung-uk Kim                        ecpointformatlist_length);
2591a93cbc2bSJung-uk Kim             }
25921f13597dSJung-uk Kim #  if 0
25936f9291ceSJung-uk Kim             fprintf(stderr,
25946f9291ceSJung-uk Kim                     "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
25951f13597dSJung-uk Kim             sdata = s->session->tlsext_ecpointformatlist;
25961f13597dSJung-uk Kim             for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
25971f13597dSJung-uk Kim                 fprintf(stderr, "%i ", *(sdata++));
25981f13597dSJung-uk Kim             fprintf(stderr, "\n");
25991f13597dSJung-uk Kim #  endif
26001f13597dSJung-uk Kim         }
26011f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
26021f13597dSJung-uk Kim 
26036f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_session_ticket) {
26041f13597dSJung-uk Kim             if (s->tls_session_ticket_ext_cb &&
26056f9291ceSJung-uk Kim                 !s->tls_session_ticket_ext_cb(s, data, size,
26066f9291ceSJung-uk Kim                                               s->tls_session_ticket_ext_cb_arg))
26071f13597dSJung-uk Kim             {
26081f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
26091f13597dSJung-uk Kim                 return 0;
26101f13597dSJung-uk Kim             }
2611db522d3aSSimon L. B. Nielsen             if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
26126f9291ceSJung-uk Kim                 || (size > 0)) {
2613db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2614db522d3aSSimon L. B. Nielsen                 return 0;
2615db522d3aSSimon L. B. Nielsen             }
2616db522d3aSSimon L. B. Nielsen             s->tlsext_ticket_expected = 1;
2617db522d3aSSimon L. B. Nielsen         }
26181f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
2619*7bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_opaque_prf_input) {
26201f13597dSJung-uk Kim             unsigned char *sdata = data;
26211f13597dSJung-uk Kim 
26226f9291ceSJung-uk Kim             if (size < 2) {
26231f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
26241f13597dSJung-uk Kim                 return 0;
26251f13597dSJung-uk Kim             }
26261f13597dSJung-uk Kim             n2s(sdata, s->s3->server_opaque_prf_input_len);
26276f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len != size - 2) {
26281f13597dSJung-uk Kim                 *al = SSL_AD_DECODE_ERROR;
26291f13597dSJung-uk Kim                 return 0;
26301f13597dSJung-uk Kim             }
26311f13597dSJung-uk Kim 
26326f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input != NULL) {
26336f9291ceSJung-uk Kim                 /* shouldn't really happen */
26341f13597dSJung-uk Kim                 OPENSSL_free(s->s3->server_opaque_prf_input);
26356f9291ceSJung-uk Kim             }
26366f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input_len == 0) {
26376f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
26386f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
26396f9291ceSJung-uk Kim             } else {
26406f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input =
26416f9291ceSJung-uk Kim                     BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
26426f9291ceSJung-uk Kim             }
26431f13597dSJung-uk Kim 
26446f9291ceSJung-uk Kim             if (s->s3->server_opaque_prf_input == NULL) {
26451f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
26461f13597dSJung-uk Kim                 return 0;
26471f13597dSJung-uk Kim             }
26481f13597dSJung-uk Kim         }
26491f13597dSJung-uk Kim # endif
2650*7bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_status_request) {
26516f9291ceSJung-uk Kim             /*
26526f9291ceSJung-uk Kim              * MUST be empty and only sent if we've requested a status
26536f9291ceSJung-uk Kim              * request message.
2654db522d3aSSimon L. B. Nielsen              */
26556f9291ceSJung-uk Kim             if ((s->tlsext_status_type == -1) || (size > 0)) {
2656db522d3aSSimon L. B. Nielsen                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2657db522d3aSSimon L. B. Nielsen                 return 0;
2658db522d3aSSimon L. B. Nielsen             }
2659db522d3aSSimon L. B. Nielsen             /* Set flag to expect CertificateStatus message */
2660db522d3aSSimon L. B. Nielsen             s->tlsext_status_expected = 1;
2661db522d3aSSimon L. B. Nielsen         }
26621f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
26631f13597dSJung-uk Kim         else if (type == TLSEXT_TYPE_next_proto_neg &&
26646f9291ceSJung-uk Kim                  s->s3->tmp.finish_md_len == 0) {
26651f13597dSJung-uk Kim             unsigned char *selected;
26661f13597dSJung-uk Kim             unsigned char selected_len;
26671f13597dSJung-uk Kim 
26681f13597dSJung-uk Kim             /* We must have requested it. */
26696f9291ceSJung-uk Kim             if (s->ctx->next_proto_select_cb == NULL) {
26701f13597dSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
26711f13597dSJung-uk Kim                 return 0;
26721f13597dSJung-uk Kim             }
26731f13597dSJung-uk Kim             /* The data must be valid */
26746f9291ceSJung-uk Kim             if (!ssl_next_proto_validate(data, size)) {
26751f13597dSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
26761f13597dSJung-uk Kim                 return 0;
26771f13597dSJung-uk Kim             }
26786f9291ceSJung-uk Kim             if (s->
26796f9291ceSJung-uk Kim                 ctx->next_proto_select_cb(s, &selected, &selected_len, data,
26806f9291ceSJung-uk Kim                                           size,
26816f9291ceSJung-uk Kim                                           s->ctx->next_proto_select_cb_arg) !=
26826f9291ceSJung-uk Kim                 SSL_TLSEXT_ERR_OK) {
26831f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
26841f13597dSJung-uk Kim                 return 0;
26851f13597dSJung-uk Kim             }
26861f13597dSJung-uk Kim             s->next_proto_negotiated = OPENSSL_malloc(selected_len);
26876f9291ceSJung-uk Kim             if (!s->next_proto_negotiated) {
26881f13597dSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
26891f13597dSJung-uk Kim                 return 0;
26901f13597dSJung-uk Kim             }
26911f13597dSJung-uk Kim             memcpy(s->next_proto_negotiated, selected, selected_len);
26921f13597dSJung-uk Kim             s->next_proto_negotiated_len = selected_len;
26931f13597dSJung-uk Kim             s->s3->next_proto_neg_seen = 1;
26941f13597dSJung-uk Kim         }
26951f13597dSJung-uk Kim # endif
2696*7bded2dbSJung-uk Kim 
2697*7bded2dbSJung-uk Kim         else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
2698*7bded2dbSJung-uk Kim             unsigned len;
2699*7bded2dbSJung-uk Kim 
2700*7bded2dbSJung-uk Kim             /* We must have requested it. */
2701*7bded2dbSJung-uk Kim             if (s->alpn_client_proto_list == NULL) {
2702*7bded2dbSJung-uk Kim                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
2703*7bded2dbSJung-uk Kim                 return 0;
2704*7bded2dbSJung-uk Kim             }
2705*7bded2dbSJung-uk Kim             if (size < 4) {
2706*7bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
2707*7bded2dbSJung-uk Kim                 return 0;
2708*7bded2dbSJung-uk Kim             }
2709*7bded2dbSJung-uk Kim             /*-
2710*7bded2dbSJung-uk Kim              * The extension data consists of:
2711*7bded2dbSJung-uk Kim              *   uint16 list_length
2712*7bded2dbSJung-uk Kim              *   uint8 proto_length;
2713*7bded2dbSJung-uk Kim              *   uint8 proto[proto_length];
2714*7bded2dbSJung-uk Kim              */
2715*7bded2dbSJung-uk Kim             len = data[0];
2716*7bded2dbSJung-uk Kim             len <<= 8;
2717*7bded2dbSJung-uk Kim             len |= data[1];
2718*7bded2dbSJung-uk Kim             if (len != (unsigned)size - 2) {
2719*7bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
2720*7bded2dbSJung-uk Kim                 return 0;
2721*7bded2dbSJung-uk Kim             }
2722*7bded2dbSJung-uk Kim             len = data[2];
2723*7bded2dbSJung-uk Kim             if (len != (unsigned)size - 3) {
2724*7bded2dbSJung-uk Kim                 *al = TLS1_AD_DECODE_ERROR;
2725*7bded2dbSJung-uk Kim                 return 0;
2726*7bded2dbSJung-uk Kim             }
2727*7bded2dbSJung-uk Kim             if (s->s3->alpn_selected)
2728*7bded2dbSJung-uk Kim                 OPENSSL_free(s->s3->alpn_selected);
2729*7bded2dbSJung-uk Kim             s->s3->alpn_selected = OPENSSL_malloc(len);
2730*7bded2dbSJung-uk Kim             if (!s->s3->alpn_selected) {
2731*7bded2dbSJung-uk Kim                 *al = TLS1_AD_INTERNAL_ERROR;
2732*7bded2dbSJung-uk Kim                 return 0;
2733*7bded2dbSJung-uk Kim             }
2734*7bded2dbSJung-uk Kim             memcpy(s->s3->alpn_selected, data + 3, len);
2735*7bded2dbSJung-uk Kim             s->s3->alpn_selected_len = len;
2736*7bded2dbSJung-uk Kim         }
2737*7bded2dbSJung-uk Kim 
27386f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_renegotiate) {
27396a599222SSimon L. B. Nielsen             if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
27406a599222SSimon L. B. Nielsen                 return 0;
27416a599222SSimon L. B. Nielsen             renegotiate_seen = 1;
27426a599222SSimon L. B. Nielsen         }
27431f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
27446f9291ceSJung-uk Kim         else if (type == TLSEXT_TYPE_heartbeat) {
27456f9291ceSJung-uk Kim             switch (data[0]) {
27461f13597dSJung-uk Kim             case 0x01:         /* Server allows us to send HB requests */
27471f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
27481f13597dSJung-uk Kim                 break;
27491f13597dSJung-uk Kim             case 0x02:         /* Server doesn't accept HB requests */
27501f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
27511f13597dSJung-uk Kim                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
27521f13597dSJung-uk Kim                 break;
27536f9291ceSJung-uk Kim             default:
27546f9291ceSJung-uk Kim                 *al = SSL_AD_ILLEGAL_PARAMETER;
27551f13597dSJung-uk Kim                 return 0;
27561f13597dSJung-uk Kim             }
27571f13597dSJung-uk Kim         }
27581f13597dSJung-uk Kim # endif
275909286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
27606f9291ceSJung-uk Kim         else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
27616f9291ceSJung-uk Kim             if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al))
27621f13597dSJung-uk Kim                 return 0;
27631f13597dSJung-uk Kim         }
276409286989SJung-uk Kim # endif
2765*7bded2dbSJung-uk Kim         /*
2766*7bded2dbSJung-uk Kim          * If this extension type was not otherwise handled, but matches a
2767*7bded2dbSJung-uk Kim          * custom_cli_ext_record, then send it to the c callback
2768*7bded2dbSJung-uk Kim          */
2769*7bded2dbSJung-uk Kim         else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
2770*7bded2dbSJung-uk Kim             return 0;
27711f13597dSJung-uk Kim 
2772db522d3aSSimon L. B. Nielsen         data += size;
2773db522d3aSSimon L. B. Nielsen     }
2774db522d3aSSimon L. B. Nielsen 
27756f9291ceSJung-uk Kim     if (data != d + n) {
2776db522d3aSSimon L. B. Nielsen         *al = SSL_AD_DECODE_ERROR;
2777db522d3aSSimon L. B. Nielsen         return 0;
2778db522d3aSSimon L. B. Nielsen     }
2779db522d3aSSimon L. B. Nielsen 
27806f9291ceSJung-uk Kim     if (!s->hit && tlsext_servername == 1) {
27816f9291ceSJung-uk Kim         if (s->tlsext_hostname) {
27826f9291ceSJung-uk Kim             if (s->session->tlsext_hostname == NULL) {
2783db522d3aSSimon L. B. Nielsen                 s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
27846f9291ceSJung-uk Kim                 if (!s->session->tlsext_hostname) {
2785db522d3aSSimon L. B. Nielsen                     *al = SSL_AD_UNRECOGNIZED_NAME;
2786db522d3aSSimon L. B. Nielsen                     return 0;
2787db522d3aSSimon L. B. Nielsen                 }
27886f9291ceSJung-uk Kim             } else {
2789db522d3aSSimon L. B. Nielsen                 *al = SSL_AD_DECODE_ERROR;
2790db522d3aSSimon L. B. Nielsen                 return 0;
2791db522d3aSSimon L. B. Nielsen             }
2792db522d3aSSimon L. B. Nielsen         }
2793db522d3aSSimon L. B. Nielsen     }
2794db522d3aSSimon L. B. Nielsen 
2795db522d3aSSimon L. B. Nielsen     *p = data;
27966a599222SSimon L. B. Nielsen 
27976a599222SSimon L. B. Nielsen  ri_check:
27986a599222SSimon L. B. Nielsen 
27996f9291ceSJung-uk Kim     /*
28006f9291ceSJung-uk Kim      * Determine if we need to see RI. Strictly speaking if we want to avoid
28016f9291ceSJung-uk Kim      * an attack we should *always* see RI even on initial server hello
28026f9291ceSJung-uk Kim      * because the client doesn't see any renegotiation during an attack.
28036f9291ceSJung-uk Kim      * However this would mean we could not connect to any server which
28046f9291ceSJung-uk Kim      * doesn't support RI so for the immediate future tolerate RI absence on
28056f9291ceSJung-uk Kim      * initial connect only.
28066a599222SSimon L. B. Nielsen      */
28076f9291ceSJung-uk Kim     if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
28086f9291ceSJung-uk Kim         && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
28096a599222SSimon L. B. Nielsen         *al = SSL_AD_HANDSHAKE_FAILURE;
2810*7bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
28116a599222SSimon L. B. Nielsen                SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
28126a599222SSimon L. B. Nielsen         return 0;
28136a599222SSimon L. B. Nielsen     }
28146a599222SSimon L. B. Nielsen 
2815db522d3aSSimon L. B. Nielsen     return 1;
2816db522d3aSSimon L. B. Nielsen }
2817db522d3aSSimon L. B. Nielsen 
28181f13597dSJung-uk Kim int ssl_prepare_clienthello_tlsext(SSL *s)
28191f13597dSJung-uk Kim {
28201f13597dSJung-uk Kim 
28211f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
28221f13597dSJung-uk Kim     {
28231f13597dSJung-uk Kim         int r = 1;
28241f13597dSJung-uk Kim 
28256f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
28266f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
28276f9291ceSJung-uk Kim                                                          s->
28286f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
28291f13597dSJung-uk Kim             if (!r)
28301f13597dSJung-uk Kim                 return -1;
28311f13597dSJung-uk Kim         }
28321f13597dSJung-uk Kim 
28336f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
28346f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL) {
28356f9291ceSJung-uk Kim                 /* shouldn't really happen */
28361f13597dSJung-uk Kim                 OPENSSL_free(s->s3->client_opaque_prf_input);
28376f9291ceSJung-uk Kim             }
28381f13597dSJung-uk Kim 
28396f9291ceSJung-uk Kim             if (s->tlsext_opaque_prf_input_len == 0) {
28406f9291ceSJung-uk Kim                 /* dummy byte just to get non-NULL */
28416f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
28426f9291ceSJung-uk Kim             } else {
28436f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input =
28446f9291ceSJung-uk Kim                     BUF_memdup(s->tlsext_opaque_prf_input,
28456f9291ceSJung-uk Kim                                s->tlsext_opaque_prf_input_len);
28466f9291ceSJung-uk Kim             }
28476f9291ceSJung-uk Kim             if (s->s3->client_opaque_prf_input == NULL) {
28486f9291ceSJung-uk Kim                 SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
28496f9291ceSJung-uk Kim                        ERR_R_MALLOC_FAILURE);
28501f13597dSJung-uk Kim                 return -1;
28511f13597dSJung-uk Kim             }
28526f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len =
28536f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
28541f13597dSJung-uk Kim         }
28551f13597dSJung-uk Kim 
28561f13597dSJung-uk Kim         if (r == 2)
28576f9291ceSJung-uk Kim             /*
28586f9291ceSJung-uk Kim              * at callback's request, insist on receiving an appropriate
28596f9291ceSJung-uk Kim              * server opaque PRF input
28606f9291ceSJung-uk Kim              */
28616f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len =
28626f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len;
28631f13597dSJung-uk Kim     }
28641f13597dSJung-uk Kim # endif
28651f13597dSJung-uk Kim 
28661f13597dSJung-uk Kim     return 1;
28671f13597dSJung-uk Kim }
28681f13597dSJung-uk Kim 
28691f13597dSJung-uk Kim int ssl_prepare_serverhello_tlsext(SSL *s)
28701f13597dSJung-uk Kim {
28711f13597dSJung-uk Kim     return 1;
28721f13597dSJung-uk Kim }
28731f13597dSJung-uk Kim 
2874*7bded2dbSJung-uk Kim static int ssl_check_clienthello_tlsext_early(SSL *s)
2875db522d3aSSimon L. B. Nielsen {
2876db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
2877db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
2878db522d3aSSimon L. B. Nielsen 
28791f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
28806f9291ceSJung-uk Kim     /*
28816f9291ceSJung-uk Kim      * The handling of the ECPointFormats extension is done elsewhere, namely
28826f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
28831f13597dSJung-uk Kim      */
28846f9291ceSJung-uk Kim     /*
28856f9291ceSJung-uk Kim      * The handling of the EllipticCurves extension is done elsewhere, namely
28866f9291ceSJung-uk Kim      * in ssl3_choose_cipher in s3_lib.c.
28871f13597dSJung-uk Kim      */
28881f13597dSJung-uk Kim # endif
28891f13597dSJung-uk Kim 
2890db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
28916f9291ceSJung-uk Kim         ret =
28926f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
28936f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
28946f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
28956f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
28966f9291ceSJung-uk Kim         ret =
28976f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
28986f9291ceSJung-uk Kim                                                        s->
28996f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
2900db522d3aSSimon L. B. Nielsen 
29011f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
29021f13597dSJung-uk Kim     {
29036f9291ceSJung-uk Kim         /*
29046f9291ceSJung-uk Kim          * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we
29056f9291ceSJung-uk Kim          * might be sending an alert in response to the client hello, so this
29066f9291ceSJung-uk Kim          * has to happen here in ssl_check_clienthello_tlsext_early().
29076f9291ceSJung-uk Kim          */
29081f13597dSJung-uk Kim 
29091f13597dSJung-uk Kim         int r = 1;
29101f13597dSJung-uk Kim 
29116f9291ceSJung-uk Kim         if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
29126f9291ceSJung-uk Kim             r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
29136f9291ceSJung-uk Kim                                                          s->
29146f9291ceSJung-uk Kim                                                          ctx->tlsext_opaque_prf_input_callback_arg);
29156f9291ceSJung-uk Kim             if (!r) {
29161f13597dSJung-uk Kim                 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
29171f13597dSJung-uk Kim                 al = SSL_AD_INTERNAL_ERROR;
29181f13597dSJung-uk Kim                 goto err;
29191f13597dSJung-uk Kim             }
29201f13597dSJung-uk Kim         }
29211f13597dSJung-uk Kim 
29226f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input != NULL) {
29236f9291ceSJung-uk Kim             /* shouldn't really happen */
29241f13597dSJung-uk Kim             OPENSSL_free(s->s3->server_opaque_prf_input);
29256f9291ceSJung-uk Kim         }
29261f13597dSJung-uk Kim         s->s3->server_opaque_prf_input = NULL;
29271f13597dSJung-uk Kim 
29286f9291ceSJung-uk Kim         if (s->tlsext_opaque_prf_input != NULL) {
29291f13597dSJung-uk Kim             if (s->s3->client_opaque_prf_input != NULL &&
29306f9291ceSJung-uk Kim                 s->s3->client_opaque_prf_input_len ==
29316f9291ceSJung-uk Kim                 s->tlsext_opaque_prf_input_len) {
29326f9291ceSJung-uk Kim                 /*
29336f9291ceSJung-uk Kim                  * can only use this extension if we have a server opaque PRF
29346f9291ceSJung-uk Kim                  * input of the same length as the client opaque PRF input!
29356f9291ceSJung-uk Kim                  */
29361f13597dSJung-uk Kim 
29376f9291ceSJung-uk Kim                 if (s->tlsext_opaque_prf_input_len == 0) {
29386f9291ceSJung-uk Kim                     /* dummy byte just to get non-NULL */
29396f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
29406f9291ceSJung-uk Kim                 } else {
29416f9291ceSJung-uk Kim                     s->s3->server_opaque_prf_input =
29426f9291ceSJung-uk Kim                         BUF_memdup(s->tlsext_opaque_prf_input,
29436f9291ceSJung-uk Kim                                    s->tlsext_opaque_prf_input_len);
29446f9291ceSJung-uk Kim                 }
29456f9291ceSJung-uk Kim                 if (s->s3->server_opaque_prf_input == NULL) {
29461f13597dSJung-uk Kim                     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
29471f13597dSJung-uk Kim                     al = SSL_AD_INTERNAL_ERROR;
29481f13597dSJung-uk Kim                     goto err;
29491f13597dSJung-uk Kim                 }
29506f9291ceSJung-uk Kim                 s->s3->server_opaque_prf_input_len =
29516f9291ceSJung-uk Kim                     s->tlsext_opaque_prf_input_len;
29521f13597dSJung-uk Kim             }
29531f13597dSJung-uk Kim         }
29541f13597dSJung-uk Kim 
29556f9291ceSJung-uk Kim         if (r == 2 && s->s3->server_opaque_prf_input == NULL) {
29566f9291ceSJung-uk Kim             /*
29576f9291ceSJung-uk Kim              * The callback wants to enforce use of the extension, but we
29586f9291ceSJung-uk Kim              * can't do that with the client opaque PRF input; abort the
29596f9291ceSJung-uk Kim              * handshake.
29601f13597dSJung-uk Kim              */
29611f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
29621f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
29631f13597dSJung-uk Kim         }
29641f13597dSJung-uk Kim     }
29651f13597dSJung-uk Kim 
2966db522d3aSSimon L. B. Nielsen  err:
296709286989SJung-uk Kim # endif
29686f9291ceSJung-uk Kim     switch (ret) {
2969db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
2970db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
2971db522d3aSSimon L. B. Nielsen         return -1;
2972db522d3aSSimon L. B. Nielsen 
2973db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
2974db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
2975db522d3aSSimon L. B. Nielsen         return 1;
2976db522d3aSSimon L. B. Nielsen 
2977db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
2978db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
2979db522d3aSSimon L. B. Nielsen     default:
2980db522d3aSSimon L. B. Nielsen         return 1;
2981db522d3aSSimon L. B. Nielsen     }
2982db522d3aSSimon L. B. Nielsen }
2983db522d3aSSimon L. B. Nielsen 
2984*7bded2dbSJung-uk Kim int tls1_set_server_sigalgs(SSL *s)
2985*7bded2dbSJung-uk Kim {
2986*7bded2dbSJung-uk Kim     int al;
2987*7bded2dbSJung-uk Kim     size_t i;
2988*7bded2dbSJung-uk Kim     /* Clear any shared sigtnature algorithms */
2989*7bded2dbSJung-uk Kim     if (s->cert->shared_sigalgs) {
2990*7bded2dbSJung-uk Kim         OPENSSL_free(s->cert->shared_sigalgs);
2991*7bded2dbSJung-uk Kim         s->cert->shared_sigalgs = NULL;
2992*7bded2dbSJung-uk Kim         s->cert->shared_sigalgslen = 0;
2993*7bded2dbSJung-uk Kim     }
2994*7bded2dbSJung-uk Kim     /* Clear certificate digests and validity flags */
2995*7bded2dbSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
2996*7bded2dbSJung-uk Kim         s->cert->pkeys[i].digest = NULL;
2997*7bded2dbSJung-uk Kim         s->cert->pkeys[i].valid_flags = 0;
2998*7bded2dbSJung-uk Kim     }
2999*7bded2dbSJung-uk Kim 
3000*7bded2dbSJung-uk Kim     /* If sigalgs received process it. */
3001*7bded2dbSJung-uk Kim     if (s->cert->peer_sigalgs) {
3002*7bded2dbSJung-uk Kim         if (!tls1_process_sigalgs(s)) {
3003*7bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
3004*7bded2dbSJung-uk Kim             al = SSL_AD_INTERNAL_ERROR;
3005*7bded2dbSJung-uk Kim             goto err;
3006*7bded2dbSJung-uk Kim         }
3007*7bded2dbSJung-uk Kim         /* Fatal error is no shared signature algorithms */
3008*7bded2dbSJung-uk Kim         if (!s->cert->shared_sigalgs) {
3009*7bded2dbSJung-uk Kim             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
3010*7bded2dbSJung-uk Kim                    SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
3011*7bded2dbSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
3012*7bded2dbSJung-uk Kim             goto err;
3013*7bded2dbSJung-uk Kim         }
3014*7bded2dbSJung-uk Kim     } else
3015*7bded2dbSJung-uk Kim         ssl_cert_set_default_md(s->cert);
3016*7bded2dbSJung-uk Kim     return 1;
3017*7bded2dbSJung-uk Kim  err:
3018*7bded2dbSJung-uk Kim     ssl3_send_alert(s, SSL3_AL_FATAL, al);
3019*7bded2dbSJung-uk Kim     return 0;
3020*7bded2dbSJung-uk Kim }
3021*7bded2dbSJung-uk Kim 
302209286989SJung-uk Kim int ssl_check_clienthello_tlsext_late(SSL *s)
302309286989SJung-uk Kim {
302409286989SJung-uk Kim     int ret = SSL_TLSEXT_ERR_OK;
302509286989SJung-uk Kim     int al;
302609286989SJung-uk Kim 
30276f9291ceSJung-uk Kim     /*
30286f9291ceSJung-uk Kim      * If status request then ask callback what to do. Note: this must be
3029*7bded2dbSJung-uk Kim      * called after servername callbacks in case the certificate has changed,
3030*7bded2dbSJung-uk Kim      * and must be called after the cipher has been chosen because this may
3031*7bded2dbSJung-uk Kim      * influence which certificate is sent
303209286989SJung-uk Kim      */
30336f9291ceSJung-uk Kim     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
303409286989SJung-uk Kim         int r;
303509286989SJung-uk Kim         CERT_PKEY *certpkey;
303609286989SJung-uk Kim         certpkey = ssl_get_server_send_pkey(s);
303709286989SJung-uk Kim         /* If no certificate can't return certificate status */
30386f9291ceSJung-uk Kim         if (certpkey == NULL) {
303909286989SJung-uk Kim             s->tlsext_status_expected = 0;
304009286989SJung-uk Kim             return 1;
304109286989SJung-uk Kim         }
30426f9291ceSJung-uk Kim         /*
30436f9291ceSJung-uk Kim          * Set current certificate to one we will use so SSL_get_certificate
30446f9291ceSJung-uk Kim          * et al can pick it up.
304509286989SJung-uk Kim          */
304609286989SJung-uk Kim         s->cert->key = certpkey;
304709286989SJung-uk Kim         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
30486f9291ceSJung-uk Kim         switch (r) {
304909286989SJung-uk Kim             /* We don't want to send a status request response */
305009286989SJung-uk Kim         case SSL_TLSEXT_ERR_NOACK:
305109286989SJung-uk Kim             s->tlsext_status_expected = 0;
305209286989SJung-uk Kim             break;
305309286989SJung-uk Kim             /* status request response should be sent */
305409286989SJung-uk Kim         case SSL_TLSEXT_ERR_OK:
305509286989SJung-uk Kim             if (s->tlsext_ocsp_resp)
305609286989SJung-uk Kim                 s->tlsext_status_expected = 1;
305709286989SJung-uk Kim             else
305809286989SJung-uk Kim                 s->tlsext_status_expected = 0;
305909286989SJung-uk Kim             break;
306009286989SJung-uk Kim             /* something bad happened */
306109286989SJung-uk Kim         case SSL_TLSEXT_ERR_ALERT_FATAL:
306209286989SJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
306309286989SJung-uk Kim             al = SSL_AD_INTERNAL_ERROR;
306409286989SJung-uk Kim             goto err;
306509286989SJung-uk Kim         }
30666f9291ceSJung-uk Kim     } else
306709286989SJung-uk Kim         s->tlsext_status_expected = 0;
306809286989SJung-uk Kim 
306909286989SJung-uk Kim  err:
30706f9291ceSJung-uk Kim     switch (ret) {
307109286989SJung-uk Kim     case SSL_TLSEXT_ERR_ALERT_FATAL:
307209286989SJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
307309286989SJung-uk Kim         return -1;
307409286989SJung-uk Kim 
307509286989SJung-uk Kim     case SSL_TLSEXT_ERR_ALERT_WARNING:
307609286989SJung-uk Kim         ssl3_send_alert(s, SSL3_AL_WARNING, al);
307709286989SJung-uk Kim         return 1;
307809286989SJung-uk Kim 
307909286989SJung-uk Kim     default:
308009286989SJung-uk Kim         return 1;
308109286989SJung-uk Kim     }
308209286989SJung-uk Kim }
308309286989SJung-uk Kim 
3084db522d3aSSimon L. B. Nielsen int ssl_check_serverhello_tlsext(SSL *s)
3085db522d3aSSimon L. B. Nielsen {
3086db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
3087db522d3aSSimon L. B. Nielsen     int al = SSL_AD_UNRECOGNIZED_NAME;
3088db522d3aSSimon L. B. Nielsen 
30891f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC
30906f9291ceSJung-uk Kim     /*
30916f9291ceSJung-uk Kim      * If we are client and using an elliptic curve cryptography cipher
30926f9291ceSJung-uk Kim      * suite, then if server returns an EC point formats lists extension it
30936f9291ceSJung-uk Kim      * must contain uncompressed.
30941f13597dSJung-uk Kim      */
30951f13597dSJung-uk Kim     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
30961f13597dSJung-uk Kim     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
30976f9291ceSJung-uk Kim     if ((s->tlsext_ecpointformatlist != NULL)
30986f9291ceSJung-uk Kim         && (s->tlsext_ecpointformatlist_length > 0)
30996f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist != NULL)
31006f9291ceSJung-uk Kim         && (s->session->tlsext_ecpointformatlist_length > 0)
31016f9291ceSJung-uk Kim         && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe))
31026f9291ceSJung-uk Kim             || (alg_a & SSL_aECDSA))) {
31031f13597dSJung-uk Kim         /* we are using an ECC cipher */
31041f13597dSJung-uk Kim         size_t i;
31051f13597dSJung-uk Kim         unsigned char *list;
31061f13597dSJung-uk Kim         int found_uncompressed = 0;
31071f13597dSJung-uk Kim         list = s->session->tlsext_ecpointformatlist;
31086f9291ceSJung-uk Kim         for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
31096f9291ceSJung-uk Kim             if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
31101f13597dSJung-uk Kim                 found_uncompressed = 1;
31111f13597dSJung-uk Kim                 break;
31121f13597dSJung-uk Kim             }
31131f13597dSJung-uk Kim         }
31146f9291ceSJung-uk Kim         if (!found_uncompressed) {
31156f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
31166f9291ceSJung-uk Kim                    SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
31171f13597dSJung-uk Kim             return -1;
31181f13597dSJung-uk Kim         }
31191f13597dSJung-uk Kim     }
31201f13597dSJung-uk Kim     ret = SSL_TLSEXT_ERR_OK;
31211f13597dSJung-uk Kim # endif                         /* OPENSSL_NO_EC */
31221f13597dSJung-uk Kim 
3123db522d3aSSimon L. B. Nielsen     if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
31246f9291ceSJung-uk Kim         ret =
31256f9291ceSJung-uk Kim             s->ctx->tlsext_servername_callback(s, &al,
31266f9291ceSJung-uk Kim                                                s->ctx->tlsext_servername_arg);
31276f9291ceSJung-uk Kim     else if (s->initial_ctx != NULL
31286f9291ceSJung-uk Kim              && s->initial_ctx->tlsext_servername_callback != 0)
31296f9291ceSJung-uk Kim         ret =
31306f9291ceSJung-uk Kim             s->initial_ctx->tlsext_servername_callback(s, &al,
31316f9291ceSJung-uk Kim                                                        s->
31326f9291ceSJung-uk Kim                                                        initial_ctx->tlsext_servername_arg);
3133db522d3aSSimon L. B. Nielsen 
31341f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
31356f9291ceSJung-uk Kim     if (s->s3->server_opaque_prf_input_len > 0) {
31366f9291ceSJung-uk Kim         /*
31376f9291ceSJung-uk Kim          * This case may indicate that we, as a client, want to insist on
31386f9291ceSJung-uk Kim          * using opaque PRF inputs. So first verify that we really have a
31396f9291ceSJung-uk Kim          * value from the server too.
31406f9291ceSJung-uk Kim          */
31411f13597dSJung-uk Kim 
31426f9291ceSJung-uk Kim         if (s->s3->server_opaque_prf_input == NULL) {
31431f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
31441f13597dSJung-uk Kim             al = SSL_AD_HANDSHAKE_FAILURE;
31451f13597dSJung-uk Kim         }
31461f13597dSJung-uk Kim 
31476f9291ceSJung-uk Kim         /*
31486f9291ceSJung-uk Kim          * Anytime the server *has* sent an opaque PRF input, we need to
31496f9291ceSJung-uk Kim          * check that we have a client opaque PRF input of the same size.
31506f9291ceSJung-uk Kim          */
31511f13597dSJung-uk Kim         if (s->s3->client_opaque_prf_input == NULL ||
31526f9291ceSJung-uk Kim             s->s3->client_opaque_prf_input_len !=
31536f9291ceSJung-uk Kim             s->s3->server_opaque_prf_input_len) {
31541f13597dSJung-uk Kim             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
31551f13597dSJung-uk Kim             al = SSL_AD_ILLEGAL_PARAMETER;
31561f13597dSJung-uk Kim         }
31571f13597dSJung-uk Kim     }
31581f13597dSJung-uk Kim # endif
31591f13597dSJung-uk Kim 
31606f9291ceSJung-uk Kim     /*
31616f9291ceSJung-uk Kim      * If we've requested certificate status and we wont get one tell the
31626f9291ceSJung-uk Kim      * callback
3163db522d3aSSimon L. B. Nielsen      */
3164db522d3aSSimon L. B. Nielsen     if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
31656f9291ceSJung-uk Kim         && s->ctx && s->ctx->tlsext_status_cb) {
3166db522d3aSSimon L. B. Nielsen         int r;
31676f9291ceSJung-uk Kim         /*
31686f9291ceSJung-uk Kim          * Set resp to NULL, resplen to -1 so callback knows there is no
31696f9291ceSJung-uk Kim          * response.
3170db522d3aSSimon L. B. Nielsen          */
31716f9291ceSJung-uk Kim         if (s->tlsext_ocsp_resp) {
3172db522d3aSSimon L. B. Nielsen             OPENSSL_free(s->tlsext_ocsp_resp);
3173db522d3aSSimon L. B. Nielsen             s->tlsext_ocsp_resp = NULL;
3174db522d3aSSimon L. B. Nielsen         }
3175db522d3aSSimon L. B. Nielsen         s->tlsext_ocsp_resplen = -1;
3176db522d3aSSimon L. B. Nielsen         r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
31776f9291ceSJung-uk Kim         if (r == 0) {
3178db522d3aSSimon L. B. Nielsen             al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
3179db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
3180db522d3aSSimon L. B. Nielsen         }
31816f9291ceSJung-uk Kim         if (r < 0) {
3182db522d3aSSimon L. B. Nielsen             al = SSL_AD_INTERNAL_ERROR;
3183db522d3aSSimon L. B. Nielsen             ret = SSL_TLSEXT_ERR_ALERT_FATAL;
3184db522d3aSSimon L. B. Nielsen         }
3185db522d3aSSimon L. B. Nielsen     }
3186db522d3aSSimon L. B. Nielsen 
31876f9291ceSJung-uk Kim     switch (ret) {
3188db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_FATAL:
3189db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_FATAL, al);
3190db522d3aSSimon L. B. Nielsen         return -1;
3191db522d3aSSimon L. B. Nielsen 
3192db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_ALERT_WARNING:
3193db522d3aSSimon L. B. Nielsen         ssl3_send_alert(s, SSL3_AL_WARNING, al);
3194db522d3aSSimon L. B. Nielsen         return 1;
3195db522d3aSSimon L. B. Nielsen 
3196db522d3aSSimon L. B. Nielsen     case SSL_TLSEXT_ERR_NOACK:
3197db522d3aSSimon L. B. Nielsen         s->servername_done = 0;
3198db522d3aSSimon L. B. Nielsen     default:
3199db522d3aSSimon L. B. Nielsen         return 1;
3200db522d3aSSimon L. B. Nielsen     }
3201db522d3aSSimon L. B. Nielsen }
3202db522d3aSSimon L. B. Nielsen 
3203*7bded2dbSJung-uk Kim int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
3204*7bded2dbSJung-uk Kim                                  int n)
3205*7bded2dbSJung-uk Kim {
3206*7bded2dbSJung-uk Kim     int al = -1;
3207*7bded2dbSJung-uk Kim     if (s->version < SSL3_VERSION)
3208*7bded2dbSJung-uk Kim         return 1;
3209*7bded2dbSJung-uk Kim     if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) {
3210*7bded2dbSJung-uk Kim         ssl3_send_alert(s, SSL3_AL_FATAL, al);
3211*7bded2dbSJung-uk Kim         return 0;
3212*7bded2dbSJung-uk Kim     }
3213*7bded2dbSJung-uk Kim 
3214*7bded2dbSJung-uk Kim     if (ssl_check_serverhello_tlsext(s) <= 0) {
3215*7bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
3216*7bded2dbSJung-uk Kim         return 0;
3217*7bded2dbSJung-uk Kim     }
3218*7bded2dbSJung-uk Kim     return 1;
3219*7bded2dbSJung-uk Kim }
3220*7bded2dbSJung-uk Kim 
32216f9291ceSJung-uk Kim /*-
32226f9291ceSJung-uk Kim  * Since the server cache lookup is done early on in the processing of the
32231f13597dSJung-uk Kim  * ClientHello, and other operations depend on the result, we need to handle
32241f13597dSJung-uk Kim  * any TLS session ticket extension at the same time.
32251f13597dSJung-uk Kim  *
32261f13597dSJung-uk Kim  *   session_id: points at the session ID in the ClientHello. This code will
32271f13597dSJung-uk Kim  *       read past the end of this in order to parse out the session ticket
32281f13597dSJung-uk Kim  *       extension, if any.
32291f13597dSJung-uk Kim  *   len: the length of the session ID.
32301f13597dSJung-uk Kim  *   limit: a pointer to the first byte after the ClientHello.
32311f13597dSJung-uk Kim  *   ret: (output) on return, if a ticket was decrypted, then this is set to
32321f13597dSJung-uk Kim  *       point to the resulting session.
32331f13597dSJung-uk Kim  *
32341f13597dSJung-uk Kim  * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
32351f13597dSJung-uk Kim  * ciphersuite, in which case we have no use for session tickets and one will
32361f13597dSJung-uk Kim  * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
32371f13597dSJung-uk Kim  *
32381f13597dSJung-uk Kim  * Returns:
32391f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
32401f13597dSJung-uk Kim  *    0: no ticket was found (or was ignored, based on settings).
32411f13597dSJung-uk Kim  *    1: a zero length extension was found, indicating that the client supports
32421f13597dSJung-uk Kim  *       session tickets but doesn't currently have one to offer.
32431f13597dSJung-uk Kim  *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
32441f13597dSJung-uk Kim  *       couldn't be decrypted because of a non-fatal error.
32451f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *ret was set.
32461f13597dSJung-uk Kim  *
32471f13597dSJung-uk Kim  * Side effects:
32481f13597dSJung-uk Kim  *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
32491f13597dSJung-uk Kim  *   a new session ticket to the client because the client indicated support
32501f13597dSJung-uk Kim  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
32511f13597dSJung-uk Kim  *   a session ticket or we couldn't use the one it gave us, or if
32521f13597dSJung-uk Kim  *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
32531f13597dSJung-uk Kim  *   Otherwise, s->tlsext_ticket_expected is set to 0.
3254db522d3aSSimon L. B. Nielsen  */
3255db522d3aSSimon L. B. Nielsen int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
3256db522d3aSSimon L. B. Nielsen                         const unsigned char *limit, SSL_SESSION **ret)
3257db522d3aSSimon L. B. Nielsen {
3258db522d3aSSimon L. B. Nielsen     /* Point after session ID in client hello */
3259db522d3aSSimon L. B. Nielsen     const unsigned char *p = session_id + len;
3260db522d3aSSimon L. B. Nielsen     unsigned short i;
3261db522d3aSSimon L. B. Nielsen 
32621f13597dSJung-uk Kim     *ret = NULL;
32631f13597dSJung-uk Kim     s->tlsext_ticket_expected = 0;
32641f13597dSJung-uk Kim 
32656f9291ceSJung-uk Kim     /*
32666f9291ceSJung-uk Kim      * If tickets disabled behave as if no ticket present to permit stateful
32676f9291ceSJung-uk Kim      * resumption.
3268db522d3aSSimon L. B. Nielsen      */
3269db522d3aSSimon L. B. Nielsen     if (SSL_get_options(s) & SSL_OP_NO_TICKET)
32701f13597dSJung-uk Kim         return 0;
3271db522d3aSSimon L. B. Nielsen     if ((s->version <= SSL3_VERSION) || !limit)
32721f13597dSJung-uk Kim         return 0;
3273db522d3aSSimon L. B. Nielsen     if (p >= limit)
3274db522d3aSSimon L. B. Nielsen         return -1;
32756a599222SSimon L. B. Nielsen     /* Skip past DTLS cookie */
3276*7bded2dbSJung-uk Kim     if (SSL_IS_DTLS(s)) {
32776a599222SSimon L. B. Nielsen         i = *(p++);
32786a599222SSimon L. B. Nielsen         p += i;
32796a599222SSimon L. B. Nielsen         if (p >= limit)
32806a599222SSimon L. B. Nielsen             return -1;
32816a599222SSimon L. B. Nielsen     }
3282db522d3aSSimon L. B. Nielsen     /* Skip past cipher list */
3283db522d3aSSimon L. B. Nielsen     n2s(p, i);
3284db522d3aSSimon L. B. Nielsen     p += i;
3285db522d3aSSimon L. B. Nielsen     if (p >= limit)
3286db522d3aSSimon L. B. Nielsen         return -1;
3287db522d3aSSimon L. B. Nielsen     /* Skip past compression algorithm list */
3288db522d3aSSimon L. B. Nielsen     i = *(p++);
3289db522d3aSSimon L. B. Nielsen     p += i;
3290db522d3aSSimon L. B. Nielsen     if (p > limit)
3291db522d3aSSimon L. B. Nielsen         return -1;
3292db522d3aSSimon L. B. Nielsen     /* Now at start of extensions */
3293db522d3aSSimon L. B. Nielsen     if ((p + 2) >= limit)
32941f13597dSJung-uk Kim         return 0;
3295db522d3aSSimon L. B. Nielsen     n2s(p, i);
32966f9291ceSJung-uk Kim     while ((p + 4) <= limit) {
3297db522d3aSSimon L. B. Nielsen         unsigned short type, size;
3298db522d3aSSimon L. B. Nielsen         n2s(p, type);
3299db522d3aSSimon L. B. Nielsen         n2s(p, size);
3300db522d3aSSimon L. B. Nielsen         if (p + size > limit)
33011f13597dSJung-uk Kim             return 0;
33026f9291ceSJung-uk Kim         if (type == TLSEXT_TYPE_session_ticket) {
33031f13597dSJung-uk Kim             int r;
33046f9291ceSJung-uk Kim             if (size == 0) {
33056f9291ceSJung-uk Kim                 /*
33066f9291ceSJung-uk Kim                  * The client will accept a ticket but doesn't currently have
33076f9291ceSJung-uk Kim                  * one.
33086f9291ceSJung-uk Kim                  */
3309db522d3aSSimon L. B. Nielsen                 s->tlsext_ticket_expected = 1;
33101f13597dSJung-uk Kim                 return 1;
3311db522d3aSSimon L. B. Nielsen             }
33126f9291ceSJung-uk Kim             if (s->tls_session_secret_cb) {
33136f9291ceSJung-uk Kim                 /*
33146f9291ceSJung-uk Kim                  * Indicate that the ticket couldn't be decrypted rather than
33156f9291ceSJung-uk Kim                  * generating the session from ticket now, trigger
33166f9291ceSJung-uk Kim                  * abbreviated handshake based on external mechanism to
33176f9291ceSJung-uk Kim                  * calculate the master secret later.
33186f9291ceSJung-uk Kim                  */
33191f13597dSJung-uk Kim                 return 2;
33201f13597dSJung-uk Kim             }
33211f13597dSJung-uk Kim             r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
33226f9291ceSJung-uk Kim             switch (r) {
33231f13597dSJung-uk Kim             case 2:            /* ticket couldn't be decrypted */
33241f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
33251f13597dSJung-uk Kim                 return 2;
33261f13597dSJung-uk Kim             case 3:            /* ticket was decrypted */
33271f13597dSJung-uk Kim                 return r;
33281f13597dSJung-uk Kim             case 4:            /* ticket decrypted but need to renew */
33291f13597dSJung-uk Kim                 s->tlsext_ticket_expected = 1;
33301f13597dSJung-uk Kim                 return 3;
33311f13597dSJung-uk Kim             default:           /* fatal error */
33321f13597dSJung-uk Kim                 return -1;
33331f13597dSJung-uk Kim             }
3334db522d3aSSimon L. B. Nielsen         }
3335db522d3aSSimon L. B. Nielsen         p += size;
3336db522d3aSSimon L. B. Nielsen     }
33371f13597dSJung-uk Kim     return 0;
3338db522d3aSSimon L. B. Nielsen }
3339db522d3aSSimon L. B. Nielsen 
33406f9291ceSJung-uk Kim /*-
33416f9291ceSJung-uk Kim  * tls_decrypt_ticket attempts to decrypt a session ticket.
33421f13597dSJung-uk Kim  *
33431f13597dSJung-uk Kim  *   etick: points to the body of the session ticket extension.
33441f13597dSJung-uk Kim  *   eticklen: the length of the session tickets extenion.
33451f13597dSJung-uk Kim  *   sess_id: points at the session ID.
33461f13597dSJung-uk Kim  *   sesslen: the length of the session ID.
33471f13597dSJung-uk Kim  *   psess: (output) on return, if a ticket was decrypted, then this is set to
33481f13597dSJung-uk Kim  *       point to the resulting session.
33491f13597dSJung-uk Kim  *
33501f13597dSJung-uk Kim  * Returns:
33511f13597dSJung-uk Kim  *   -1: fatal error, either from parsing or decrypting the ticket.
33521f13597dSJung-uk Kim  *    2: the ticket couldn't be decrypted.
33531f13597dSJung-uk Kim  *    3: a ticket was successfully decrypted and *psess was set.
33541f13597dSJung-uk Kim  *    4: same as 3, but the ticket needs to be renewed.
33551f13597dSJung-uk Kim  */
33566f9291ceSJung-uk Kim static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
33576f9291ceSJung-uk Kim                               int eticklen, const unsigned char *sess_id,
33586f9291ceSJung-uk Kim                               int sesslen, SSL_SESSION **psess)
3359db522d3aSSimon L. B. Nielsen {
3360db522d3aSSimon L. B. Nielsen     SSL_SESSION *sess;
3361db522d3aSSimon L. B. Nielsen     unsigned char *sdec;
3362db522d3aSSimon L. B. Nielsen     const unsigned char *p;
3363db522d3aSSimon L. B. Nielsen     int slen, mlen, renew_ticket = 0;
3364db522d3aSSimon L. B. Nielsen     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
3365db522d3aSSimon L. B. Nielsen     HMAC_CTX hctx;
3366db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX ctx;
33676a599222SSimon L. B. Nielsen     SSL_CTX *tctx = s->initial_ctx;
3368db522d3aSSimon L. B. Nielsen     /* Need at least keyname + iv + some encrypted data */
3369db522d3aSSimon L. B. Nielsen     if (eticklen < 48)
33701f13597dSJung-uk Kim         return 2;
3371db522d3aSSimon L. B. Nielsen     /* Initialize session ticket encryption and HMAC contexts */
3372db522d3aSSimon L. B. Nielsen     HMAC_CTX_init(&hctx);
3373db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_init(&ctx);
33746f9291ceSJung-uk Kim     if (tctx->tlsext_ticket_key_cb) {
3375db522d3aSSimon L. B. Nielsen         unsigned char *nctick = (unsigned char *)etick;
33766a599222SSimon L. B. Nielsen         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
3377db522d3aSSimon L. B. Nielsen                                             &ctx, &hctx, 0);
3378db522d3aSSimon L. B. Nielsen         if (rv < 0)
3379db522d3aSSimon L. B. Nielsen             return -1;
3380db522d3aSSimon L. B. Nielsen         if (rv == 0)
33811f13597dSJung-uk Kim             return 2;
3382db522d3aSSimon L. B. Nielsen         if (rv == 2)
3383db522d3aSSimon L. B. Nielsen             renew_ticket = 1;
33846f9291ceSJung-uk Kim     } else {
3385db522d3aSSimon L. B. Nielsen         /* Check key name matches */
33866a599222SSimon L. B. Nielsen         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
33871f13597dSJung-uk Kim             return 2;
33886a599222SSimon L. B. Nielsen         HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
3389db522d3aSSimon L. B. Nielsen                      tlsext_tick_md(), NULL);
3390db522d3aSSimon L. B. Nielsen         EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
33916a599222SSimon L. B. Nielsen                            tctx->tlsext_tick_aes_key, etick + 16);
3392db522d3aSSimon L. B. Nielsen     }
33936f9291ceSJung-uk Kim     /*
33946f9291ceSJung-uk Kim      * Attempt to process session ticket, first conduct sanity and integrity
33956f9291ceSJung-uk Kim      * checks on ticket.
3396db522d3aSSimon L. B. Nielsen      */
3397db522d3aSSimon L. B. Nielsen     mlen = HMAC_size(&hctx);
33986f9291ceSJung-uk Kim     if (mlen < 0) {
33991f13597dSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
34001f13597dSJung-uk Kim         return -1;
34011f13597dSJung-uk Kim     }
3402db522d3aSSimon L. B. Nielsen     eticklen -= mlen;
3403db522d3aSSimon L. B. Nielsen     /* Check HMAC of encrypted ticket */
3404db522d3aSSimon L. B. Nielsen     HMAC_Update(&hctx, etick, eticklen);
3405db522d3aSSimon L. B. Nielsen     HMAC_Final(&hctx, tick_hmac, NULL);
3406db522d3aSSimon L. B. Nielsen     HMAC_CTX_cleanup(&hctx);
34076f9291ceSJung-uk Kim     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
3408fa5fddf1SJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
34091f13597dSJung-uk Kim         return 2;
3410fa5fddf1SJung-uk Kim     }
3411db522d3aSSimon L. B. Nielsen     /* Attempt to decrypt session data */
3412db522d3aSSimon L. B. Nielsen     /* Move p after IV to start of encrypted ticket, update length */
3413db522d3aSSimon L. B. Nielsen     p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
3414db522d3aSSimon L. B. Nielsen     eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
3415db522d3aSSimon L. B. Nielsen     sdec = OPENSSL_malloc(eticklen);
34166f9291ceSJung-uk Kim     if (!sdec) {
3417db522d3aSSimon L. B. Nielsen         EVP_CIPHER_CTX_cleanup(&ctx);
3418db522d3aSSimon L. B. Nielsen         return -1;
3419db522d3aSSimon L. B. Nielsen     }
3420db522d3aSSimon L. B. Nielsen     EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
34216f9291ceSJung-uk Kim     if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
3422a93cbc2bSJung-uk Kim         EVP_CIPHER_CTX_cleanup(&ctx);
3423a93cbc2bSJung-uk Kim         OPENSSL_free(sdec);
34241f13597dSJung-uk Kim         return 2;
3425a93cbc2bSJung-uk Kim     }
3426db522d3aSSimon L. B. Nielsen     slen += mlen;
3427db522d3aSSimon L. B. Nielsen     EVP_CIPHER_CTX_cleanup(&ctx);
3428db522d3aSSimon L. B. Nielsen     p = sdec;
3429db522d3aSSimon L. B. Nielsen 
3430db522d3aSSimon L. B. Nielsen     sess = d2i_SSL_SESSION(NULL, &p, slen);
3431db522d3aSSimon L. B. Nielsen     OPENSSL_free(sdec);
34326f9291ceSJung-uk Kim     if (sess) {
34336f9291ceSJung-uk Kim         /*
34346f9291ceSJung-uk Kim          * The session ID, if non-empty, is used by some clients to detect
34356f9291ceSJung-uk Kim          * that the ticket has been accepted. So we copy it to the session
34366f9291ceSJung-uk Kim          * structure. If it is empty set length to zero as required by
34376f9291ceSJung-uk Kim          * standard.
3438db522d3aSSimon L. B. Nielsen          */
3439db522d3aSSimon L. B. Nielsen         if (sesslen)
3440db522d3aSSimon L. B. Nielsen             memcpy(sess->session_id, sess_id, sesslen);
3441db522d3aSSimon L. B. Nielsen         sess->session_id_length = sesslen;
3442db522d3aSSimon L. B. Nielsen         *psess = sess;
34431f13597dSJung-uk Kim         if (renew_ticket)
34441f13597dSJung-uk Kim             return 4;
34451f13597dSJung-uk Kim         else
34461f13597dSJung-uk Kim             return 3;
34471f13597dSJung-uk Kim     }
34481f13597dSJung-uk Kim     ERR_clear_error();
34496f9291ceSJung-uk Kim     /*
34506f9291ceSJung-uk Kim      * For session parse failure, indicate that we need to send a new ticket.
34516f9291ceSJung-uk Kim      */
34521f13597dSJung-uk Kim     return 2;
34531f13597dSJung-uk Kim }
34541f13597dSJung-uk Kim 
34551f13597dSJung-uk Kim /* Tables to translate from NIDs to TLS v1.2 ids */
34561f13597dSJung-uk Kim 
34576f9291ceSJung-uk Kim typedef struct {
34581f13597dSJung-uk Kim     int nid;
34591f13597dSJung-uk Kim     int id;
34601f13597dSJung-uk Kim } tls12_lookup;
34611f13597dSJung-uk Kim 
34621f13597dSJung-uk Kim static tls12_lookup tls12_md[] = {
34631f13597dSJung-uk Kim     {NID_md5, TLSEXT_hash_md5},
34641f13597dSJung-uk Kim     {NID_sha1, TLSEXT_hash_sha1},
34651f13597dSJung-uk Kim     {NID_sha224, TLSEXT_hash_sha224},
34661f13597dSJung-uk Kim     {NID_sha256, TLSEXT_hash_sha256},
34671f13597dSJung-uk Kim     {NID_sha384, TLSEXT_hash_sha384},
34681f13597dSJung-uk Kim     {NID_sha512, TLSEXT_hash_sha512}
34691f13597dSJung-uk Kim };
34701f13597dSJung-uk Kim 
34711f13597dSJung-uk Kim static tls12_lookup tls12_sig[] = {
34721f13597dSJung-uk Kim     {EVP_PKEY_RSA, TLSEXT_signature_rsa},
34731f13597dSJung-uk Kim     {EVP_PKEY_DSA, TLSEXT_signature_dsa},
34741f13597dSJung-uk Kim     {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
34751f13597dSJung-uk Kim };
34761f13597dSJung-uk Kim 
34771f13597dSJung-uk Kim static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
34781f13597dSJung-uk Kim {
34791f13597dSJung-uk Kim     size_t i;
34806f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
34811f13597dSJung-uk Kim         if (table[i].nid == nid)
34821f13597dSJung-uk Kim             return table[i].id;
34831f13597dSJung-uk Kim     }
34841f13597dSJung-uk Kim     return -1;
34851f13597dSJung-uk Kim }
34866f9291ceSJung-uk Kim 
34871f13597dSJung-uk Kim static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
34881f13597dSJung-uk Kim {
34891f13597dSJung-uk Kim     size_t i;
34906f9291ceSJung-uk Kim     for (i = 0; i < tlen; i++) {
3491*7bded2dbSJung-uk Kim         if ((table[i].id) == id)
34921f13597dSJung-uk Kim             return table[i].nid;
34931f13597dSJung-uk Kim     }
3494*7bded2dbSJung-uk Kim     return NID_undef;
34951f13597dSJung-uk Kim }
34961f13597dSJung-uk Kim 
34976f9291ceSJung-uk Kim int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
34986f9291ceSJung-uk Kim                          const EVP_MD *md)
34991f13597dSJung-uk Kim {
35001f13597dSJung-uk Kim     int sig_id, md_id;
35011f13597dSJung-uk Kim     if (!md)
35021f13597dSJung-uk Kim         return 0;
35031f13597dSJung-uk Kim     md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
35041f13597dSJung-uk Kim                           sizeof(tls12_md) / sizeof(tls12_lookup));
35051f13597dSJung-uk Kim     if (md_id == -1)
35061f13597dSJung-uk Kim         return 0;
35071f13597dSJung-uk Kim     sig_id = tls12_get_sigid(pk);
35081f13597dSJung-uk Kim     if (sig_id == -1)
35091f13597dSJung-uk Kim         return 0;
35101f13597dSJung-uk Kim     p[0] = (unsigned char)md_id;
35111f13597dSJung-uk Kim     p[1] = (unsigned char)sig_id;
3512db522d3aSSimon L. B. Nielsen     return 1;
3513db522d3aSSimon L. B. Nielsen }
35141f13597dSJung-uk Kim 
35151f13597dSJung-uk Kim int tls12_get_sigid(const EVP_PKEY *pk)
35161f13597dSJung-uk Kim {
35171f13597dSJung-uk Kim     return tls12_find_id(pk->type, tls12_sig,
35181f13597dSJung-uk Kim                          sizeof(tls12_sig) / sizeof(tls12_lookup));
35191f13597dSJung-uk Kim }
35201f13597dSJung-uk Kim 
35211f13597dSJung-uk Kim const EVP_MD *tls12_get_hash(unsigned char hash_alg)
35221f13597dSJung-uk Kim {
35236f9291ceSJung-uk Kim     switch (hash_alg) {
3524*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_MD5
3525*7bded2dbSJung-uk Kim     case TLSEXT_hash_md5:
3526*7bded2dbSJung-uk Kim #  ifdef OPENSSL_FIPS
3527*7bded2dbSJung-uk Kim         if (FIPS_mode())
3528*7bded2dbSJung-uk Kim             return NULL;
3529*7bded2dbSJung-uk Kim #  endif
3530*7bded2dbSJung-uk Kim         return EVP_md5();
3531*7bded2dbSJung-uk Kim # endif
35321f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA
35331f13597dSJung-uk Kim     case TLSEXT_hash_sha1:
35341f13597dSJung-uk Kim         return EVP_sha1();
35351f13597dSJung-uk Kim # endif
35361f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA256
35371f13597dSJung-uk Kim     case TLSEXT_hash_sha224:
35381f13597dSJung-uk Kim         return EVP_sha224();
35391f13597dSJung-uk Kim 
35401f13597dSJung-uk Kim     case TLSEXT_hash_sha256:
35411f13597dSJung-uk Kim         return EVP_sha256();
35421f13597dSJung-uk Kim # endif
35431f13597dSJung-uk Kim # ifndef OPENSSL_NO_SHA512
35441f13597dSJung-uk Kim     case TLSEXT_hash_sha384:
35451f13597dSJung-uk Kim         return EVP_sha384();
35461f13597dSJung-uk Kim 
35471f13597dSJung-uk Kim     case TLSEXT_hash_sha512:
35481f13597dSJung-uk Kim         return EVP_sha512();
35491f13597dSJung-uk Kim # endif
35501f13597dSJung-uk Kim     default:
35511f13597dSJung-uk Kim         return NULL;
35521f13597dSJung-uk Kim 
35531f13597dSJung-uk Kim     }
35541f13597dSJung-uk Kim }
35551f13597dSJung-uk Kim 
3556*7bded2dbSJung-uk Kim static int tls12_get_pkey_idx(unsigned char sig_alg)
3557*7bded2dbSJung-uk Kim {
3558*7bded2dbSJung-uk Kim     switch (sig_alg) {
3559*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_RSA
3560*7bded2dbSJung-uk Kim     case TLSEXT_signature_rsa:
3561*7bded2dbSJung-uk Kim         return SSL_PKEY_RSA_SIGN;
3562*7bded2dbSJung-uk Kim # endif
3563*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_DSA
3564*7bded2dbSJung-uk Kim     case TLSEXT_signature_dsa:
3565*7bded2dbSJung-uk Kim         return SSL_PKEY_DSA_SIGN;
3566*7bded2dbSJung-uk Kim # endif
3567*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
3568*7bded2dbSJung-uk Kim     case TLSEXT_signature_ecdsa:
3569*7bded2dbSJung-uk Kim         return SSL_PKEY_ECC;
3570*7bded2dbSJung-uk Kim # endif
3571*7bded2dbSJung-uk Kim     }
3572*7bded2dbSJung-uk Kim     return -1;
3573*7bded2dbSJung-uk Kim }
3574*7bded2dbSJung-uk Kim 
3575*7bded2dbSJung-uk Kim /* Convert TLS 1.2 signature algorithm extension values into NIDs */
3576*7bded2dbSJung-uk Kim static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
3577*7bded2dbSJung-uk Kim                                int *psignhash_nid, const unsigned char *data)
3578*7bded2dbSJung-uk Kim {
3579*7bded2dbSJung-uk Kim     int sign_nid = 0, hash_nid = 0;
3580*7bded2dbSJung-uk Kim     if (!phash_nid && !psign_nid && !psignhash_nid)
3581*7bded2dbSJung-uk Kim         return;
3582*7bded2dbSJung-uk Kim     if (phash_nid || psignhash_nid) {
3583*7bded2dbSJung-uk Kim         hash_nid = tls12_find_nid(data[0], tls12_md,
3584*7bded2dbSJung-uk Kim                                   sizeof(tls12_md) / sizeof(tls12_lookup));
3585*7bded2dbSJung-uk Kim         if (phash_nid)
3586*7bded2dbSJung-uk Kim             *phash_nid = hash_nid;
3587*7bded2dbSJung-uk Kim     }
3588*7bded2dbSJung-uk Kim     if (psign_nid || psignhash_nid) {
3589*7bded2dbSJung-uk Kim         sign_nid = tls12_find_nid(data[1], tls12_sig,
3590*7bded2dbSJung-uk Kim                                   sizeof(tls12_sig) / sizeof(tls12_lookup));
3591*7bded2dbSJung-uk Kim         if (psign_nid)
3592*7bded2dbSJung-uk Kim             *psign_nid = sign_nid;
3593*7bded2dbSJung-uk Kim     }
3594*7bded2dbSJung-uk Kim     if (psignhash_nid) {
3595*7bded2dbSJung-uk Kim         if (sign_nid && hash_nid)
3596*7bded2dbSJung-uk Kim             OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid);
3597*7bded2dbSJung-uk Kim         else
3598*7bded2dbSJung-uk Kim             *psignhash_nid = NID_undef;
3599*7bded2dbSJung-uk Kim     }
3600*7bded2dbSJung-uk Kim }
3601*7bded2dbSJung-uk Kim 
3602*7bded2dbSJung-uk Kim /* Given preference and allowed sigalgs set shared sigalgs */
3603*7bded2dbSJung-uk Kim static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig,
3604*7bded2dbSJung-uk Kim                                    const unsigned char *pref, size_t preflen,
3605*7bded2dbSJung-uk Kim                                    const unsigned char *allow,
3606*7bded2dbSJung-uk Kim                                    size_t allowlen)
3607*7bded2dbSJung-uk Kim {
3608*7bded2dbSJung-uk Kim     const unsigned char *ptmp, *atmp;
3609*7bded2dbSJung-uk Kim     size_t i, j, nmatch = 0;
3610*7bded2dbSJung-uk Kim     for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
3611*7bded2dbSJung-uk Kim         /* Skip disabled hashes or signature algorithms */
3612*7bded2dbSJung-uk Kim         if (tls12_get_hash(ptmp[0]) == NULL)
3613*7bded2dbSJung-uk Kim             continue;
3614*7bded2dbSJung-uk Kim         if (tls12_get_pkey_idx(ptmp[1]) == -1)
3615*7bded2dbSJung-uk Kim             continue;
3616*7bded2dbSJung-uk Kim         for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
3617*7bded2dbSJung-uk Kim             if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
3618*7bded2dbSJung-uk Kim                 nmatch++;
3619*7bded2dbSJung-uk Kim                 if (shsig) {
3620*7bded2dbSJung-uk Kim                     shsig->rhash = ptmp[0];
3621*7bded2dbSJung-uk Kim                     shsig->rsign = ptmp[1];
3622*7bded2dbSJung-uk Kim                     tls1_lookup_sigalg(&shsig->hash_nid,
3623*7bded2dbSJung-uk Kim                                        &shsig->sign_nid,
3624*7bded2dbSJung-uk Kim                                        &shsig->signandhash_nid, ptmp);
3625*7bded2dbSJung-uk Kim                     shsig++;
3626*7bded2dbSJung-uk Kim                 }
3627*7bded2dbSJung-uk Kim                 break;
3628*7bded2dbSJung-uk Kim             }
3629*7bded2dbSJung-uk Kim         }
3630*7bded2dbSJung-uk Kim     }
3631*7bded2dbSJung-uk Kim     return nmatch;
3632*7bded2dbSJung-uk Kim }
3633*7bded2dbSJung-uk Kim 
3634*7bded2dbSJung-uk Kim /* Set shared signature algorithms for SSL structures */
3635*7bded2dbSJung-uk Kim static int tls1_set_shared_sigalgs(SSL *s)
3636*7bded2dbSJung-uk Kim {
3637*7bded2dbSJung-uk Kim     const unsigned char *pref, *allow, *conf;
3638*7bded2dbSJung-uk Kim     size_t preflen, allowlen, conflen;
3639*7bded2dbSJung-uk Kim     size_t nmatch;
3640*7bded2dbSJung-uk Kim     TLS_SIGALGS *salgs = NULL;
3641*7bded2dbSJung-uk Kim     CERT *c = s->cert;
3642*7bded2dbSJung-uk Kim     unsigned int is_suiteb = tls1_suiteb(s);
3643*7bded2dbSJung-uk Kim     if (c->shared_sigalgs) {
3644*7bded2dbSJung-uk Kim         OPENSSL_free(c->shared_sigalgs);
3645*7bded2dbSJung-uk Kim         c->shared_sigalgs = NULL;
3646*7bded2dbSJung-uk Kim         c->shared_sigalgslen = 0;
3647*7bded2dbSJung-uk Kim     }
3648*7bded2dbSJung-uk Kim     /* If client use client signature algorithms if not NULL */
3649*7bded2dbSJung-uk Kim     if (!s->server && c->client_sigalgs && !is_suiteb) {
3650*7bded2dbSJung-uk Kim         conf = c->client_sigalgs;
3651*7bded2dbSJung-uk Kim         conflen = c->client_sigalgslen;
3652*7bded2dbSJung-uk Kim     } else if (c->conf_sigalgs && !is_suiteb) {
3653*7bded2dbSJung-uk Kim         conf = c->conf_sigalgs;
3654*7bded2dbSJung-uk Kim         conflen = c->conf_sigalgslen;
3655*7bded2dbSJung-uk Kim     } else
3656*7bded2dbSJung-uk Kim         conflen = tls12_get_psigalgs(s, &conf);
3657*7bded2dbSJung-uk Kim     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
3658*7bded2dbSJung-uk Kim         pref = conf;
3659*7bded2dbSJung-uk Kim         preflen = conflen;
3660*7bded2dbSJung-uk Kim         allow = c->peer_sigalgs;
3661*7bded2dbSJung-uk Kim         allowlen = c->peer_sigalgslen;
3662*7bded2dbSJung-uk Kim     } else {
3663*7bded2dbSJung-uk Kim         allow = conf;
3664*7bded2dbSJung-uk Kim         allowlen = conflen;
3665*7bded2dbSJung-uk Kim         pref = c->peer_sigalgs;
3666*7bded2dbSJung-uk Kim         preflen = c->peer_sigalgslen;
3667*7bded2dbSJung-uk Kim     }
3668*7bded2dbSJung-uk Kim     nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
3669*7bded2dbSJung-uk Kim     if (nmatch) {
3670*7bded2dbSJung-uk Kim         salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
3671*7bded2dbSJung-uk Kim         if (!salgs)
3672*7bded2dbSJung-uk Kim             return 0;
3673*7bded2dbSJung-uk Kim         nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
3674*7bded2dbSJung-uk Kim     } else {
3675*7bded2dbSJung-uk Kim         salgs = NULL;
3676*7bded2dbSJung-uk Kim     }
3677*7bded2dbSJung-uk Kim     c->shared_sigalgs = salgs;
3678*7bded2dbSJung-uk Kim     c->shared_sigalgslen = nmatch;
3679*7bded2dbSJung-uk Kim     return 1;
3680*7bded2dbSJung-uk Kim }
3681*7bded2dbSJung-uk Kim 
36821f13597dSJung-uk Kim /* Set preferred digest for each key type */
36831f13597dSJung-uk Kim 
3684*7bded2dbSJung-uk Kim int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
36851f13597dSJung-uk Kim {
36861f13597dSJung-uk Kim     CERT *c = s->cert;
3687*7bded2dbSJung-uk Kim     /* Extension ignored for inappropriate versions */
3688*7bded2dbSJung-uk Kim     if (!SSL_USE_SIGALGS(s))
36891f13597dSJung-uk Kim         return 1;
36901f13597dSJung-uk Kim     /* Should never happen */
36911f13597dSJung-uk Kim     if (!c)
36921f13597dSJung-uk Kim         return 0;
36931f13597dSJung-uk Kim 
3694*7bded2dbSJung-uk Kim     if (c->peer_sigalgs)
3695*7bded2dbSJung-uk Kim         OPENSSL_free(c->peer_sigalgs);
3696*7bded2dbSJung-uk Kim     c->peer_sigalgs = OPENSSL_malloc(dsize);
3697*7bded2dbSJung-uk Kim     if (!c->peer_sigalgs)
3698*7bded2dbSJung-uk Kim         return 0;
3699*7bded2dbSJung-uk Kim     c->peer_sigalgslen = dsize;
3700*7bded2dbSJung-uk Kim     memcpy(c->peer_sigalgs, data, dsize);
3701*7bded2dbSJung-uk Kim     return 1;
37021f13597dSJung-uk Kim }
37031f13597dSJung-uk Kim 
3704*7bded2dbSJung-uk Kim int tls1_process_sigalgs(SSL *s)
3705*7bded2dbSJung-uk Kim {
3706*7bded2dbSJung-uk Kim     int idx;
3707*7bded2dbSJung-uk Kim     size_t i;
3708*7bded2dbSJung-uk Kim     const EVP_MD *md;
3709*7bded2dbSJung-uk Kim     CERT *c = s->cert;
3710*7bded2dbSJung-uk Kim     TLS_SIGALGS *sigptr;
3711*7bded2dbSJung-uk Kim     if (!tls1_set_shared_sigalgs(s))
3712*7bded2dbSJung-uk Kim         return 0;
3713*7bded2dbSJung-uk Kim 
3714*7bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
3715*7bded2dbSJung-uk Kim     if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
3716*7bded2dbSJung-uk Kim         /*
3717*7bded2dbSJung-uk Kim          * Use first set signature preference to force message digest,
3718*7bded2dbSJung-uk Kim          * ignoring any peer preferences.
3719*7bded2dbSJung-uk Kim          */
3720*7bded2dbSJung-uk Kim         const unsigned char *sigs = NULL;
3721*7bded2dbSJung-uk Kim         if (s->server)
3722*7bded2dbSJung-uk Kim             sigs = c->conf_sigalgs;
3723*7bded2dbSJung-uk Kim         else
3724*7bded2dbSJung-uk Kim             sigs = c->client_sigalgs;
3725*7bded2dbSJung-uk Kim         if (sigs) {
3726*7bded2dbSJung-uk Kim             idx = tls12_get_pkey_idx(sigs[1]);
3727*7bded2dbSJung-uk Kim             md = tls12_get_hash(sigs[0]);
37281f13597dSJung-uk Kim             c->pkeys[idx].digest = md;
3729*7bded2dbSJung-uk Kim             c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
3730*7bded2dbSJung-uk Kim             if (idx == SSL_PKEY_RSA_SIGN) {
3731*7bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
3732*7bded2dbSJung-uk Kim                     CERT_PKEY_EXPLICIT_SIGN;
3733*7bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
3734*7bded2dbSJung-uk Kim             }
3735*7bded2dbSJung-uk Kim         }
3736*7bded2dbSJung-uk Kim     }
3737*7bded2dbSJung-uk Kim # endif
3738*7bded2dbSJung-uk Kim 
3739*7bded2dbSJung-uk Kim     for (i = 0, sigptr = c->shared_sigalgs;
3740*7bded2dbSJung-uk Kim          i < c->shared_sigalgslen; i++, sigptr++) {
3741*7bded2dbSJung-uk Kim         idx = tls12_get_pkey_idx(sigptr->rsign);
3742*7bded2dbSJung-uk Kim         if (idx > 0 && c->pkeys[idx].digest == NULL) {
3743*7bded2dbSJung-uk Kim             md = tls12_get_hash(sigptr->rhash);
3744*7bded2dbSJung-uk Kim             c->pkeys[idx].digest = md;
3745*7bded2dbSJung-uk Kim             c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
3746*7bded2dbSJung-uk Kim             if (idx == SSL_PKEY_RSA_SIGN) {
3747*7bded2dbSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
3748*7bded2dbSJung-uk Kim                     CERT_PKEY_EXPLICIT_SIGN;
37491f13597dSJung-uk Kim                 c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
37501f13597dSJung-uk Kim             }
37511f13597dSJung-uk Kim         }
37521f13597dSJung-uk Kim 
37531f13597dSJung-uk Kim     }
3754*7bded2dbSJung-uk Kim     /*
3755*7bded2dbSJung-uk Kim      * In strict mode leave unset digests as NULL to indicate we can't use
3756*7bded2dbSJung-uk Kim      * the certificate for signing.
3757*7bded2dbSJung-uk Kim      */
3758*7bded2dbSJung-uk Kim     if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
37596f9291ceSJung-uk Kim         /*
37606f9291ceSJung-uk Kim          * Set any remaining keys to default values. NOTE: if alg is not
37611f13597dSJung-uk Kim          * supported it stays as NULL.
3762db522d3aSSimon L. B. Nielsen          */
37631f13597dSJung-uk Kim # ifndef OPENSSL_NO_DSA
37641f13597dSJung-uk Kim         if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
376509286989SJung-uk Kim             c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
37661f13597dSJung-uk Kim # endif
37671f13597dSJung-uk Kim # ifndef OPENSSL_NO_RSA
37686f9291ceSJung-uk Kim         if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
37691f13597dSJung-uk Kim             c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
37701f13597dSJung-uk Kim             c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
37711f13597dSJung-uk Kim         }
37721f13597dSJung-uk Kim # endif
37731f13597dSJung-uk Kim # ifndef OPENSSL_NO_ECDSA
37741f13597dSJung-uk Kim         if (!c->pkeys[SSL_PKEY_ECC].digest)
377509286989SJung-uk Kim             c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
37761f13597dSJung-uk Kim # endif
3777*7bded2dbSJung-uk Kim     }
37781f13597dSJung-uk Kim     return 1;
37791f13597dSJung-uk Kim }
37801f13597dSJung-uk Kim 
3781*7bded2dbSJung-uk Kim int SSL_get_sigalgs(SSL *s, int idx,
3782*7bded2dbSJung-uk Kim                     int *psign, int *phash, int *psignhash,
3783*7bded2dbSJung-uk Kim                     unsigned char *rsig, unsigned char *rhash)
3784*7bded2dbSJung-uk Kim {
3785*7bded2dbSJung-uk Kim     const unsigned char *psig = s->cert->peer_sigalgs;
3786*7bded2dbSJung-uk Kim     if (psig == NULL)
3787*7bded2dbSJung-uk Kim         return 0;
3788*7bded2dbSJung-uk Kim     if (idx >= 0) {
3789*7bded2dbSJung-uk Kim         idx <<= 1;
3790*7bded2dbSJung-uk Kim         if (idx >= (int)s->cert->peer_sigalgslen)
3791*7bded2dbSJung-uk Kim             return 0;
3792*7bded2dbSJung-uk Kim         psig += idx;
3793*7bded2dbSJung-uk Kim         if (rhash)
3794*7bded2dbSJung-uk Kim             *rhash = psig[0];
3795*7bded2dbSJung-uk Kim         if (rsig)
3796*7bded2dbSJung-uk Kim             *rsig = psig[1];
3797*7bded2dbSJung-uk Kim         tls1_lookup_sigalg(phash, psign, psignhash, psig);
3798*7bded2dbSJung-uk Kim     }
3799*7bded2dbSJung-uk Kim     return s->cert->peer_sigalgslen / 2;
3800*7bded2dbSJung-uk Kim }
3801*7bded2dbSJung-uk Kim 
3802*7bded2dbSJung-uk Kim int SSL_get_shared_sigalgs(SSL *s, int idx,
3803*7bded2dbSJung-uk Kim                            int *psign, int *phash, int *psignhash,
3804*7bded2dbSJung-uk Kim                            unsigned char *rsig, unsigned char *rhash)
3805*7bded2dbSJung-uk Kim {
3806*7bded2dbSJung-uk Kim     TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
3807*7bded2dbSJung-uk Kim     if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen)
3808*7bded2dbSJung-uk Kim         return 0;
3809*7bded2dbSJung-uk Kim     shsigalgs += idx;
3810*7bded2dbSJung-uk Kim     if (phash)
3811*7bded2dbSJung-uk Kim         *phash = shsigalgs->hash_nid;
3812*7bded2dbSJung-uk Kim     if (psign)
3813*7bded2dbSJung-uk Kim         *psign = shsigalgs->sign_nid;
3814*7bded2dbSJung-uk Kim     if (psignhash)
3815*7bded2dbSJung-uk Kim         *psignhash = shsigalgs->signandhash_nid;
3816*7bded2dbSJung-uk Kim     if (rsig)
3817*7bded2dbSJung-uk Kim         *rsig = shsigalgs->rsign;
3818*7bded2dbSJung-uk Kim     if (rhash)
3819*7bded2dbSJung-uk Kim         *rhash = shsigalgs->rhash;
3820*7bded2dbSJung-uk Kim     return s->cert->shared_sigalgslen;
3821*7bded2dbSJung-uk Kim }
38221f13597dSJung-uk Kim 
38231f13597dSJung-uk Kim # ifndef OPENSSL_NO_HEARTBEATS
38246f9291ceSJung-uk Kim int tls1_process_heartbeat(SSL *s)
38251f13597dSJung-uk Kim {
38261f13597dSJung-uk Kim     unsigned char *p = &s->s3->rrec.data[0], *pl;
38271f13597dSJung-uk Kim     unsigned short hbtype;
38281f13597dSJung-uk Kim     unsigned int payload;
38291f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
38301f13597dSJung-uk Kim 
38311f13597dSJung-uk Kim     if (s->msg_callback)
38321f13597dSJung-uk Kim         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
38331f13597dSJung-uk Kim                         &s->s3->rrec.data[0], s->s3->rrec.length,
38341f13597dSJung-uk Kim                         s, s->msg_callback_arg);
38351f13597dSJung-uk Kim 
383625bfde79SXin LI     /* Read type and payload length first */
383725bfde79SXin LI     if (1 + 2 + 16 > s->s3->rrec.length)
383825bfde79SXin LI         return 0;               /* silently discard */
383925bfde79SXin LI     hbtype = *p++;
384025bfde79SXin LI     n2s(p, payload);
384125bfde79SXin LI     if (1 + 2 + payload + 16 > s->s3->rrec.length)
384225bfde79SXin LI         return 0;               /* silently discard per RFC 6520 sec. 4 */
384325bfde79SXin LI     pl = p;
384425bfde79SXin LI 
38456f9291ceSJung-uk Kim     if (hbtype == TLS1_HB_REQUEST) {
38461f13597dSJung-uk Kim         unsigned char *buffer, *bp;
38471f13597dSJung-uk Kim         int r;
38481f13597dSJung-uk Kim 
38496f9291ceSJung-uk Kim         /*
38506f9291ceSJung-uk Kim          * Allocate memory for the response, size is 1 bytes message type,
38516f9291ceSJung-uk Kim          * plus 2 bytes payload length, plus payload, plus padding
38521f13597dSJung-uk Kim          */
38531f13597dSJung-uk Kim         buffer = OPENSSL_malloc(1 + 2 + payload + padding);
38541f13597dSJung-uk Kim         bp = buffer;
38551f13597dSJung-uk Kim 
38561f13597dSJung-uk Kim         /* Enter response type, length and copy payload */
38571f13597dSJung-uk Kim         *bp++ = TLS1_HB_RESPONSE;
38581f13597dSJung-uk Kim         s2n(payload, bp);
38591f13597dSJung-uk Kim         memcpy(bp, pl, payload);
38601f13597dSJung-uk Kim         bp += payload;
38611f13597dSJung-uk Kim         /* Random padding */
3862ed6b93beSJung-uk Kim         if (RAND_pseudo_bytes(bp, padding) < 0) {
3863ed6b93beSJung-uk Kim             OPENSSL_free(buffer);
3864ed6b93beSJung-uk Kim             return -1;
3865ed6b93beSJung-uk Kim         }
38661f13597dSJung-uk Kim 
38676f9291ceSJung-uk Kim         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
38686f9291ceSJung-uk Kim                              3 + payload + padding);
38691f13597dSJung-uk Kim 
38701f13597dSJung-uk Kim         if (r >= 0 && s->msg_callback)
38711f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
38721f13597dSJung-uk Kim                             buffer, 3 + payload + padding,
38731f13597dSJung-uk Kim                             s, s->msg_callback_arg);
38741f13597dSJung-uk Kim 
38751f13597dSJung-uk Kim         OPENSSL_free(buffer);
38761f13597dSJung-uk Kim 
38771f13597dSJung-uk Kim         if (r < 0)
38781f13597dSJung-uk Kim             return r;
38796f9291ceSJung-uk Kim     } else if (hbtype == TLS1_HB_RESPONSE) {
38801f13597dSJung-uk Kim         unsigned int seq;
38811f13597dSJung-uk Kim 
38826f9291ceSJung-uk Kim         /*
38836f9291ceSJung-uk Kim          * We only send sequence numbers (2 bytes unsigned int), and 16
38846f9291ceSJung-uk Kim          * random bytes, so we just try to read the sequence number
38856f9291ceSJung-uk Kim          */
38861f13597dSJung-uk Kim         n2s(pl, seq);
38871f13597dSJung-uk Kim 
38886f9291ceSJung-uk Kim         if (payload == 18 && seq == s->tlsext_hb_seq) {
38891f13597dSJung-uk Kim             s->tlsext_hb_seq++;
38901f13597dSJung-uk Kim             s->tlsext_hb_pending = 0;
38911f13597dSJung-uk Kim         }
38921f13597dSJung-uk Kim     }
38931f13597dSJung-uk Kim 
3894db522d3aSSimon L. B. Nielsen     return 0;
3895db522d3aSSimon L. B. Nielsen }
3896db522d3aSSimon L. B. Nielsen 
38976f9291ceSJung-uk Kim int tls1_heartbeat(SSL *s)
38981f13597dSJung-uk Kim {
38991f13597dSJung-uk Kim     unsigned char *buf, *p;
3900ed6b93beSJung-uk Kim     int ret = -1;
39011f13597dSJung-uk Kim     unsigned int payload = 18;  /* Sequence number + random bytes */
39021f13597dSJung-uk Kim     unsigned int padding = 16;  /* Use minimum padding */
39031f13597dSJung-uk Kim 
39041f13597dSJung-uk Kim     /* Only send if peer supports and accepts HB requests... */
39051f13597dSJung-uk Kim     if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
39066f9291ceSJung-uk Kim         s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
39071f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
39081f13597dSJung-uk Kim         return -1;
39091f13597dSJung-uk Kim     }
39101f13597dSJung-uk Kim 
39111f13597dSJung-uk Kim     /* ...and there is none in flight yet... */
39126f9291ceSJung-uk Kim     if (s->tlsext_hb_pending) {
39131f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
39141f13597dSJung-uk Kim         return -1;
39151f13597dSJung-uk Kim     }
39161f13597dSJung-uk Kim 
39171f13597dSJung-uk Kim     /* ...and no handshake in progress. */
39186f9291ceSJung-uk Kim     if (SSL_in_init(s) || s->in_handshake) {
39191f13597dSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
39201f13597dSJung-uk Kim         return -1;
39211f13597dSJung-uk Kim     }
39221f13597dSJung-uk Kim 
39236f9291ceSJung-uk Kim     /*
39246f9291ceSJung-uk Kim      * Check if padding is too long, payload and padding must not exceed 2^14
39256f9291ceSJung-uk Kim      * - 3 = 16381 bytes in total.
39261f13597dSJung-uk Kim      */
39271f13597dSJung-uk Kim     OPENSSL_assert(payload + padding <= 16381);
39281f13597dSJung-uk Kim 
39296f9291ceSJung-uk Kim     /*-
39306f9291ceSJung-uk Kim      * Create HeartBeat message, we just use a sequence number
39311f13597dSJung-uk Kim      * as payload to distuingish different messages and add
39321f13597dSJung-uk Kim      * some random stuff.
39331f13597dSJung-uk Kim      *  - Message Type, 1 byte
39341f13597dSJung-uk Kim      *  - Payload Length, 2 bytes (unsigned int)
39351f13597dSJung-uk Kim      *  - Payload, the sequence number (2 bytes uint)
39361f13597dSJung-uk Kim      *  - Payload, random bytes (16 bytes uint)
39371f13597dSJung-uk Kim      *  - Padding
39381f13597dSJung-uk Kim      */
39391f13597dSJung-uk Kim     buf = OPENSSL_malloc(1 + 2 + payload + padding);
39401f13597dSJung-uk Kim     p = buf;
39411f13597dSJung-uk Kim     /* Message Type */
39421f13597dSJung-uk Kim     *p++ = TLS1_HB_REQUEST;
39431f13597dSJung-uk Kim     /* Payload length (18 bytes here) */
39441f13597dSJung-uk Kim     s2n(payload, p);
39451f13597dSJung-uk Kim     /* Sequence number */
39461f13597dSJung-uk Kim     s2n(s->tlsext_hb_seq, p);
39471f13597dSJung-uk Kim     /* 16 random bytes */
3948ed6b93beSJung-uk Kim     if (RAND_pseudo_bytes(p, 16) < 0) {
3949ed6b93beSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
3950ed6b93beSJung-uk Kim         goto err;
3951ed6b93beSJung-uk Kim     }
39521f13597dSJung-uk Kim     p += 16;
39531f13597dSJung-uk Kim     /* Random padding */
3954ed6b93beSJung-uk Kim     if (RAND_pseudo_bytes(p, padding) < 0) {
3955ed6b93beSJung-uk Kim         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
3956ed6b93beSJung-uk Kim         goto err;
3957ed6b93beSJung-uk Kim     }
39581f13597dSJung-uk Kim 
39591f13597dSJung-uk Kim     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
39606f9291ceSJung-uk Kim     if (ret >= 0) {
39611f13597dSJung-uk Kim         if (s->msg_callback)
39621f13597dSJung-uk Kim             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
39631f13597dSJung-uk Kim                             buf, 3 + payload + padding,
39641f13597dSJung-uk Kim                             s, s->msg_callback_arg);
39651f13597dSJung-uk Kim 
39661f13597dSJung-uk Kim         s->tlsext_hb_pending = 1;
39671f13597dSJung-uk Kim     }
39681f13597dSJung-uk Kim 
3969ed6b93beSJung-uk Kim err:
39701f13597dSJung-uk Kim     OPENSSL_free(buf);
39711f13597dSJung-uk Kim 
39721f13597dSJung-uk Kim     return ret;
39731f13597dSJung-uk Kim }
3974db522d3aSSimon L. B. Nielsen # endif
3975*7bded2dbSJung-uk Kim 
3976*7bded2dbSJung-uk Kim # define MAX_SIGALGLEN   (TLSEXT_hash_num * TLSEXT_signature_num * 2)
3977*7bded2dbSJung-uk Kim 
3978*7bded2dbSJung-uk Kim typedef struct {
3979*7bded2dbSJung-uk Kim     size_t sigalgcnt;
3980*7bded2dbSJung-uk Kim     int sigalgs[MAX_SIGALGLEN];
3981*7bded2dbSJung-uk Kim } sig_cb_st;
3982*7bded2dbSJung-uk Kim 
3983*7bded2dbSJung-uk Kim static int sig_cb(const char *elem, int len, void *arg)
3984*7bded2dbSJung-uk Kim {
3985*7bded2dbSJung-uk Kim     sig_cb_st *sarg = arg;
3986*7bded2dbSJung-uk Kim     size_t i;
3987*7bded2dbSJung-uk Kim     char etmp[20], *p;
3988*7bded2dbSJung-uk Kim     int sig_alg, hash_alg;
3989*7bded2dbSJung-uk Kim     if (elem == NULL)
3990*7bded2dbSJung-uk Kim         return 0;
3991*7bded2dbSJung-uk Kim     if (sarg->sigalgcnt == MAX_SIGALGLEN)
3992*7bded2dbSJung-uk Kim         return 0;
3993*7bded2dbSJung-uk Kim     if (len > (int)(sizeof(etmp) - 1))
3994*7bded2dbSJung-uk Kim         return 0;
3995*7bded2dbSJung-uk Kim     memcpy(etmp, elem, len);
3996*7bded2dbSJung-uk Kim     etmp[len] = 0;
3997*7bded2dbSJung-uk Kim     p = strchr(etmp, '+');
3998*7bded2dbSJung-uk Kim     if (!p)
3999*7bded2dbSJung-uk Kim         return 0;
4000*7bded2dbSJung-uk Kim     *p = 0;
4001*7bded2dbSJung-uk Kim     p++;
4002*7bded2dbSJung-uk Kim     if (!*p)
4003*7bded2dbSJung-uk Kim         return 0;
4004*7bded2dbSJung-uk Kim 
4005*7bded2dbSJung-uk Kim     if (!strcmp(etmp, "RSA"))
4006*7bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_RSA;
4007*7bded2dbSJung-uk Kim     else if (!strcmp(etmp, "DSA"))
4008*7bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_DSA;
4009*7bded2dbSJung-uk Kim     else if (!strcmp(etmp, "ECDSA"))
4010*7bded2dbSJung-uk Kim         sig_alg = EVP_PKEY_EC;
4011*7bded2dbSJung-uk Kim     else
4012*7bded2dbSJung-uk Kim         return 0;
4013*7bded2dbSJung-uk Kim 
4014*7bded2dbSJung-uk Kim     hash_alg = OBJ_sn2nid(p);
4015*7bded2dbSJung-uk Kim     if (hash_alg == NID_undef)
4016*7bded2dbSJung-uk Kim         hash_alg = OBJ_ln2nid(p);
4017*7bded2dbSJung-uk Kim     if (hash_alg == NID_undef)
4018*7bded2dbSJung-uk Kim         return 0;
4019*7bded2dbSJung-uk Kim 
4020*7bded2dbSJung-uk Kim     for (i = 0; i < sarg->sigalgcnt; i += 2) {
4021*7bded2dbSJung-uk Kim         if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg)
4022*7bded2dbSJung-uk Kim             return 0;
4023*7bded2dbSJung-uk Kim     }
4024*7bded2dbSJung-uk Kim     sarg->sigalgs[sarg->sigalgcnt++] = hash_alg;
4025*7bded2dbSJung-uk Kim     sarg->sigalgs[sarg->sigalgcnt++] = sig_alg;
4026*7bded2dbSJung-uk Kim     return 1;
4027*7bded2dbSJung-uk Kim }
4028*7bded2dbSJung-uk Kim 
4029*7bded2dbSJung-uk Kim /*
4030*7bded2dbSJung-uk Kim  * Set suppored signature algorithms based on a colon separated list of the
4031*7bded2dbSJung-uk Kim  * form sig+hash e.g. RSA+SHA512:DSA+SHA512
4032*7bded2dbSJung-uk Kim  */
4033*7bded2dbSJung-uk Kim int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
4034*7bded2dbSJung-uk Kim {
4035*7bded2dbSJung-uk Kim     sig_cb_st sig;
4036*7bded2dbSJung-uk Kim     sig.sigalgcnt = 0;
4037*7bded2dbSJung-uk Kim     if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
4038*7bded2dbSJung-uk Kim         return 0;
4039*7bded2dbSJung-uk Kim     if (c == NULL)
4040*7bded2dbSJung-uk Kim         return 1;
4041*7bded2dbSJung-uk Kim     return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
4042*7bded2dbSJung-uk Kim }
4043*7bded2dbSJung-uk Kim 
4044*7bded2dbSJung-uk Kim int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
4045*7bded2dbSJung-uk Kim                      int client)
4046*7bded2dbSJung-uk Kim {
4047*7bded2dbSJung-uk Kim     unsigned char *sigalgs, *sptr;
4048*7bded2dbSJung-uk Kim     int rhash, rsign;
4049*7bded2dbSJung-uk Kim     size_t i;
4050*7bded2dbSJung-uk Kim     if (salglen & 1)
4051*7bded2dbSJung-uk Kim         return 0;
4052*7bded2dbSJung-uk Kim     sigalgs = OPENSSL_malloc(salglen);
4053*7bded2dbSJung-uk Kim     if (sigalgs == NULL)
4054*7bded2dbSJung-uk Kim         return 0;
4055*7bded2dbSJung-uk Kim     for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
4056*7bded2dbSJung-uk Kim         rhash = tls12_find_id(*psig_nids++, tls12_md,
4057*7bded2dbSJung-uk Kim                               sizeof(tls12_md) / sizeof(tls12_lookup));
4058*7bded2dbSJung-uk Kim         rsign = tls12_find_id(*psig_nids++, tls12_sig,
4059*7bded2dbSJung-uk Kim                               sizeof(tls12_sig) / sizeof(tls12_lookup));
4060*7bded2dbSJung-uk Kim 
4061*7bded2dbSJung-uk Kim         if (rhash == -1 || rsign == -1)
4062*7bded2dbSJung-uk Kim             goto err;
4063*7bded2dbSJung-uk Kim         *sptr++ = rhash;
4064*7bded2dbSJung-uk Kim         *sptr++ = rsign;
4065*7bded2dbSJung-uk Kim     }
4066*7bded2dbSJung-uk Kim 
4067*7bded2dbSJung-uk Kim     if (client) {
4068*7bded2dbSJung-uk Kim         if (c->client_sigalgs)
4069*7bded2dbSJung-uk Kim             OPENSSL_free(c->client_sigalgs);
4070*7bded2dbSJung-uk Kim         c->client_sigalgs = sigalgs;
4071*7bded2dbSJung-uk Kim         c->client_sigalgslen = salglen;
4072*7bded2dbSJung-uk Kim     } else {
4073*7bded2dbSJung-uk Kim         if (c->conf_sigalgs)
4074*7bded2dbSJung-uk Kim             OPENSSL_free(c->conf_sigalgs);
4075*7bded2dbSJung-uk Kim         c->conf_sigalgs = sigalgs;
4076*7bded2dbSJung-uk Kim         c->conf_sigalgslen = salglen;
4077*7bded2dbSJung-uk Kim     }
4078*7bded2dbSJung-uk Kim 
4079*7bded2dbSJung-uk Kim     return 1;
4080*7bded2dbSJung-uk Kim 
4081*7bded2dbSJung-uk Kim  err:
4082*7bded2dbSJung-uk Kim     OPENSSL_free(sigalgs);
4083*7bded2dbSJung-uk Kim     return 0;
4084*7bded2dbSJung-uk Kim }
4085*7bded2dbSJung-uk Kim 
4086*7bded2dbSJung-uk Kim static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
4087*7bded2dbSJung-uk Kim {
4088*7bded2dbSJung-uk Kim     int sig_nid;
4089*7bded2dbSJung-uk Kim     size_t i;
4090*7bded2dbSJung-uk Kim     if (default_nid == -1)
4091*7bded2dbSJung-uk Kim         return 1;
4092*7bded2dbSJung-uk Kim     sig_nid = X509_get_signature_nid(x);
4093*7bded2dbSJung-uk Kim     if (default_nid)
4094*7bded2dbSJung-uk Kim         return sig_nid == default_nid ? 1 : 0;
4095*7bded2dbSJung-uk Kim     for (i = 0; i < c->shared_sigalgslen; i++)
4096*7bded2dbSJung-uk Kim         if (sig_nid == c->shared_sigalgs[i].signandhash_nid)
4097*7bded2dbSJung-uk Kim             return 1;
4098*7bded2dbSJung-uk Kim     return 0;
4099*7bded2dbSJung-uk Kim }
4100*7bded2dbSJung-uk Kim 
4101*7bded2dbSJung-uk Kim /* Check to see if a certificate issuer name matches list of CA names */
4102*7bded2dbSJung-uk Kim static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
4103*7bded2dbSJung-uk Kim {
4104*7bded2dbSJung-uk Kim     X509_NAME *nm;
4105*7bded2dbSJung-uk Kim     int i;
4106*7bded2dbSJung-uk Kim     nm = X509_get_issuer_name(x);
4107*7bded2dbSJung-uk Kim     for (i = 0; i < sk_X509_NAME_num(names); i++) {
4108*7bded2dbSJung-uk Kim         if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
4109*7bded2dbSJung-uk Kim             return 1;
4110*7bded2dbSJung-uk Kim     }
4111*7bded2dbSJung-uk Kim     return 0;
4112*7bded2dbSJung-uk Kim }
4113*7bded2dbSJung-uk Kim 
4114*7bded2dbSJung-uk Kim /*
4115*7bded2dbSJung-uk Kim  * Check certificate chain is consistent with TLS extensions and is usable by
4116*7bded2dbSJung-uk Kim  * server. This servers two purposes: it allows users to check chains before
4117*7bded2dbSJung-uk Kim  * passing them to the server and it allows the server to check chains before
4118*7bded2dbSJung-uk Kim  * attempting to use them.
4119*7bded2dbSJung-uk Kim  */
4120*7bded2dbSJung-uk Kim 
4121*7bded2dbSJung-uk Kim /* Flags which need to be set for a certificate when stict mode not set */
4122*7bded2dbSJung-uk Kim 
4123*7bded2dbSJung-uk Kim # define CERT_PKEY_VALID_FLAGS \
4124*7bded2dbSJung-uk Kim         (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
4125*7bded2dbSJung-uk Kim /* Strict mode flags */
4126*7bded2dbSJung-uk Kim # define CERT_PKEY_STRICT_FLAGS \
4127*7bded2dbSJung-uk Kim          (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
4128*7bded2dbSJung-uk Kim          | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
4129*7bded2dbSJung-uk Kim 
4130*7bded2dbSJung-uk Kim int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
4131*7bded2dbSJung-uk Kim                      int idx)
4132*7bded2dbSJung-uk Kim {
4133*7bded2dbSJung-uk Kim     int i;
4134*7bded2dbSJung-uk Kim     int rv = 0;
4135*7bded2dbSJung-uk Kim     int check_flags = 0, strict_mode;
4136*7bded2dbSJung-uk Kim     CERT_PKEY *cpk = NULL;
4137*7bded2dbSJung-uk Kim     CERT *c = s->cert;
4138*7bded2dbSJung-uk Kim     unsigned int suiteb_flags = tls1_suiteb(s);
4139*7bded2dbSJung-uk Kim     /* idx == -1 means checking server chains */
4140*7bded2dbSJung-uk Kim     if (idx != -1) {
4141*7bded2dbSJung-uk Kim         /* idx == -2 means checking client certificate chains */
4142*7bded2dbSJung-uk Kim         if (idx == -2) {
4143*7bded2dbSJung-uk Kim             cpk = c->key;
4144*7bded2dbSJung-uk Kim             idx = cpk - c->pkeys;
4145*7bded2dbSJung-uk Kim         } else
4146*7bded2dbSJung-uk Kim             cpk = c->pkeys + idx;
4147*7bded2dbSJung-uk Kim         x = cpk->x509;
4148*7bded2dbSJung-uk Kim         pk = cpk->privatekey;
4149*7bded2dbSJung-uk Kim         chain = cpk->chain;
4150*7bded2dbSJung-uk Kim         strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
4151*7bded2dbSJung-uk Kim         /* If no cert or key, forget it */
4152*7bded2dbSJung-uk Kim         if (!x || !pk)
4153*7bded2dbSJung-uk Kim             goto end;
4154*7bded2dbSJung-uk Kim # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
4155*7bded2dbSJung-uk Kim         /* Allow any certificate to pass test */
4156*7bded2dbSJung-uk Kim         if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
4157*7bded2dbSJung-uk Kim             rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN |
4158*7bded2dbSJung-uk Kim                 CERT_PKEY_VALID | CERT_PKEY_SIGN;
4159*7bded2dbSJung-uk Kim             cpk->valid_flags = rv;
4160*7bded2dbSJung-uk Kim             return rv;
4161*7bded2dbSJung-uk Kim         }
4162*7bded2dbSJung-uk Kim # endif
4163*7bded2dbSJung-uk Kim     } else {
4164*7bded2dbSJung-uk Kim         if (!x || !pk)
4165*7bded2dbSJung-uk Kim             return 0;
4166*7bded2dbSJung-uk Kim         idx = ssl_cert_type(x, pk);
4167*7bded2dbSJung-uk Kim         if (idx == -1)
4168*7bded2dbSJung-uk Kim             return 0;
4169*7bded2dbSJung-uk Kim         cpk = c->pkeys + idx;
4170*7bded2dbSJung-uk Kim         if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
4171*7bded2dbSJung-uk Kim             check_flags = CERT_PKEY_STRICT_FLAGS;
4172*7bded2dbSJung-uk Kim         else
4173*7bded2dbSJung-uk Kim             check_flags = CERT_PKEY_VALID_FLAGS;
4174*7bded2dbSJung-uk Kim         strict_mode = 1;
4175*7bded2dbSJung-uk Kim     }
4176*7bded2dbSJung-uk Kim 
4177*7bded2dbSJung-uk Kim     if (suiteb_flags) {
4178*7bded2dbSJung-uk Kim         int ok;
4179*7bded2dbSJung-uk Kim         if (check_flags)
4180*7bded2dbSJung-uk Kim             check_flags |= CERT_PKEY_SUITEB;
4181*7bded2dbSJung-uk Kim         ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
4182*7bded2dbSJung-uk Kim         if (ok == X509_V_OK)
4183*7bded2dbSJung-uk Kim             rv |= CERT_PKEY_SUITEB;
4184*7bded2dbSJung-uk Kim         else if (!check_flags)
4185*7bded2dbSJung-uk Kim             goto end;
4186*7bded2dbSJung-uk Kim     }
4187*7bded2dbSJung-uk Kim 
4188*7bded2dbSJung-uk Kim     /*
4189*7bded2dbSJung-uk Kim      * Check all signature algorithms are consistent with signature
4190*7bded2dbSJung-uk Kim      * algorithms extension if TLS 1.2 or later and strict mode.
4191*7bded2dbSJung-uk Kim      */
4192*7bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
4193*7bded2dbSJung-uk Kim         int default_nid;
4194*7bded2dbSJung-uk Kim         unsigned char rsign = 0;
4195*7bded2dbSJung-uk Kim         if (c->peer_sigalgs)
4196*7bded2dbSJung-uk Kim             default_nid = 0;
4197*7bded2dbSJung-uk Kim         /* If no sigalgs extension use defaults from RFC5246 */
4198*7bded2dbSJung-uk Kim         else {
4199*7bded2dbSJung-uk Kim             switch (idx) {
4200*7bded2dbSJung-uk Kim             case SSL_PKEY_RSA_ENC:
4201*7bded2dbSJung-uk Kim             case SSL_PKEY_RSA_SIGN:
4202*7bded2dbSJung-uk Kim             case SSL_PKEY_DH_RSA:
4203*7bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_rsa;
4204*7bded2dbSJung-uk Kim                 default_nid = NID_sha1WithRSAEncryption;
4205*7bded2dbSJung-uk Kim                 break;
4206*7bded2dbSJung-uk Kim 
4207*7bded2dbSJung-uk Kim             case SSL_PKEY_DSA_SIGN:
4208*7bded2dbSJung-uk Kim             case SSL_PKEY_DH_DSA:
4209*7bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_dsa;
4210*7bded2dbSJung-uk Kim                 default_nid = NID_dsaWithSHA1;
4211*7bded2dbSJung-uk Kim                 break;
4212*7bded2dbSJung-uk Kim 
4213*7bded2dbSJung-uk Kim             case SSL_PKEY_ECC:
4214*7bded2dbSJung-uk Kim                 rsign = TLSEXT_signature_ecdsa;
4215*7bded2dbSJung-uk Kim                 default_nid = NID_ecdsa_with_SHA1;
4216*7bded2dbSJung-uk Kim                 break;
4217*7bded2dbSJung-uk Kim 
4218*7bded2dbSJung-uk Kim             default:
4219*7bded2dbSJung-uk Kim                 default_nid = -1;
4220*7bded2dbSJung-uk Kim                 break;
4221*7bded2dbSJung-uk Kim             }
4222*7bded2dbSJung-uk Kim         }
4223*7bded2dbSJung-uk Kim         /*
4224*7bded2dbSJung-uk Kim          * If peer sent no signature algorithms extension and we have set
4225*7bded2dbSJung-uk Kim          * preferred signature algorithms check we support sha1.
4226*7bded2dbSJung-uk Kim          */
4227*7bded2dbSJung-uk Kim         if (default_nid > 0 && c->conf_sigalgs) {
4228*7bded2dbSJung-uk Kim             size_t j;
4229*7bded2dbSJung-uk Kim             const unsigned char *p = c->conf_sigalgs;
4230*7bded2dbSJung-uk Kim             for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) {
4231*7bded2dbSJung-uk Kim                 if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign)
4232*7bded2dbSJung-uk Kim                     break;
4233*7bded2dbSJung-uk Kim             }
4234*7bded2dbSJung-uk Kim             if (j == c->conf_sigalgslen) {
4235*7bded2dbSJung-uk Kim                 if (check_flags)
4236*7bded2dbSJung-uk Kim                     goto skip_sigs;
4237*7bded2dbSJung-uk Kim                 else
4238*7bded2dbSJung-uk Kim                     goto end;
4239*7bded2dbSJung-uk Kim             }
4240*7bded2dbSJung-uk Kim         }
4241*7bded2dbSJung-uk Kim         /* Check signature algorithm of each cert in chain */
4242*7bded2dbSJung-uk Kim         if (!tls1_check_sig_alg(c, x, default_nid)) {
4243*7bded2dbSJung-uk Kim             if (!check_flags)
4244*7bded2dbSJung-uk Kim                 goto end;
4245*7bded2dbSJung-uk Kim         } else
4246*7bded2dbSJung-uk Kim             rv |= CERT_PKEY_EE_SIGNATURE;
4247*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_SIGNATURE;
4248*7bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
4249*7bded2dbSJung-uk Kim             if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) {
4250*7bded2dbSJung-uk Kim                 if (check_flags) {
4251*7bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_SIGNATURE;
4252*7bded2dbSJung-uk Kim                     break;
4253*7bded2dbSJung-uk Kim                 } else
4254*7bded2dbSJung-uk Kim                     goto end;
4255*7bded2dbSJung-uk Kim             }
4256*7bded2dbSJung-uk Kim         }
4257*7bded2dbSJung-uk Kim     }
4258*7bded2dbSJung-uk Kim     /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
4259*7bded2dbSJung-uk Kim     else if (check_flags)
4260*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
4261*7bded2dbSJung-uk Kim  skip_sigs:
4262*7bded2dbSJung-uk Kim     /* Check cert parameters are consistent */
4263*7bded2dbSJung-uk Kim     if (tls1_check_cert_param(s, x, check_flags ? 1 : 2))
4264*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_EE_PARAM;
4265*7bded2dbSJung-uk Kim     else if (!check_flags)
4266*7bded2dbSJung-uk Kim         goto end;
4267*7bded2dbSJung-uk Kim     if (!s->server)
4268*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
4269*7bded2dbSJung-uk Kim     /* In strict mode check rest of chain too */
4270*7bded2dbSJung-uk Kim     else if (strict_mode) {
4271*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_CA_PARAM;
4272*7bded2dbSJung-uk Kim         for (i = 0; i < sk_X509_num(chain); i++) {
4273*7bded2dbSJung-uk Kim             X509 *ca = sk_X509_value(chain, i);
4274*7bded2dbSJung-uk Kim             if (!tls1_check_cert_param(s, ca, 0)) {
4275*7bded2dbSJung-uk Kim                 if (check_flags) {
4276*7bded2dbSJung-uk Kim                     rv &= ~CERT_PKEY_CA_PARAM;
4277*7bded2dbSJung-uk Kim                     break;
4278*7bded2dbSJung-uk Kim                 } else
4279*7bded2dbSJung-uk Kim                     goto end;
4280*7bded2dbSJung-uk Kim             }
4281*7bded2dbSJung-uk Kim         }
4282*7bded2dbSJung-uk Kim     }
4283*7bded2dbSJung-uk Kim     if (!s->server && strict_mode) {
4284*7bded2dbSJung-uk Kim         STACK_OF(X509_NAME) *ca_dn;
4285*7bded2dbSJung-uk Kim         int check_type = 0;
4286*7bded2dbSJung-uk Kim         switch (pk->type) {
4287*7bded2dbSJung-uk Kim         case EVP_PKEY_RSA:
4288*7bded2dbSJung-uk Kim             check_type = TLS_CT_RSA_SIGN;
4289*7bded2dbSJung-uk Kim             break;
4290*7bded2dbSJung-uk Kim         case EVP_PKEY_DSA:
4291*7bded2dbSJung-uk Kim             check_type = TLS_CT_DSS_SIGN;
4292*7bded2dbSJung-uk Kim             break;
4293*7bded2dbSJung-uk Kim         case EVP_PKEY_EC:
4294*7bded2dbSJung-uk Kim             check_type = TLS_CT_ECDSA_SIGN;
4295*7bded2dbSJung-uk Kim             break;
4296*7bded2dbSJung-uk Kim         case EVP_PKEY_DH:
4297*7bded2dbSJung-uk Kim         case EVP_PKEY_DHX:
4298*7bded2dbSJung-uk Kim             {
4299*7bded2dbSJung-uk Kim                 int cert_type = X509_certificate_type(x, pk);
4300*7bded2dbSJung-uk Kim                 if (cert_type & EVP_PKS_RSA)
4301*7bded2dbSJung-uk Kim                     check_type = TLS_CT_RSA_FIXED_DH;
4302*7bded2dbSJung-uk Kim                 if (cert_type & EVP_PKS_DSA)
4303*7bded2dbSJung-uk Kim                     check_type = TLS_CT_DSS_FIXED_DH;
4304*7bded2dbSJung-uk Kim             }
4305*7bded2dbSJung-uk Kim         }
4306*7bded2dbSJung-uk Kim         if (check_type) {
4307*7bded2dbSJung-uk Kim             const unsigned char *ctypes;
4308*7bded2dbSJung-uk Kim             int ctypelen;
4309*7bded2dbSJung-uk Kim             if (c->ctypes) {
4310*7bded2dbSJung-uk Kim                 ctypes = c->ctypes;
4311*7bded2dbSJung-uk Kim                 ctypelen = (int)c->ctype_num;
4312*7bded2dbSJung-uk Kim             } else {
4313*7bded2dbSJung-uk Kim                 ctypes = (unsigned char *)s->s3->tmp.ctype;
4314*7bded2dbSJung-uk Kim                 ctypelen = s->s3->tmp.ctype_num;
4315*7bded2dbSJung-uk Kim             }
4316*7bded2dbSJung-uk Kim             for (i = 0; i < ctypelen; i++) {
4317*7bded2dbSJung-uk Kim                 if (ctypes[i] == check_type) {
4318*7bded2dbSJung-uk Kim                     rv |= CERT_PKEY_CERT_TYPE;
4319*7bded2dbSJung-uk Kim                     break;
4320*7bded2dbSJung-uk Kim                 }
4321*7bded2dbSJung-uk Kim             }
4322*7bded2dbSJung-uk Kim             if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
4323*7bded2dbSJung-uk Kim                 goto end;
4324*7bded2dbSJung-uk Kim         } else
4325*7bded2dbSJung-uk Kim             rv |= CERT_PKEY_CERT_TYPE;
4326*7bded2dbSJung-uk Kim 
4327*7bded2dbSJung-uk Kim         ca_dn = s->s3->tmp.ca_names;
4328*7bded2dbSJung-uk Kim 
4329*7bded2dbSJung-uk Kim         if (!sk_X509_NAME_num(ca_dn))
4330*7bded2dbSJung-uk Kim             rv |= CERT_PKEY_ISSUER_NAME;
4331*7bded2dbSJung-uk Kim 
4332*7bded2dbSJung-uk Kim         if (!(rv & CERT_PKEY_ISSUER_NAME)) {
4333*7bded2dbSJung-uk Kim             if (ssl_check_ca_name(ca_dn, x))
4334*7bded2dbSJung-uk Kim                 rv |= CERT_PKEY_ISSUER_NAME;
4335*7bded2dbSJung-uk Kim         }
4336*7bded2dbSJung-uk Kim         if (!(rv & CERT_PKEY_ISSUER_NAME)) {
4337*7bded2dbSJung-uk Kim             for (i = 0; i < sk_X509_num(chain); i++) {
4338*7bded2dbSJung-uk Kim                 X509 *xtmp = sk_X509_value(chain, i);
4339*7bded2dbSJung-uk Kim                 if (ssl_check_ca_name(ca_dn, xtmp)) {
4340*7bded2dbSJung-uk Kim                     rv |= CERT_PKEY_ISSUER_NAME;
4341*7bded2dbSJung-uk Kim                     break;
4342*7bded2dbSJung-uk Kim                 }
4343*7bded2dbSJung-uk Kim             }
4344*7bded2dbSJung-uk Kim         }
4345*7bded2dbSJung-uk Kim         if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
4346*7bded2dbSJung-uk Kim             goto end;
4347*7bded2dbSJung-uk Kim     } else
4348*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE;
4349*7bded2dbSJung-uk Kim 
4350*7bded2dbSJung-uk Kim     if (!check_flags || (rv & check_flags) == check_flags)
4351*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_VALID;
4352*7bded2dbSJung-uk Kim 
4353*7bded2dbSJung-uk Kim  end:
4354*7bded2dbSJung-uk Kim 
4355*7bded2dbSJung-uk Kim     if (TLS1_get_version(s) >= TLS1_2_VERSION) {
4356*7bded2dbSJung-uk Kim         if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN)
4357*7bded2dbSJung-uk Kim             rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
4358*7bded2dbSJung-uk Kim         else if (cpk->digest)
4359*7bded2dbSJung-uk Kim             rv |= CERT_PKEY_SIGN;
4360*7bded2dbSJung-uk Kim     } else
4361*7bded2dbSJung-uk Kim         rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
4362*7bded2dbSJung-uk Kim 
4363*7bded2dbSJung-uk Kim     /*
4364*7bded2dbSJung-uk Kim      * When checking a CERT_PKEY structure all flags are irrelevant if the
4365*7bded2dbSJung-uk Kim      * chain is invalid.
4366*7bded2dbSJung-uk Kim      */
4367*7bded2dbSJung-uk Kim     if (!check_flags) {
4368*7bded2dbSJung-uk Kim         if (rv & CERT_PKEY_VALID)
4369*7bded2dbSJung-uk Kim             cpk->valid_flags = rv;
4370*7bded2dbSJung-uk Kim         else {
4371*7bded2dbSJung-uk Kim             /* Preserve explicit sign flag, clear rest */
4372*7bded2dbSJung-uk Kim             cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
4373*7bded2dbSJung-uk Kim             return 0;
4374*7bded2dbSJung-uk Kim         }
4375*7bded2dbSJung-uk Kim     }
4376*7bded2dbSJung-uk Kim     return rv;
4377*7bded2dbSJung-uk Kim }
4378*7bded2dbSJung-uk Kim 
4379*7bded2dbSJung-uk Kim /* Set validity of certificates in an SSL structure */
4380*7bded2dbSJung-uk Kim void tls1_set_cert_validity(SSL *s)
4381*7bded2dbSJung-uk Kim {
4382*7bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
4383*7bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
4384*7bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
4385*7bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA);
4386*7bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA);
4387*7bded2dbSJung-uk Kim     tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
4388*7bded2dbSJung-uk Kim }
4389*7bded2dbSJung-uk Kim 
4390*7bded2dbSJung-uk Kim /* User level utiity function to check a chain is suitable */
4391*7bded2dbSJung-uk Kim int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
4392*7bded2dbSJung-uk Kim {
4393*7bded2dbSJung-uk Kim     return tls1_check_chain(s, x, pk, chain, -1);
4394*7bded2dbSJung-uk Kim }
4395*7bded2dbSJung-uk Kim 
4396*7bded2dbSJung-uk Kim #endif
4397