xref: /dragonfly/crypto/libressl/ssl/t1_lib.c (revision de0e0e4d)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: t1_lib.c,v 1.195 2022/08/17 18:45:25 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino /* ====================================================================
59f5b1c8a1SJohn Marino  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60f5b1c8a1SJohn Marino  *
61f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
62f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
63f5b1c8a1SJohn Marino  * are met:
64f5b1c8a1SJohn Marino  *
65f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the above copyright
66f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
67f5b1c8a1SJohn Marino  *
68f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
69f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in
70f5b1c8a1SJohn Marino  *    the documentation and/or other materials provided with the
71f5b1c8a1SJohn Marino  *    distribution.
72f5b1c8a1SJohn Marino  *
73f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this
74f5b1c8a1SJohn Marino  *    software must display the following acknowledgment:
75f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
76f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77f5b1c8a1SJohn Marino  *
78f5b1c8a1SJohn Marino  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79f5b1c8a1SJohn Marino  *    endorse or promote products derived from this software without
80f5b1c8a1SJohn Marino  *    prior written permission. For written permission, please contact
81f5b1c8a1SJohn Marino  *    openssl-core@openssl.org.
82f5b1c8a1SJohn Marino  *
83f5b1c8a1SJohn Marino  * 5. Products derived from this software may not be called "OpenSSL"
84f5b1c8a1SJohn Marino  *    nor may "OpenSSL" appear in their names without prior written
85f5b1c8a1SJohn Marino  *    permission of the OpenSSL Project.
86f5b1c8a1SJohn Marino  *
87f5b1c8a1SJohn Marino  * 6. Redistributions of any form whatsoever must retain the following
88f5b1c8a1SJohn Marino  *    acknowledgment:
89f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
90f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91f5b1c8a1SJohn Marino  *
92f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93f5b1c8a1SJohn Marino  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95f5b1c8a1SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96f5b1c8a1SJohn Marino  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97f5b1c8a1SJohn Marino  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98f5b1c8a1SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99f5b1c8a1SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101f5b1c8a1SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102f5b1c8a1SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103f5b1c8a1SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
104f5b1c8a1SJohn Marino  * ====================================================================
105f5b1c8a1SJohn Marino  *
106f5b1c8a1SJohn Marino  * This product includes cryptographic software written by Eric Young
107f5b1c8a1SJohn Marino  * (eay@cryptsoft.com).  This product includes software written by Tim
108f5b1c8a1SJohn Marino  * Hudson (tjh@cryptsoft.com).
109f5b1c8a1SJohn Marino  *
110f5b1c8a1SJohn Marino  */
111f5b1c8a1SJohn Marino 
112f5b1c8a1SJohn Marino #include <stdio.h>
113f5b1c8a1SJohn Marino 
114f5b1c8a1SJohn Marino #include <openssl/evp.h>
115f5b1c8a1SJohn Marino #include <openssl/hmac.h>
116f5b1c8a1SJohn Marino #include <openssl/objects.h>
117f5b1c8a1SJohn Marino #include <openssl/ocsp.h>
118f5b1c8a1SJohn Marino 
119f5b1c8a1SJohn Marino #include "bytestring.h"
120*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
12172c33676SMaxim Ag #include "ssl_sigalgs.h"
12272c33676SMaxim Ag #include "ssl_tlsext.h"
123f5b1c8a1SJohn Marino 
1248edacedfSDaniel Fojt static int tls_decrypt_ticket(SSL *s, CBS *ticket, int *alert,
125f5b1c8a1SJohn Marino     SSL_SESSION **psess);
126f5b1c8a1SJohn Marino 
127f5b1c8a1SJohn Marino int
tls1_new(SSL * s)128f5b1c8a1SJohn Marino tls1_new(SSL *s)
129f5b1c8a1SJohn Marino {
130f5b1c8a1SJohn Marino 	if (!ssl3_new(s))
131f5b1c8a1SJohn Marino 		return (0);
132*de0e0e4dSAntonio Huete Jimenez 	s->method->ssl_clear(s);
133f5b1c8a1SJohn Marino 	return (1);
134f5b1c8a1SJohn Marino }
135f5b1c8a1SJohn Marino 
136f5b1c8a1SJohn Marino void
tls1_free(SSL * s)137f5b1c8a1SJohn Marino tls1_free(SSL *s)
138f5b1c8a1SJohn Marino {
139f5b1c8a1SJohn Marino 	if (s == NULL)
140f5b1c8a1SJohn Marino 		return;
141f5b1c8a1SJohn Marino 
14272c33676SMaxim Ag 	free(s->internal->tlsext_session_ticket);
143f5b1c8a1SJohn Marino 	ssl3_free(s);
144f5b1c8a1SJohn Marino }
145f5b1c8a1SJohn Marino 
146f5b1c8a1SJohn Marino void
tls1_clear(SSL * s)147f5b1c8a1SJohn Marino tls1_clear(SSL *s)
148f5b1c8a1SJohn Marino {
149f5b1c8a1SJohn Marino 	ssl3_clear(s);
150*de0e0e4dSAntonio Huete Jimenez 	s->version = s->method->version;
151f5b1c8a1SJohn Marino }
152f5b1c8a1SJohn Marino 
153*de0e0e4dSAntonio Huete Jimenez struct supported_group {
154*de0e0e4dSAntonio Huete Jimenez 	int nid;
155*de0e0e4dSAntonio Huete Jimenez 	int bits;
156f5b1c8a1SJohn Marino };
157f5b1c8a1SJohn Marino 
158*de0e0e4dSAntonio Huete Jimenez /*
159*de0e0e4dSAntonio Huete Jimenez  * Supported groups (formerly known as named curves)
160*de0e0e4dSAntonio Huete Jimenez  * https://www.iana.org/assignments/tls-parameters/#tls-parameters-8
161*de0e0e4dSAntonio Huete Jimenez  */
162*de0e0e4dSAntonio Huete Jimenez static const struct supported_group nid_list[] = {
163*de0e0e4dSAntonio Huete Jimenez 	[1] = {
164*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect163k1,
165*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
166*de0e0e4dSAntonio Huete Jimenez 	},
167*de0e0e4dSAntonio Huete Jimenez 	[2] = {
168*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect163r1,
169*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
170*de0e0e4dSAntonio Huete Jimenez 	},
171*de0e0e4dSAntonio Huete Jimenez 	[3] = {
172*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect163r2,
173*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
174*de0e0e4dSAntonio Huete Jimenez 	},
175*de0e0e4dSAntonio Huete Jimenez 	[4] = {
176*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect193r1,
177*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
178*de0e0e4dSAntonio Huete Jimenez 	},
179*de0e0e4dSAntonio Huete Jimenez 	[5] = {
180*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect193r2,
181*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
182*de0e0e4dSAntonio Huete Jimenez 	},
183*de0e0e4dSAntonio Huete Jimenez 	[6] = {
184*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect233k1,
185*de0e0e4dSAntonio Huete Jimenez 		.bits = 112,
186*de0e0e4dSAntonio Huete Jimenez 	},
187*de0e0e4dSAntonio Huete Jimenez 	[7] = {
188*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect233r1,
189*de0e0e4dSAntonio Huete Jimenez 		.bits = 112,
190*de0e0e4dSAntonio Huete Jimenez 	},
191*de0e0e4dSAntonio Huete Jimenez 	[8] = {
192*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect239k1,
193*de0e0e4dSAntonio Huete Jimenez 		.bits = 112,
194*de0e0e4dSAntonio Huete Jimenez 	},
195*de0e0e4dSAntonio Huete Jimenez 	[9] = {
196*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect283k1,
197*de0e0e4dSAntonio Huete Jimenez 		.bits = 128,
198*de0e0e4dSAntonio Huete Jimenez 	},
199*de0e0e4dSAntonio Huete Jimenez 	[10] = {
200*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect283r1,
201*de0e0e4dSAntonio Huete Jimenez 		.bits = 128,
202*de0e0e4dSAntonio Huete Jimenez 	},
203*de0e0e4dSAntonio Huete Jimenez 	[11] = {
204*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect409k1,
205*de0e0e4dSAntonio Huete Jimenez 		.bits = 192,
206*de0e0e4dSAntonio Huete Jimenez 	},
207*de0e0e4dSAntonio Huete Jimenez 	[12] = {
208*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect409r1,
209*de0e0e4dSAntonio Huete Jimenez 		.bits = 192,
210*de0e0e4dSAntonio Huete Jimenez 	},
211*de0e0e4dSAntonio Huete Jimenez 	[13] = {
212*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect571k1,
213*de0e0e4dSAntonio Huete Jimenez 		.bits = 256,
214*de0e0e4dSAntonio Huete Jimenez 	},
215*de0e0e4dSAntonio Huete Jimenez 	[14] = {
216*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_sect571r1,
217*de0e0e4dSAntonio Huete Jimenez 		.bits = 256,
218*de0e0e4dSAntonio Huete Jimenez 	},
219*de0e0e4dSAntonio Huete Jimenez 	[15] = {
220*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp160k1,
221*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
222*de0e0e4dSAntonio Huete Jimenez 	},
223*de0e0e4dSAntonio Huete Jimenez 	[16] = {
224*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp160r1,
225*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
226*de0e0e4dSAntonio Huete Jimenez 	},
227*de0e0e4dSAntonio Huete Jimenez 	[17] = {
228*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp160r2,
229*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
230*de0e0e4dSAntonio Huete Jimenez 	},
231*de0e0e4dSAntonio Huete Jimenez 	[18] = {
232*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp192k1,
233*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
234*de0e0e4dSAntonio Huete Jimenez 	},
235*de0e0e4dSAntonio Huete Jimenez 	[19] = {
236*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_X9_62_prime192v1,	/* aka secp192r1 */
237*de0e0e4dSAntonio Huete Jimenez 		.bits = 80,
238*de0e0e4dSAntonio Huete Jimenez 	},
239*de0e0e4dSAntonio Huete Jimenez 	[20] = {
240*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp224k1,
241*de0e0e4dSAntonio Huete Jimenez 		.bits = 112,
242*de0e0e4dSAntonio Huete Jimenez 	},
243*de0e0e4dSAntonio Huete Jimenez 	[21] = {
244*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp224r1,
245*de0e0e4dSAntonio Huete Jimenez 		.bits = 112,
246*de0e0e4dSAntonio Huete Jimenez 	},
247*de0e0e4dSAntonio Huete Jimenez 	[22] = {
248*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp256k1,
249*de0e0e4dSAntonio Huete Jimenez 		.bits = 128,
250*de0e0e4dSAntonio Huete Jimenez 	},
251*de0e0e4dSAntonio Huete Jimenez 	[23] = {
252*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_X9_62_prime256v1,	/* aka secp256r1 */
253*de0e0e4dSAntonio Huete Jimenez 		.bits = 128,
254*de0e0e4dSAntonio Huete Jimenez 	},
255*de0e0e4dSAntonio Huete Jimenez 	[24] = {
256*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp384r1,
257*de0e0e4dSAntonio Huete Jimenez 		.bits = 192,
258*de0e0e4dSAntonio Huete Jimenez 	},
259*de0e0e4dSAntonio Huete Jimenez 	[25] = {
260*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_secp521r1,
261*de0e0e4dSAntonio Huete Jimenez 		.bits = 256,
262*de0e0e4dSAntonio Huete Jimenez 	},
263*de0e0e4dSAntonio Huete Jimenez 	[26] = {
264*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_brainpoolP256r1,
265*de0e0e4dSAntonio Huete Jimenez 		.bits = 128,
266*de0e0e4dSAntonio Huete Jimenez 	},
267*de0e0e4dSAntonio Huete Jimenez 	[27] = {
268*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_brainpoolP384r1,
269*de0e0e4dSAntonio Huete Jimenez 		.bits = 192,
270*de0e0e4dSAntonio Huete Jimenez 	},
271*de0e0e4dSAntonio Huete Jimenez 	[28] = {
272*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_brainpoolP512r1,
273*de0e0e4dSAntonio Huete Jimenez 		.bits = 256,
274*de0e0e4dSAntonio Huete Jimenez 	},
275*de0e0e4dSAntonio Huete Jimenez 	[29] = {
276*de0e0e4dSAntonio Huete Jimenez 		.nid = NID_X25519,
277*de0e0e4dSAntonio Huete Jimenez 		.bits = 128,
278*de0e0e4dSAntonio Huete Jimenez 	},
279*de0e0e4dSAntonio Huete Jimenez };
280*de0e0e4dSAntonio Huete Jimenez 
281*de0e0e4dSAntonio Huete Jimenez #define NID_LIST_LEN (sizeof(nid_list) / sizeof(nid_list[0]))
282*de0e0e4dSAntonio Huete Jimenez 
28372c33676SMaxim Ag #if 0
28472c33676SMaxim Ag static const uint8_t ecformats_list[] = {
285f5b1c8a1SJohn Marino 	TLSEXT_ECPOINTFORMAT_uncompressed,
286f5b1c8a1SJohn Marino 	TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
287f5b1c8a1SJohn Marino 	TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
288f5b1c8a1SJohn Marino };
28972c33676SMaxim Ag #endif
290f5b1c8a1SJohn Marino 
29172c33676SMaxim Ag static const uint8_t ecformats_default[] = {
29272c33676SMaxim Ag 	TLSEXT_ECPOINTFORMAT_uncompressed,
29372c33676SMaxim Ag };
29472c33676SMaxim Ag 
29572c33676SMaxim Ag #if 0
296*de0e0e4dSAntonio Huete Jimenez static const uint16_t ecgroups_list[] = {
29772c33676SMaxim Ag 	29,			/* X25519 (29) */
298f5b1c8a1SJohn Marino 	14,			/* sect571r1 (14) */
299f5b1c8a1SJohn Marino 	13,			/* sect571k1 (13) */
300f5b1c8a1SJohn Marino 	25,			/* secp521r1 (25) */
30172c33676SMaxim Ag 	28,			/* brainpoolP512r1 (28) */
302f5b1c8a1SJohn Marino 	11,			/* sect409k1 (11) */
303f5b1c8a1SJohn Marino 	12,			/* sect409r1 (12) */
304f5b1c8a1SJohn Marino 	27,			/* brainpoolP384r1 (27) */
305f5b1c8a1SJohn Marino 	24,			/* secp384r1 (24) */
306f5b1c8a1SJohn Marino 	9,			/* sect283k1 (9) */
307f5b1c8a1SJohn Marino 	10,			/* sect283r1 (10) */
308f5b1c8a1SJohn Marino 	26,			/* brainpoolP256r1 (26) */
309f5b1c8a1SJohn Marino 	22,			/* secp256k1 (22) */
310f5b1c8a1SJohn Marino 	23,			/* secp256r1 (23) */
311f5b1c8a1SJohn Marino 	8,			/* sect239k1 (8) */
312f5b1c8a1SJohn Marino 	6,			/* sect233k1 (6) */
313f5b1c8a1SJohn Marino 	7,			/* sect233r1 (7) */
314f5b1c8a1SJohn Marino 	20,			/* secp224k1 (20) */
315f5b1c8a1SJohn Marino 	21,			/* secp224r1 (21) */
316f5b1c8a1SJohn Marino 	4,			/* sect193r1 (4) */
317f5b1c8a1SJohn Marino 	5,			/* sect193r2 (5) */
318f5b1c8a1SJohn Marino 	18,			/* secp192k1 (18) */
319f5b1c8a1SJohn Marino 	19,			/* secp192r1 (19) */
320f5b1c8a1SJohn Marino 	1,			/* sect163k1 (1) */
321f5b1c8a1SJohn Marino 	2,			/* sect163r1 (2) */
322f5b1c8a1SJohn Marino 	3,			/* sect163r2 (3) */
323f5b1c8a1SJohn Marino 	15,			/* secp160k1 (15) */
324f5b1c8a1SJohn Marino 	16,			/* secp160r1 (16) */
325f5b1c8a1SJohn Marino 	17,			/* secp160r2 (17) */
326f5b1c8a1SJohn Marino };
32772c33676SMaxim Ag #endif
32872c33676SMaxim Ag 
329*de0e0e4dSAntonio Huete Jimenez static const uint16_t ecgroups_client_default[] = {
330f015dc58SDaniel Fojt 	29,			/* X25519 (29) */
331f015dc58SDaniel Fojt 	23,			/* secp256r1 (23) */
332f015dc58SDaniel Fojt 	24,			/* secp384r1 (24) */
333f015dc58SDaniel Fojt 	25,			/* secp521r1 (25) */
334f015dc58SDaniel Fojt };
335f015dc58SDaniel Fojt 
336*de0e0e4dSAntonio Huete Jimenez static const uint16_t ecgroups_server_default[] = {
33772c33676SMaxim Ag 	29,			/* X25519 (29) */
33872c33676SMaxim Ag 	23,			/* secp256r1 (23) */
33972c33676SMaxim Ag 	24,			/* secp384r1 (24) */
34072c33676SMaxim Ag };
341f5b1c8a1SJohn Marino 
342f5b1c8a1SJohn Marino int
tls1_ec_group_id2nid(uint16_t group_id,int * out_nid)343*de0e0e4dSAntonio Huete Jimenez tls1_ec_group_id2nid(uint16_t group_id, int *out_nid)
344f5b1c8a1SJohn Marino {
345*de0e0e4dSAntonio Huete Jimenez 	int nid;
346*de0e0e4dSAntonio Huete Jimenez 
347*de0e0e4dSAntonio Huete Jimenez 	if (group_id >= NID_LIST_LEN)
348f5b1c8a1SJohn Marino 		return 0;
349*de0e0e4dSAntonio Huete Jimenez 
350*de0e0e4dSAntonio Huete Jimenez 	if ((nid = nid_list[group_id].nid) == 0)
351*de0e0e4dSAntonio Huete Jimenez 		return 0;
352*de0e0e4dSAntonio Huete Jimenez 
353*de0e0e4dSAntonio Huete Jimenez 	*out_nid = nid;
354*de0e0e4dSAntonio Huete Jimenez 
355*de0e0e4dSAntonio Huete Jimenez 	return 1;
356f5b1c8a1SJohn Marino }
357f5b1c8a1SJohn Marino 
358*de0e0e4dSAntonio Huete Jimenez int
tls1_ec_group_id2bits(uint16_t group_id,int * out_bits)359*de0e0e4dSAntonio Huete Jimenez tls1_ec_group_id2bits(uint16_t group_id, int *out_bits)
360f5b1c8a1SJohn Marino {
361*de0e0e4dSAntonio Huete Jimenez 	int bits;
362*de0e0e4dSAntonio Huete Jimenez 
363*de0e0e4dSAntonio Huete Jimenez 	if (group_id >= NID_LIST_LEN)
364f5b1c8a1SJohn Marino 		return 0;
365*de0e0e4dSAntonio Huete Jimenez 
366*de0e0e4dSAntonio Huete Jimenez 	if ((bits = nid_list[group_id].bits) == 0)
367*de0e0e4dSAntonio Huete Jimenez 		return 0;
368*de0e0e4dSAntonio Huete Jimenez 
369*de0e0e4dSAntonio Huete Jimenez 	*out_bits = bits;
370*de0e0e4dSAntonio Huete Jimenez 
371*de0e0e4dSAntonio Huete Jimenez 	return 1;
372f5b1c8a1SJohn Marino }
373*de0e0e4dSAntonio Huete Jimenez 
374*de0e0e4dSAntonio Huete Jimenez int
tls1_ec_nid2group_id(int nid,uint16_t * out_group_id)375*de0e0e4dSAntonio Huete Jimenez tls1_ec_nid2group_id(int nid, uint16_t *out_group_id)
376*de0e0e4dSAntonio Huete Jimenez {
377*de0e0e4dSAntonio Huete Jimenez 	uint16_t group_id;
378*de0e0e4dSAntonio Huete Jimenez 
379*de0e0e4dSAntonio Huete Jimenez 	if (nid == 0)
380*de0e0e4dSAntonio Huete Jimenez 		return 0;
381*de0e0e4dSAntonio Huete Jimenez 
382*de0e0e4dSAntonio Huete Jimenez 	for (group_id = 0; group_id < NID_LIST_LEN; group_id++) {
383*de0e0e4dSAntonio Huete Jimenez 		if (nid_list[group_id].nid == nid) {
384*de0e0e4dSAntonio Huete Jimenez 			*out_group_id = group_id;
385*de0e0e4dSAntonio Huete Jimenez 			return 1;
386*de0e0e4dSAntonio Huete Jimenez 		}
387*de0e0e4dSAntonio Huete Jimenez 	}
388*de0e0e4dSAntonio Huete Jimenez 
389*de0e0e4dSAntonio Huete Jimenez 	return 0;
390f5b1c8a1SJohn Marino }
391f5b1c8a1SJohn Marino 
392f5b1c8a1SJohn Marino /*
393f5b1c8a1SJohn Marino  * Return the appropriate format list. If client_formats is non-zero, return
394f5b1c8a1SJohn Marino  * the client/session formats. Otherwise return the custom format list if one
395f5b1c8a1SJohn Marino  * exists, or the default formats if a custom list has not been specified.
396f5b1c8a1SJohn Marino  */
39772c33676SMaxim Ag void
tls1_get_formatlist(const SSL * s,int client_formats,const uint8_t ** pformats,size_t * pformatslen)398*de0e0e4dSAntonio Huete Jimenez tls1_get_formatlist(const SSL *s, int client_formats, const uint8_t **pformats,
399f5b1c8a1SJohn Marino     size_t *pformatslen)
400f5b1c8a1SJohn Marino {
401f5b1c8a1SJohn Marino 	if (client_formats != 0) {
402*de0e0e4dSAntonio Huete Jimenez 		*pformats = s->session->tlsext_ecpointformatlist;
403*de0e0e4dSAntonio Huete Jimenez 		*pformatslen = s->session->tlsext_ecpointformatlist_length;
404f5b1c8a1SJohn Marino 		return;
405f5b1c8a1SJohn Marino 	}
406f5b1c8a1SJohn Marino 
40772c33676SMaxim Ag 	*pformats = s->internal->tlsext_ecpointformatlist;
40872c33676SMaxim Ag 	*pformatslen = s->internal->tlsext_ecpointformatlist_length;
409f5b1c8a1SJohn Marino 	if (*pformats == NULL) {
410f5b1c8a1SJohn Marino 		*pformats = ecformats_default;
411f5b1c8a1SJohn Marino 		*pformatslen = sizeof(ecformats_default);
412f5b1c8a1SJohn Marino 	}
413f5b1c8a1SJohn Marino }
414f5b1c8a1SJohn Marino 
415f5b1c8a1SJohn Marino /*
41672c33676SMaxim Ag  * Return the appropriate group list. If client_groups is non-zero, return
41772c33676SMaxim Ag  * the client/session groups. Otherwise return the custom group list if one
41872c33676SMaxim Ag  * exists, or the default groups if a custom list has not been specified.
419f5b1c8a1SJohn Marino  */
42072c33676SMaxim Ag void
tls1_get_group_list(const SSL * s,int client_groups,const uint16_t ** pgroups,size_t * pgroupslen)421*de0e0e4dSAntonio Huete Jimenez tls1_get_group_list(const SSL *s, int client_groups, const uint16_t **pgroups,
42272c33676SMaxim Ag     size_t *pgroupslen)
423f5b1c8a1SJohn Marino {
42472c33676SMaxim Ag 	if (client_groups != 0) {
425*de0e0e4dSAntonio Huete Jimenez 		*pgroups = s->session->tlsext_supportedgroups;
426*de0e0e4dSAntonio Huete Jimenez 		*pgroupslen = s->session->tlsext_supportedgroups_length;
427f5b1c8a1SJohn Marino 		return;
428f5b1c8a1SJohn Marino 	}
429f5b1c8a1SJohn Marino 
43072c33676SMaxim Ag 	*pgroups = s->internal->tlsext_supportedgroups;
43172c33676SMaxim Ag 	*pgroupslen = s->internal->tlsext_supportedgroups_length;
432f015dc58SDaniel Fojt 	if (*pgroups != NULL)
433f015dc58SDaniel Fojt 		return;
434f015dc58SDaniel Fojt 
435f015dc58SDaniel Fojt 	if (!s->server) {
436*de0e0e4dSAntonio Huete Jimenez 		*pgroups = ecgroups_client_default;
437*de0e0e4dSAntonio Huete Jimenez 		*pgroupslen = sizeof(ecgroups_client_default) / 2;
438f015dc58SDaniel Fojt 	} else {
439*de0e0e4dSAntonio Huete Jimenez 		*pgroups = ecgroups_server_default;
440*de0e0e4dSAntonio Huete Jimenez 		*pgroupslen = sizeof(ecgroups_server_default) / 2;
441f5b1c8a1SJohn Marino 	}
442f5b1c8a1SJohn Marino }
443f5b1c8a1SJohn Marino 
444*de0e0e4dSAntonio Huete Jimenez static int
tls1_get_group_lists(const SSL * ssl,const uint16_t ** pref,size_t * preflen,const uint16_t ** supp,size_t * supplen)445*de0e0e4dSAntonio Huete Jimenez tls1_get_group_lists(const SSL *ssl, const uint16_t **pref, size_t *preflen,
446*de0e0e4dSAntonio Huete Jimenez     const uint16_t **supp, size_t *supplen)
447*de0e0e4dSAntonio Huete Jimenez {
448*de0e0e4dSAntonio Huete Jimenez 	unsigned long server_pref;
449*de0e0e4dSAntonio Huete Jimenez 
450*de0e0e4dSAntonio Huete Jimenez 	/* Cannot do anything on the client side. */
451*de0e0e4dSAntonio Huete Jimenez 	if (!ssl->server)
452*de0e0e4dSAntonio Huete Jimenez 		return 0;
453*de0e0e4dSAntonio Huete Jimenez 
454*de0e0e4dSAntonio Huete Jimenez 	server_pref = (ssl->internal->options & SSL_OP_CIPHER_SERVER_PREFERENCE);
455*de0e0e4dSAntonio Huete Jimenez 	tls1_get_group_list(ssl, (server_pref == 0), pref, preflen);
456*de0e0e4dSAntonio Huete Jimenez 	tls1_get_group_list(ssl, (server_pref != 0), supp, supplen);
457*de0e0e4dSAntonio Huete Jimenez 
458*de0e0e4dSAntonio Huete Jimenez 	return 1;
459*de0e0e4dSAntonio Huete Jimenez }
460*de0e0e4dSAntonio Huete Jimenez 
461*de0e0e4dSAntonio Huete Jimenez static int
tls1_group_id_present(uint16_t group_id,const uint16_t * list,size_t list_len)462*de0e0e4dSAntonio Huete Jimenez tls1_group_id_present(uint16_t group_id, const uint16_t *list, size_t list_len)
463*de0e0e4dSAntonio Huete Jimenez {
464*de0e0e4dSAntonio Huete Jimenez 	size_t i;
465*de0e0e4dSAntonio Huete Jimenez 
466*de0e0e4dSAntonio Huete Jimenez 	for (i = 0; i < list_len; i++) {
467*de0e0e4dSAntonio Huete Jimenez 		if (group_id == list[i])
468*de0e0e4dSAntonio Huete Jimenez 			return 1;
469*de0e0e4dSAntonio Huete Jimenez 	}
470*de0e0e4dSAntonio Huete Jimenez 
471*de0e0e4dSAntonio Huete Jimenez 	return 0;
472*de0e0e4dSAntonio Huete Jimenez }
473*de0e0e4dSAntonio Huete Jimenez 
474*de0e0e4dSAntonio Huete Jimenez int
tls1_count_shared_groups(const SSL * ssl,size_t * out_count)475*de0e0e4dSAntonio Huete Jimenez tls1_count_shared_groups(const SSL *ssl, size_t *out_count)
476*de0e0e4dSAntonio Huete Jimenez {
477*de0e0e4dSAntonio Huete Jimenez 	size_t count, preflen, supplen, i;
478*de0e0e4dSAntonio Huete Jimenez 	const uint16_t *pref, *supp;
479*de0e0e4dSAntonio Huete Jimenez 
480*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_get_group_lists(ssl, &pref, &preflen, &supp, &supplen))
481*de0e0e4dSAntonio Huete Jimenez 		return 0;
482*de0e0e4dSAntonio Huete Jimenez 
483*de0e0e4dSAntonio Huete Jimenez 	count = 0;
484*de0e0e4dSAntonio Huete Jimenez 	for (i = 0; i < preflen; i++) {
485*de0e0e4dSAntonio Huete Jimenez 		if (!tls1_group_id_present(pref[i], supp, supplen))
486*de0e0e4dSAntonio Huete Jimenez 			continue;
487*de0e0e4dSAntonio Huete Jimenez 
488*de0e0e4dSAntonio Huete Jimenez 		if (!ssl_security_shared_group(ssl, pref[i]))
489*de0e0e4dSAntonio Huete Jimenez 			continue;
490*de0e0e4dSAntonio Huete Jimenez 
491*de0e0e4dSAntonio Huete Jimenez 		count++;
492*de0e0e4dSAntonio Huete Jimenez 	}
493*de0e0e4dSAntonio Huete Jimenez 
494*de0e0e4dSAntonio Huete Jimenez 	*out_count = count;
495*de0e0e4dSAntonio Huete Jimenez 
496*de0e0e4dSAntonio Huete Jimenez 	return 1;
497*de0e0e4dSAntonio Huete Jimenez }
498*de0e0e4dSAntonio Huete Jimenez 
499*de0e0e4dSAntonio Huete Jimenez static int
tls1_group_by_index(const SSL * ssl,size_t n,int * out_nid,int (* ssl_security_fn)(const SSL *,uint16_t))500*de0e0e4dSAntonio Huete Jimenez tls1_group_by_index(const SSL *ssl, size_t n, int *out_nid,
501*de0e0e4dSAntonio Huete Jimenez     int (*ssl_security_fn)(const SSL *, uint16_t))
502*de0e0e4dSAntonio Huete Jimenez {
503*de0e0e4dSAntonio Huete Jimenez 	size_t count, preflen, supplen, i;
504*de0e0e4dSAntonio Huete Jimenez 	const uint16_t *pref, *supp;
505*de0e0e4dSAntonio Huete Jimenez 
506*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_get_group_lists(ssl, &pref, &preflen, &supp, &supplen))
507*de0e0e4dSAntonio Huete Jimenez 		return 0;
508*de0e0e4dSAntonio Huete Jimenez 
509*de0e0e4dSAntonio Huete Jimenez 	count = 0;
510*de0e0e4dSAntonio Huete Jimenez 	for (i = 0; i < preflen; i++) {
511*de0e0e4dSAntonio Huete Jimenez 		if (!tls1_group_id_present(pref[i], supp, supplen))
512*de0e0e4dSAntonio Huete Jimenez 			continue;
513*de0e0e4dSAntonio Huete Jimenez 
514*de0e0e4dSAntonio Huete Jimenez 		if (!ssl_security_fn(ssl, pref[i]))
515*de0e0e4dSAntonio Huete Jimenez 			continue;
516*de0e0e4dSAntonio Huete Jimenez 
517*de0e0e4dSAntonio Huete Jimenez 		if (count++ == n)
518*de0e0e4dSAntonio Huete Jimenez 			return tls1_ec_group_id2nid(pref[i], out_nid);
519*de0e0e4dSAntonio Huete Jimenez 	}
520*de0e0e4dSAntonio Huete Jimenez 
521*de0e0e4dSAntonio Huete Jimenez 	return 0;
522*de0e0e4dSAntonio Huete Jimenez }
523*de0e0e4dSAntonio Huete Jimenez 
524*de0e0e4dSAntonio Huete Jimenez int
tls1_get_shared_group_by_index(const SSL * ssl,size_t index,int * out_nid)525*de0e0e4dSAntonio Huete Jimenez tls1_get_shared_group_by_index(const SSL *ssl, size_t index, int *out_nid)
526*de0e0e4dSAntonio Huete Jimenez {
527*de0e0e4dSAntonio Huete Jimenez 	return tls1_group_by_index(ssl, index, out_nid,
528*de0e0e4dSAntonio Huete Jimenez 	    ssl_security_shared_group);
529*de0e0e4dSAntonio Huete Jimenez }
530*de0e0e4dSAntonio Huete Jimenez 
531*de0e0e4dSAntonio Huete Jimenez int
tls1_get_supported_group(const SSL * ssl,int * out_nid)532*de0e0e4dSAntonio Huete Jimenez tls1_get_supported_group(const SSL *ssl, int *out_nid)
533*de0e0e4dSAntonio Huete Jimenez {
534*de0e0e4dSAntonio Huete Jimenez 	return tls1_group_by_index(ssl, 0, out_nid,
535*de0e0e4dSAntonio Huete Jimenez 	    ssl_security_supported_group);
536*de0e0e4dSAntonio Huete Jimenez }
537*de0e0e4dSAntonio Huete Jimenez 
53872c33676SMaxim Ag int
tls1_set_groups(uint16_t ** out_group_ids,size_t * out_group_ids_len,const int * groups,size_t ngroups)53972c33676SMaxim Ag tls1_set_groups(uint16_t **out_group_ids, size_t *out_group_ids_len,
54072c33676SMaxim Ag     const int *groups, size_t ngroups)
54172c33676SMaxim Ag {
54272c33676SMaxim Ag 	uint16_t *group_ids;
54372c33676SMaxim Ag 	size_t i;
54472c33676SMaxim Ag 
545*de0e0e4dSAntonio Huete Jimenez 	if ((group_ids = calloc(ngroups, sizeof(uint16_t))) == NULL)
54672c33676SMaxim Ag 		return 0;
54772c33676SMaxim Ag 
54872c33676SMaxim Ag 	for (i = 0; i < ngroups; i++) {
549*de0e0e4dSAntonio Huete Jimenez 		if (!tls1_ec_nid2group_id(groups[i], &group_ids[i])) {
55072c33676SMaxim Ag 			free(group_ids);
55172c33676SMaxim Ag 			return 0;
55272c33676SMaxim Ag 		}
55372c33676SMaxim Ag 	}
55472c33676SMaxim Ag 
55572c33676SMaxim Ag 	free(*out_group_ids);
55672c33676SMaxim Ag 	*out_group_ids = group_ids;
55772c33676SMaxim Ag 	*out_group_ids_len = ngroups;
55872c33676SMaxim Ag 
55972c33676SMaxim Ag 	return 1;
56072c33676SMaxim Ag }
56172c33676SMaxim Ag 
56272c33676SMaxim Ag int
tls1_set_group_list(uint16_t ** out_group_ids,size_t * out_group_ids_len,const char * groups)56372c33676SMaxim Ag tls1_set_group_list(uint16_t **out_group_ids, size_t *out_group_ids_len,
56472c33676SMaxim Ag     const char *groups)
56572c33676SMaxim Ag {
56672c33676SMaxim Ag 	uint16_t *new_group_ids, *group_ids = NULL;
56772c33676SMaxim Ag 	size_t ngroups = 0;
56872c33676SMaxim Ag 	char *gs, *p, *q;
56972c33676SMaxim Ag 	int nid;
57072c33676SMaxim Ag 
57172c33676SMaxim Ag 	if ((gs = strdup(groups)) == NULL)
57272c33676SMaxim Ag 		return 0;
57372c33676SMaxim Ag 
57472c33676SMaxim Ag 	q = gs;
57572c33676SMaxim Ag 	while ((p = strsep(&q, ":")) != NULL) {
57672c33676SMaxim Ag 		nid = OBJ_sn2nid(p);
57772c33676SMaxim Ag 		if (nid == NID_undef)
57872c33676SMaxim Ag 			nid = OBJ_ln2nid(p);
57972c33676SMaxim Ag 		if (nid == NID_undef)
58072c33676SMaxim Ag 			nid = EC_curve_nist2nid(p);
58172c33676SMaxim Ag 		if (nid == NID_undef)
58272c33676SMaxim Ag 			goto err;
58372c33676SMaxim Ag 
58472c33676SMaxim Ag 		if ((new_group_ids = reallocarray(group_ids, ngroups + 1,
58572c33676SMaxim Ag 		    sizeof(uint16_t))) == NULL)
58672c33676SMaxim Ag 			goto err;
58772c33676SMaxim Ag 		group_ids = new_group_ids;
58872c33676SMaxim Ag 
589*de0e0e4dSAntonio Huete Jimenez 		if (!tls1_ec_nid2group_id(nid, &group_ids[ngroups]))
59072c33676SMaxim Ag 			goto err;
59172c33676SMaxim Ag 
59272c33676SMaxim Ag 		ngroups++;
59372c33676SMaxim Ag 	}
59472c33676SMaxim Ag 
59572c33676SMaxim Ag 	free(gs);
59672c33676SMaxim Ag 	free(*out_group_ids);
59772c33676SMaxim Ag 	*out_group_ids = group_ids;
59872c33676SMaxim Ag 	*out_group_ids_len = ngroups;
59972c33676SMaxim Ag 
60072c33676SMaxim Ag 	return 1;
60172c33676SMaxim Ag 
60272c33676SMaxim Ag  err:
60372c33676SMaxim Ag 	free(gs);
60472c33676SMaxim Ag 	free(group_ids);
60572c33676SMaxim Ag 
60672c33676SMaxim Ag 	return 0;
60772c33676SMaxim Ag }
60872c33676SMaxim Ag 
609*de0e0e4dSAntonio Huete Jimenez /* Check that a group is one of our preferences. */
610f5b1c8a1SJohn Marino int
tls1_check_group(SSL * s,uint16_t group_id)611*de0e0e4dSAntonio Huete Jimenez tls1_check_group(SSL *s, uint16_t group_id)
612f5b1c8a1SJohn Marino {
61372c33676SMaxim Ag 	const uint16_t *groups;
61472c33676SMaxim Ag 	size_t groupslen, i;
615f5b1c8a1SJohn Marino 
61672c33676SMaxim Ag 	tls1_get_group_list(s, 0, &groups, &groupslen);
617f5b1c8a1SJohn Marino 
61872c33676SMaxim Ag 	for (i = 0; i < groupslen; i++) {
619*de0e0e4dSAntonio Huete Jimenez 		if (!ssl_security_supported_group(s, groups[i]))
620*de0e0e4dSAntonio Huete Jimenez 			continue;
621*de0e0e4dSAntonio Huete Jimenez 		if (groups[i] == group_id)
622*de0e0e4dSAntonio Huete Jimenez 			return 1;
623f5b1c8a1SJohn Marino 	}
624*de0e0e4dSAntonio Huete Jimenez 	return 0;
625f5b1c8a1SJohn Marino }
626f5b1c8a1SJohn Marino 
627f5b1c8a1SJohn Marino /* For an EC key set TLS ID and required compression based on parameters. */
628f5b1c8a1SJohn Marino static int
tls1_set_ec_id(uint16_t * group_id,uint8_t * comp_id,EC_KEY * ec)629*de0e0e4dSAntonio Huete Jimenez tls1_set_ec_id(uint16_t *group_id, uint8_t *comp_id, EC_KEY *ec)
630f5b1c8a1SJohn Marino {
631f5b1c8a1SJohn Marino 	const EC_GROUP *grp;
632f5b1c8a1SJohn Marino 	const EC_METHOD *meth;
6338edacedfSDaniel Fojt 	int prime_field;
6348edacedfSDaniel Fojt 	int nid;
635f5b1c8a1SJohn Marino 
636f5b1c8a1SJohn Marino 	if (ec == NULL)
637f5b1c8a1SJohn Marino 		return (0);
638f5b1c8a1SJohn Marino 
639*de0e0e4dSAntonio Huete Jimenez 	/* Determine whether the group is defined over a prime field. */
640f5b1c8a1SJohn Marino 	if ((grp = EC_KEY_get0_group(ec)) == NULL)
641f5b1c8a1SJohn Marino 		return (0);
642f5b1c8a1SJohn Marino 	if ((meth = EC_GROUP_method_of(grp)) == NULL)
643f5b1c8a1SJohn Marino 		return (0);
6448edacedfSDaniel Fojt 	prime_field = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
645f5b1c8a1SJohn Marino 
646*de0e0e4dSAntonio Huete Jimenez 	/* Determine group ID. */
647f5b1c8a1SJohn Marino 	nid = EC_GROUP_get_curve_name(grp);
648*de0e0e4dSAntonio Huete Jimenez 	/* If we have an ID set it, otherwise set arbitrary explicit group. */
649*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_ec_nid2group_id(nid, group_id))
650*de0e0e4dSAntonio Huete Jimenez 		*group_id = prime_field ? 0xff01 : 0xff02;
6518edacedfSDaniel Fojt 
6528edacedfSDaniel Fojt 	if (comp_id == NULL)
6538edacedfSDaniel Fojt 		return (1);
654f5b1c8a1SJohn Marino 
655f5b1c8a1SJohn Marino 	/* Specify the compression identifier. */
656f5b1c8a1SJohn Marino 	if (EC_KEY_get0_public_key(ec) == NULL)
657f5b1c8a1SJohn Marino 		return (0);
658f5b1c8a1SJohn Marino 	*comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
6598edacedfSDaniel Fojt 	if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
6608edacedfSDaniel Fojt 		*comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
6618edacedfSDaniel Fojt 		if (prime_field)
6628edacedfSDaniel Fojt 			*comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
663f5b1c8a1SJohn Marino 	}
6648edacedfSDaniel Fojt 
665f5b1c8a1SJohn Marino 	return (1);
666f5b1c8a1SJohn Marino }
667f5b1c8a1SJohn Marino 
668f5b1c8a1SJohn Marino /* Check that an EC key is compatible with extensions. */
669f5b1c8a1SJohn Marino static int
tls1_check_ec_key(SSL * s,const uint16_t * group_id,const uint8_t * comp_id)670*de0e0e4dSAntonio Huete Jimenez tls1_check_ec_key(SSL *s, const uint16_t *group_id, const uint8_t *comp_id)
671f5b1c8a1SJohn Marino {
67272c33676SMaxim Ag 	size_t groupslen, formatslen, i;
67372c33676SMaxim Ag 	const uint16_t *groups;
674f5b1c8a1SJohn Marino 	const uint8_t *formats;
675f5b1c8a1SJohn Marino 
676f5b1c8a1SJohn Marino 	/*
677f5b1c8a1SJohn Marino 	 * Check point formats extension if present, otherwise everything
678f5b1c8a1SJohn Marino 	 * is supported (see RFC4492).
679f5b1c8a1SJohn Marino 	 */
680f5b1c8a1SJohn Marino 	tls1_get_formatlist(s, 1, &formats, &formatslen);
681f5b1c8a1SJohn Marino 	if (comp_id != NULL && formats != NULL) {
682f5b1c8a1SJohn Marino 		for (i = 0; i < formatslen; i++) {
683f5b1c8a1SJohn Marino 			if (formats[i] == *comp_id)
684f5b1c8a1SJohn Marino 				break;
685f5b1c8a1SJohn Marino 		}
686f5b1c8a1SJohn Marino 		if (i == formatslen)
687f5b1c8a1SJohn Marino 			return (0);
688f5b1c8a1SJohn Marino 	}
689f5b1c8a1SJohn Marino 
690f5b1c8a1SJohn Marino 	/*
691*de0e0e4dSAntonio Huete Jimenez 	 * Check group list if present, otherwise everything is supported.
692f5b1c8a1SJohn Marino 	 */
69372c33676SMaxim Ag 	tls1_get_group_list(s, 1, &groups, &groupslen);
694*de0e0e4dSAntonio Huete Jimenez 	if (group_id != NULL && groups != NULL) {
69572c33676SMaxim Ag 		for (i = 0; i < groupslen; i++) {
696*de0e0e4dSAntonio Huete Jimenez 			if (groups[i] == *group_id)
697f5b1c8a1SJohn Marino 				break;
698f5b1c8a1SJohn Marino 		}
69972c33676SMaxim Ag 		if (i == groupslen)
700f5b1c8a1SJohn Marino 			return (0);
701f5b1c8a1SJohn Marino 	}
702f5b1c8a1SJohn Marino 
703f5b1c8a1SJohn Marino 	return (1);
704f5b1c8a1SJohn Marino }
705f5b1c8a1SJohn Marino 
706f5b1c8a1SJohn Marino /* Check EC server key is compatible with client extensions. */
707f5b1c8a1SJohn Marino int
tls1_check_ec_server_key(SSL * s)708f5b1c8a1SJohn Marino tls1_check_ec_server_key(SSL *s)
709f5b1c8a1SJohn Marino {
710*de0e0e4dSAntonio Huete Jimenez 	SSL_CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC;
711*de0e0e4dSAntonio Huete Jimenez 	uint16_t group_id;
712f5b1c8a1SJohn Marino 	uint8_t comp_id;
713*de0e0e4dSAntonio Huete Jimenez 	EC_KEY *eckey;
714f5b1c8a1SJohn Marino 	EVP_PKEY *pkey;
715f5b1c8a1SJohn Marino 
716f5b1c8a1SJohn Marino 	if (cpk->x509 == NULL || cpk->privatekey == NULL)
717f5b1c8a1SJohn Marino 		return (0);
718*de0e0e4dSAntonio Huete Jimenez 	if ((pkey = X509_get0_pubkey(cpk->x509)) == NULL)
719f5b1c8a1SJohn Marino 		return (0);
720*de0e0e4dSAntonio Huete Jimenez 	if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
721*de0e0e4dSAntonio Huete Jimenez 		return (0);
722*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_set_ec_id(&group_id, &comp_id, eckey))
723f5b1c8a1SJohn Marino 		return (0);
724f5b1c8a1SJohn Marino 
725*de0e0e4dSAntonio Huete Jimenez 	return tls1_check_ec_key(s, &group_id, &comp_id);
726f5b1c8a1SJohn Marino }
727f5b1c8a1SJohn Marino 
728f5b1c8a1SJohn Marino int
ssl_check_clienthello_tlsext_early(SSL * s)729f5b1c8a1SJohn Marino ssl_check_clienthello_tlsext_early(SSL *s)
730f5b1c8a1SJohn Marino {
731f5b1c8a1SJohn Marino 	int ret = SSL_TLSEXT_ERR_NOACK;
732f5b1c8a1SJohn Marino 	int al = SSL_AD_UNRECOGNIZED_NAME;
733f5b1c8a1SJohn Marino 
734f5b1c8a1SJohn Marino 	/* The handling of the ECPointFormats extension is done elsewhere, namely in
735f5b1c8a1SJohn Marino 	 * ssl3_choose_cipher in s3_lib.c.
736f5b1c8a1SJohn Marino 	 */
737f5b1c8a1SJohn Marino 	/* The handling of the EllipticCurves extension is done elsewhere, namely in
738f5b1c8a1SJohn Marino 	 * ssl3_choose_cipher in s3_lib.c.
739f5b1c8a1SJohn Marino 	 */
740f5b1c8a1SJohn Marino 
74172c33676SMaxim Ag 	if (s->ctx != NULL && s->ctx->internal->tlsext_servername_callback != 0)
74272c33676SMaxim Ag 		ret = s->ctx->internal->tlsext_servername_callback(s, &al,
74372c33676SMaxim Ag 		    s->ctx->internal->tlsext_servername_arg);
74472c33676SMaxim Ag 	else if (s->initial_ctx != NULL && s->initial_ctx->internal->tlsext_servername_callback != 0)
74572c33676SMaxim Ag 		ret = s->initial_ctx->internal->tlsext_servername_callback(s, &al,
74672c33676SMaxim Ag 		    s->initial_ctx->internal->tlsext_servername_arg);
747f5b1c8a1SJohn Marino 
748f5b1c8a1SJohn Marino 	switch (ret) {
749f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_ALERT_FATAL:
750f5b1c8a1SJohn Marino 		ssl3_send_alert(s, SSL3_AL_FATAL, al);
751f5b1c8a1SJohn Marino 		return -1;
752f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_ALERT_WARNING:
753f5b1c8a1SJohn Marino 		ssl3_send_alert(s, SSL3_AL_WARNING, al);
754f5b1c8a1SJohn Marino 		return 1;
755f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_NOACK:
756f5b1c8a1SJohn Marino 	default:
757f5b1c8a1SJohn Marino 		return 1;
758f5b1c8a1SJohn Marino 	}
759f5b1c8a1SJohn Marino }
760f5b1c8a1SJohn Marino 
761f5b1c8a1SJohn Marino int
ssl_check_clienthello_tlsext_late(SSL * s)762f5b1c8a1SJohn Marino ssl_check_clienthello_tlsext_late(SSL *s)
763f5b1c8a1SJohn Marino {
764f5b1c8a1SJohn Marino 	int ret = SSL_TLSEXT_ERR_OK;
765f5b1c8a1SJohn Marino 	int al = 0;	/* XXX gcc3 */
766f5b1c8a1SJohn Marino 
767f5b1c8a1SJohn Marino 	/* If status request then ask callback what to do.
768f5b1c8a1SJohn Marino  	 * Note: this must be called after servername callbacks in case
769f5b1c8a1SJohn Marino  	 * the certificate has changed, and must be called after the cipher
770f5b1c8a1SJohn Marino 	 * has been chosen because this may influence which certificate is sent
771f5b1c8a1SJohn Marino  	 */
772f5b1c8a1SJohn Marino 	if ((s->tlsext_status_type != -1) &&
77372c33676SMaxim Ag 	    s->ctx && s->ctx->internal->tlsext_status_cb) {
774f5b1c8a1SJohn Marino 		int r;
775*de0e0e4dSAntonio Huete Jimenez 		SSL_CERT_PKEY *certpkey;
776f5b1c8a1SJohn Marino 		certpkey = ssl_get_server_send_pkey(s);
777f5b1c8a1SJohn Marino 		/* If no certificate can't return certificate status */
778f5b1c8a1SJohn Marino 		if (certpkey == NULL) {
77972c33676SMaxim Ag 			s->internal->tlsext_status_expected = 0;
780f5b1c8a1SJohn Marino 			return 1;
781f5b1c8a1SJohn Marino 		}
782f5b1c8a1SJohn Marino 		/* Set current certificate to one we will use so
783f5b1c8a1SJohn Marino 		 * SSL_get_certificate et al can pick it up.
784f5b1c8a1SJohn Marino 		 */
785f5b1c8a1SJohn Marino 		s->cert->key = certpkey;
78672c33676SMaxim Ag 		r = s->ctx->internal->tlsext_status_cb(s,
78772c33676SMaxim Ag 		    s->ctx->internal->tlsext_status_arg);
788f5b1c8a1SJohn Marino 		switch (r) {
789f5b1c8a1SJohn Marino 			/* We don't want to send a status request response */
790f5b1c8a1SJohn Marino 		case SSL_TLSEXT_ERR_NOACK:
79172c33676SMaxim Ag 			s->internal->tlsext_status_expected = 0;
792f5b1c8a1SJohn Marino 			break;
793f5b1c8a1SJohn Marino 			/* status request response should be sent */
794f5b1c8a1SJohn Marino 		case SSL_TLSEXT_ERR_OK:
79572c33676SMaxim Ag 			if (s->internal->tlsext_ocsp_resp)
79672c33676SMaxim Ag 				s->internal->tlsext_status_expected = 1;
797f5b1c8a1SJohn Marino 			else
79872c33676SMaxim Ag 				s->internal->tlsext_status_expected = 0;
799f5b1c8a1SJohn Marino 			break;
800f5b1c8a1SJohn Marino 			/* something bad happened */
801f5b1c8a1SJohn Marino 		case SSL_TLSEXT_ERR_ALERT_FATAL:
802f5b1c8a1SJohn Marino 			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
803f5b1c8a1SJohn Marino 			al = SSL_AD_INTERNAL_ERROR;
804f5b1c8a1SJohn Marino 			goto err;
805f5b1c8a1SJohn Marino 		}
806f5b1c8a1SJohn Marino 	} else
80772c33676SMaxim Ag 		s->internal->tlsext_status_expected = 0;
808f5b1c8a1SJohn Marino 
809f5b1c8a1SJohn Marino  err:
810f5b1c8a1SJohn Marino 	switch (ret) {
811f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_ALERT_FATAL:
812f5b1c8a1SJohn Marino 		ssl3_send_alert(s, SSL3_AL_FATAL, al);
813f5b1c8a1SJohn Marino 		return -1;
814f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_ALERT_WARNING:
815f5b1c8a1SJohn Marino 		ssl3_send_alert(s, SSL3_AL_WARNING, al);
816f5b1c8a1SJohn Marino 		return 1;
817f5b1c8a1SJohn Marino 	default:
818f5b1c8a1SJohn Marino 		return 1;
819f5b1c8a1SJohn Marino 	}
820f5b1c8a1SJohn Marino }
821f5b1c8a1SJohn Marino 
822f5b1c8a1SJohn Marino int
ssl_check_serverhello_tlsext(SSL * s)823f5b1c8a1SJohn Marino ssl_check_serverhello_tlsext(SSL *s)
824f5b1c8a1SJohn Marino {
825f5b1c8a1SJohn Marino 	int ret = SSL_TLSEXT_ERR_NOACK;
826f5b1c8a1SJohn Marino 	int al = SSL_AD_UNRECOGNIZED_NAME;
827f5b1c8a1SJohn Marino 
828f5b1c8a1SJohn Marino 	ret = SSL_TLSEXT_ERR_OK;
829f5b1c8a1SJohn Marino 
83072c33676SMaxim Ag 	if (s->ctx != NULL && s->ctx->internal->tlsext_servername_callback != 0)
83172c33676SMaxim Ag 		ret = s->ctx->internal->tlsext_servername_callback(s, &al,
83272c33676SMaxim Ag 		    s->ctx->internal->tlsext_servername_arg);
83372c33676SMaxim Ag 	else if (s->initial_ctx != NULL && s->initial_ctx->internal->tlsext_servername_callback != 0)
83472c33676SMaxim Ag 		ret = s->initial_ctx->internal->tlsext_servername_callback(s, &al,
83572c33676SMaxim Ag 		    s->initial_ctx->internal->tlsext_servername_arg);
836f5b1c8a1SJohn Marino 
837f5b1c8a1SJohn Marino 	/* If we've requested certificate status and we wont get one
838f5b1c8a1SJohn Marino  	 * tell the callback
839f5b1c8a1SJohn Marino  	 */
84072c33676SMaxim Ag 	if ((s->tlsext_status_type != -1) && !(s->internal->tlsext_status_expected) &&
84172c33676SMaxim Ag 	    s->ctx && s->ctx->internal->tlsext_status_cb) {
842f5b1c8a1SJohn Marino 		int r;
8438edacedfSDaniel Fojt 
84472c33676SMaxim Ag 		free(s->internal->tlsext_ocsp_resp);
84572c33676SMaxim Ag 		s->internal->tlsext_ocsp_resp = NULL;
8468edacedfSDaniel Fojt 		s->internal->tlsext_ocsp_resp_len = 0;
8478edacedfSDaniel Fojt 
84872c33676SMaxim Ag 		r = s->ctx->internal->tlsext_status_cb(s,
84972c33676SMaxim Ag 		    s->ctx->internal->tlsext_status_arg);
850f5b1c8a1SJohn Marino 		if (r == 0) {
851f5b1c8a1SJohn Marino 			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
852f5b1c8a1SJohn Marino 			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
853f5b1c8a1SJohn Marino 		}
854f5b1c8a1SJohn Marino 		if (r < 0) {
855f5b1c8a1SJohn Marino 			al = SSL_AD_INTERNAL_ERROR;
856f5b1c8a1SJohn Marino 			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
857f5b1c8a1SJohn Marino 		}
858f5b1c8a1SJohn Marino 	}
859f5b1c8a1SJohn Marino 
860f5b1c8a1SJohn Marino 	switch (ret) {
861f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_ALERT_FATAL:
862f5b1c8a1SJohn Marino 		ssl3_send_alert(s, SSL3_AL_FATAL, al);
863f5b1c8a1SJohn Marino 		return -1;
864f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_ALERT_WARNING:
865f5b1c8a1SJohn Marino 		ssl3_send_alert(s, SSL3_AL_WARNING, al);
866f5b1c8a1SJohn Marino 		return 1;
867f5b1c8a1SJohn Marino 	case SSL_TLSEXT_ERR_NOACK:
868f5b1c8a1SJohn Marino 	default:
869f5b1c8a1SJohn Marino 		return 1;
870f5b1c8a1SJohn Marino 	}
871f5b1c8a1SJohn Marino }
872f5b1c8a1SJohn Marino 
873f5b1c8a1SJohn Marino /* Since the server cache lookup is done early on in the processing of the
874f5b1c8a1SJohn Marino  * ClientHello, and other operations depend on the result, we need to handle
875f5b1c8a1SJohn Marino  * any TLS session ticket extension at the same time.
876f5b1c8a1SJohn Marino  *
87772c33676SMaxim Ag  *   ext_block: a CBS for the ClientHello extensions block.
878f5b1c8a1SJohn Marino  *   ret: (output) on return, if a ticket was decrypted, then this is set to
879f5b1c8a1SJohn Marino  *       point to the resulting session.
880f5b1c8a1SJohn Marino  *
88172c33676SMaxim Ag  * If s->internal->tls_session_secret_cb is set then we are expecting a pre-shared key
882f5b1c8a1SJohn Marino  * ciphersuite, in which case we have no use for session tickets and one will
88372c33676SMaxim Ag  * never be decrypted, nor will s->internal->tlsext_ticket_expected be set to 1.
884f5b1c8a1SJohn Marino  *
885f5b1c8a1SJohn Marino  * Returns:
8868edacedfSDaniel Fojt  *    TLS1_TICKET_FATAL_ERROR: error from parsing or decrypting the ticket.
8878edacedfSDaniel Fojt  *    TLS1_TICKET_NONE: no ticket was found (or was ignored, based on settings).
8888edacedfSDaniel Fojt  *    TLS1_TICKET_EMPTY: a zero length extension was found, indicating that the
8898edacedfSDaniel Fojt  *       client supports session tickets but doesn't currently have one to offer.
8908edacedfSDaniel Fojt  *    TLS1_TICKET_NOT_DECRYPTED: either s->internal->tls_session_secret_cb was
8918edacedfSDaniel Fojt  *       set, or a ticket was offered but couldn't be decrypted because of a
8928edacedfSDaniel Fojt  *       non-fatal error.
8938edacedfSDaniel Fojt  *    TLS1_TICKET_DECRYPTED: a ticket was successfully decrypted and *ret was set.
894f5b1c8a1SJohn Marino  *
895f5b1c8a1SJohn Marino  * Side effects:
89672c33676SMaxim Ag  *   Sets s->internal->tlsext_ticket_expected to 1 if the server will have to issue
897f5b1c8a1SJohn Marino  *   a new session ticket to the client because the client indicated support
89872c33676SMaxim Ag  *   (and s->internal->tls_session_secret_cb is NULL) but the client either doesn't have
899f5b1c8a1SJohn Marino  *   a session ticket or we couldn't use the one it gave us, or if
900f5b1c8a1SJohn Marino  *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
90172c33676SMaxim Ag  *   Otherwise, s->internal->tlsext_ticket_expected is set to 0.
902f5b1c8a1SJohn Marino  */
903f5b1c8a1SJohn Marino int
tls1_process_ticket(SSL * s,CBS * ext_block,int * alert,SSL_SESSION ** ret)9048edacedfSDaniel Fojt tls1_process_ticket(SSL *s, CBS *ext_block, int *alert, SSL_SESSION **ret)
905f5b1c8a1SJohn Marino {
906cca6fc52SDaniel Fojt 	CBS extensions, ext_data;
907cca6fc52SDaniel Fojt 	uint16_t ext_type = 0;
908f5b1c8a1SJohn Marino 
90972c33676SMaxim Ag 	s->internal->tlsext_ticket_expected = 0;
910f5b1c8a1SJohn Marino 	*ret = NULL;
911f5b1c8a1SJohn Marino 
91272c33676SMaxim Ag 	/*
91372c33676SMaxim Ag 	 * If tickets disabled behave as if no ticket present to permit stateful
91472c33676SMaxim Ag 	 * resumption.
915f5b1c8a1SJohn Marino 	 */
916f5b1c8a1SJohn Marino 	if (SSL_get_options(s) & SSL_OP_NO_TICKET)
9178edacedfSDaniel Fojt 		return TLS1_TICKET_NONE;
91872c33676SMaxim Ag 
91972c33676SMaxim Ag 	/*
92072c33676SMaxim Ag 	 * An empty extensions block is valid, but obviously does not contain
92172c33676SMaxim Ag 	 * a session ticket.
92272c33676SMaxim Ag 	 */
92372c33676SMaxim Ag 	if (CBS_len(ext_block) == 0)
9248edacedfSDaniel Fojt 		return TLS1_TICKET_NONE;
925f5b1c8a1SJohn Marino 
9268edacedfSDaniel Fojt 	if (!CBS_get_u16_length_prefixed(ext_block, &extensions)) {
9278edacedfSDaniel Fojt 		*alert = SSL_AD_DECODE_ERROR;
9288edacedfSDaniel Fojt 		return TLS1_TICKET_FATAL_ERROR;
9298edacedfSDaniel Fojt 	}
930f5b1c8a1SJohn Marino 
931f5b1c8a1SJohn Marino 	while (CBS_len(&extensions) > 0) {
932f5b1c8a1SJohn Marino 		if (!CBS_get_u16(&extensions, &ext_type) ||
9338edacedfSDaniel Fojt 		    !CBS_get_u16_length_prefixed(&extensions, &ext_data)) {
9348edacedfSDaniel Fojt 			*alert = SSL_AD_DECODE_ERROR;
9358edacedfSDaniel Fojt 			return TLS1_TICKET_FATAL_ERROR;
9368edacedfSDaniel Fojt 		}
937f5b1c8a1SJohn Marino 
938cca6fc52SDaniel Fojt 		if (ext_type == TLSEXT_TYPE_session_ticket)
939cca6fc52SDaniel Fojt 			break;
940cca6fc52SDaniel Fojt 	}
941cca6fc52SDaniel Fojt 
942cca6fc52SDaniel Fojt 	if (ext_type != TLSEXT_TYPE_session_ticket)
9438edacedfSDaniel Fojt 		return TLS1_TICKET_NONE;
944cca6fc52SDaniel Fojt 
945f5b1c8a1SJohn Marino 	if (CBS_len(&ext_data) == 0) {
946cca6fc52SDaniel Fojt 		/*
947cca6fc52SDaniel Fojt 		 * The client will accept a ticket but does not currently
948cca6fc52SDaniel Fojt 		 * have one.
949cca6fc52SDaniel Fojt 		 */
95072c33676SMaxim Ag 		s->internal->tlsext_ticket_expected = 1;
9518edacedfSDaniel Fojt 		return TLS1_TICKET_EMPTY;
952f5b1c8a1SJohn Marino 	}
953cca6fc52SDaniel Fojt 
95472c33676SMaxim Ag 	if (s->internal->tls_session_secret_cb != NULL) {
955cca6fc52SDaniel Fojt 		/*
956cca6fc52SDaniel Fojt 		 * Indicate that the ticket could not be decrypted rather than
957cca6fc52SDaniel Fojt 		 * generating the session from ticket now, trigger abbreviated
958cca6fc52SDaniel Fojt 		 * handshake based on external mechanism to calculate the master
959cca6fc52SDaniel Fojt 		 * secret later.
960cca6fc52SDaniel Fojt 		 */
9618edacedfSDaniel Fojt 		return TLS1_TICKET_NOT_DECRYPTED;
962f5b1c8a1SJohn Marino 	}
963f5b1c8a1SJohn Marino 
9648edacedfSDaniel Fojt 	return tls_decrypt_ticket(s, &ext_data, alert, ret);
965f5b1c8a1SJohn Marino }
966f5b1c8a1SJohn Marino 
967f5b1c8a1SJohn Marino /* tls_decrypt_ticket attempts to decrypt a session ticket.
968f5b1c8a1SJohn Marino  *
969cca6fc52SDaniel Fojt  *   ticket: a CBS containing the body of the session ticket extension.
970f5b1c8a1SJohn Marino  *   psess: (output) on return, if a ticket was decrypted, then this is set to
971f5b1c8a1SJohn Marino  *       point to the resulting session.
972f5b1c8a1SJohn Marino  *
973f5b1c8a1SJohn Marino  * Returns:
9748edacedfSDaniel Fojt  *    TLS1_TICKET_FATAL_ERROR: error from parsing or decrypting the ticket.
9758edacedfSDaniel Fojt  *    TLS1_TICKET_NOT_DECRYPTED: the ticket couldn't be decrypted.
9768edacedfSDaniel Fojt  *    TLS1_TICKET_DECRYPTED: a ticket was decrypted and *psess was set.
977f5b1c8a1SJohn Marino  */
978f5b1c8a1SJohn Marino static int
tls_decrypt_ticket(SSL * s,CBS * ticket,int * alert,SSL_SESSION ** psess)9798edacedfSDaniel Fojt tls_decrypt_ticket(SSL *s, CBS *ticket, int *alert, SSL_SESSION **psess)
980f5b1c8a1SJohn Marino {
981cca6fc52SDaniel Fojt 	CBS ticket_name, ticket_iv, ticket_encdata, ticket_hmac;
982cca6fc52SDaniel Fojt 	SSL_SESSION *sess = NULL;
983cca6fc52SDaniel Fojt 	unsigned char *sdec = NULL;
984cca6fc52SDaniel Fojt 	size_t sdec_len = 0;
985f5b1c8a1SJohn Marino 	const unsigned char *p;
986cca6fc52SDaniel Fojt 	unsigned char hmac[EVP_MAX_MD_SIZE];
987cca6fc52SDaniel Fojt 	HMAC_CTX *hctx = NULL;
988cca6fc52SDaniel Fojt 	EVP_CIPHER_CTX *cctx = NULL;
989f5b1c8a1SJohn Marino 	SSL_CTX *tctx = s->initial_ctx;
990cca6fc52SDaniel Fojt 	int slen, hlen;
9918edacedfSDaniel Fojt 	int alert_desc = SSL_AD_INTERNAL_ERROR;
9928edacedfSDaniel Fojt 	int ret = TLS1_TICKET_FATAL_ERROR;
993cca6fc52SDaniel Fojt 
994cca6fc52SDaniel Fojt 	*psess = NULL;
995cca6fc52SDaniel Fojt 
996cca6fc52SDaniel Fojt 	if (!CBS_get_bytes(ticket, &ticket_name, 16))
997cca6fc52SDaniel Fojt 		goto derr;
998cca6fc52SDaniel Fojt 
999cca6fc52SDaniel Fojt 	/*
1000cca6fc52SDaniel Fojt 	 * Initialize session ticket encryption and HMAC contexts.
1001cca6fc52SDaniel Fojt 	 */
1002cca6fc52SDaniel Fojt 	if ((cctx = EVP_CIPHER_CTX_new()) == NULL)
1003cca6fc52SDaniel Fojt 		goto err;
1004cca6fc52SDaniel Fojt 	if ((hctx = HMAC_CTX_new()) == NULL)
1005cca6fc52SDaniel Fojt 		goto err;
1006cca6fc52SDaniel Fojt 
1007cca6fc52SDaniel Fojt 	if (tctx->internal->tlsext_ticket_key_cb != NULL) {
1008cca6fc52SDaniel Fojt 		int rv;
1009530c17a6SJohn Marino 
1010530c17a6SJohn Marino 		/*
1011530c17a6SJohn Marino 		 * The API guarantees EVP_MAX_IV_LENGTH bytes of space for
1012530c17a6SJohn Marino 		 * the iv to tlsext_ticket_key_cb().  Since the total space
1013530c17a6SJohn Marino 		 * required for a session cookie is never less than this,
1014530c17a6SJohn Marino 		 * this check isn't too strict.  The exact check comes later.
1015530c17a6SJohn Marino 		 */
1016cca6fc52SDaniel Fojt 		if (CBS_len(ticket) < EVP_MAX_IV_LENGTH)
1017cca6fc52SDaniel Fojt 			goto derr;
1018530c17a6SJohn Marino 
1019cca6fc52SDaniel Fojt 		if ((rv = tctx->internal->tlsext_ticket_key_cb(s,
1020cca6fc52SDaniel Fojt 		    (unsigned char *)CBS_data(&ticket_name),
1021cca6fc52SDaniel Fojt 		    (unsigned char *)CBS_data(ticket), cctx, hctx, 0)) < 0)
1022cca6fc52SDaniel Fojt 			goto err;
1023cca6fc52SDaniel Fojt 		if (rv == 0)
1024cca6fc52SDaniel Fojt 			goto derr;
10258edacedfSDaniel Fojt 		if (rv == 2) {
10268edacedfSDaniel Fojt 			/* Renew ticket. */
10278edacedfSDaniel Fojt 			s->internal->tlsext_ticket_expected = 1;
10288edacedfSDaniel Fojt 		}
1029cca6fc52SDaniel Fojt 
1030cca6fc52SDaniel Fojt 		/*
1031cca6fc52SDaniel Fojt 		 * Now that the cipher context is initialised, we can extract
1032cca6fc52SDaniel Fojt 		 * the IV since its length is known.
1033cca6fc52SDaniel Fojt 		 */
1034cca6fc52SDaniel Fojt 		if (!CBS_get_bytes(ticket, &ticket_iv,
1035cca6fc52SDaniel Fojt 		    EVP_CIPHER_CTX_iv_length(cctx)))
1036cca6fc52SDaniel Fojt 			goto derr;
1037f5b1c8a1SJohn Marino 	} else {
1038cca6fc52SDaniel Fojt 		/* Check that the key name matches. */
1039cca6fc52SDaniel Fojt 		if (!CBS_mem_equal(&ticket_name,
1040cca6fc52SDaniel Fojt 		    tctx->internal->tlsext_tick_key_name,
1041cca6fc52SDaniel Fojt 		    sizeof(tctx->internal->tlsext_tick_key_name)))
1042cca6fc52SDaniel Fojt 			goto derr;
1043cca6fc52SDaniel Fojt 		if (!CBS_get_bytes(ticket, &ticket_iv,
1044cca6fc52SDaniel Fojt 		    EVP_CIPHER_iv_length(EVP_aes_128_cbc())))
1045cca6fc52SDaniel Fojt 			goto derr;
1046cca6fc52SDaniel Fojt 		if (!EVP_DecryptInit_ex(cctx, EVP_aes_128_cbc(), NULL,
1047cca6fc52SDaniel Fojt 		    tctx->internal->tlsext_tick_aes_key, CBS_data(&ticket_iv)))
1048cca6fc52SDaniel Fojt 			goto err;
1049cca6fc52SDaniel Fojt 		if (!HMAC_Init_ex(hctx, tctx->internal->tlsext_tick_hmac_key,
1050cca6fc52SDaniel Fojt 		    sizeof(tctx->internal->tlsext_tick_hmac_key), EVP_sha256(),
1051cca6fc52SDaniel Fojt 		    NULL))
1052cca6fc52SDaniel Fojt 			goto err;
1053f5b1c8a1SJohn Marino 	}
1054530c17a6SJohn Marino 
1055530c17a6SJohn Marino 	/*
1056cca6fc52SDaniel Fojt 	 * Attempt to process session ticket.
1057f5b1c8a1SJohn Marino 	 */
1058530c17a6SJohn Marino 
1059cca6fc52SDaniel Fojt 	if ((hlen = HMAC_size(hctx)) < 0)
1060cca6fc52SDaniel Fojt 		goto err;
1061530c17a6SJohn Marino 
1062cca6fc52SDaniel Fojt 	if (hlen > CBS_len(ticket))
1063cca6fc52SDaniel Fojt 		goto derr;
1064cca6fc52SDaniel Fojt 	if (!CBS_get_bytes(ticket, &ticket_encdata, CBS_len(ticket) - hlen))
1065cca6fc52SDaniel Fojt 		goto derr;
1066cca6fc52SDaniel Fojt 	if (!CBS_get_bytes(ticket, &ticket_hmac, hlen))
1067cca6fc52SDaniel Fojt 		goto derr;
10688edacedfSDaniel Fojt 	if (CBS_len(ticket) != 0) {
10698edacedfSDaniel Fojt 		alert_desc = SSL_AD_DECODE_ERROR;
1070cca6fc52SDaniel Fojt 		goto err;
10718edacedfSDaniel Fojt 	}
1072530c17a6SJohn Marino 
1073cca6fc52SDaniel Fojt 	/* Check HMAC of encrypted ticket. */
1074cca6fc52SDaniel Fojt 	if (HMAC_Update(hctx, CBS_data(&ticket_name),
1075cca6fc52SDaniel Fojt 	    CBS_len(&ticket_name)) <= 0)
1076cca6fc52SDaniel Fojt 		goto err;
1077cca6fc52SDaniel Fojt 	if (HMAC_Update(hctx, CBS_data(&ticket_iv),
1078cca6fc52SDaniel Fojt 	    CBS_len(&ticket_iv)) <= 0)
1079cca6fc52SDaniel Fojt 		goto err;
1080cca6fc52SDaniel Fojt 	if (HMAC_Update(hctx, CBS_data(&ticket_encdata),
1081cca6fc52SDaniel Fojt 	    CBS_len(&ticket_encdata)) <= 0)
1082cca6fc52SDaniel Fojt 		goto err;
1083cca6fc52SDaniel Fojt 	if (HMAC_Final(hctx, hmac, &hlen) <= 0)
1084cca6fc52SDaniel Fojt 		goto err;
1085530c17a6SJohn Marino 
1086cca6fc52SDaniel Fojt 	if (!CBS_mem_equal(&ticket_hmac, hmac, hlen))
1087cca6fc52SDaniel Fojt 		goto derr;
1088cca6fc52SDaniel Fojt 
1089cca6fc52SDaniel Fojt 	/* Attempt to decrypt session data. */
1090cca6fc52SDaniel Fojt 	sdec_len = CBS_len(&ticket_encdata);
1091cca6fc52SDaniel Fojt 	if ((sdec = calloc(1, sdec_len)) == NULL)
1092cca6fc52SDaniel Fojt 		goto err;
1093cca6fc52SDaniel Fojt 	if (EVP_DecryptUpdate(cctx, sdec, &slen, CBS_data(&ticket_encdata),
1094cca6fc52SDaniel Fojt 	    CBS_len(&ticket_encdata)) <= 0)
1095cca6fc52SDaniel Fojt 		goto derr;
1096cca6fc52SDaniel Fojt 	if (EVP_DecryptFinal_ex(cctx, sdec + slen, &hlen) <= 0)
1097cca6fc52SDaniel Fojt 		goto derr;
1098cca6fc52SDaniel Fojt 
1099cca6fc52SDaniel Fojt 	slen += hlen;
1100cca6fc52SDaniel Fojt 
1101cca6fc52SDaniel Fojt 	/*
1102cca6fc52SDaniel Fojt 	 * For session parse failures, indicate that we need to send a new
1103cca6fc52SDaniel Fojt 	 * ticket.
1104cca6fc52SDaniel Fojt 	 */
1105f5b1c8a1SJohn Marino 	p = sdec;
1106cca6fc52SDaniel Fojt 	if ((sess = d2i_SSL_SESSION(NULL, &p, slen)) == NULL)
1107cca6fc52SDaniel Fojt 		goto derr;
1108f5b1c8a1SJohn Marino 	*psess = sess;
1109cca6fc52SDaniel Fojt 	sess = NULL;
1110cca6fc52SDaniel Fojt 
11118edacedfSDaniel Fojt 	ret = TLS1_TICKET_DECRYPTED;
1112cca6fc52SDaniel Fojt 	goto done;
1113cca6fc52SDaniel Fojt 
1114cca6fc52SDaniel Fojt  derr:
11158edacedfSDaniel Fojt 	ERR_clear_error();
11168edacedfSDaniel Fojt 	s->internal->tlsext_ticket_expected = 1;
11178edacedfSDaniel Fojt 	ret = TLS1_TICKET_NOT_DECRYPTED;
1118cca6fc52SDaniel Fojt 	goto done;
1119cca6fc52SDaniel Fojt 
1120cca6fc52SDaniel Fojt  err:
11218edacedfSDaniel Fojt 	*alert = alert_desc;
11228edacedfSDaniel Fojt 	ret = TLS1_TICKET_FATAL_ERROR;
1123cca6fc52SDaniel Fojt 	goto done;
1124cca6fc52SDaniel Fojt 
1125cca6fc52SDaniel Fojt  done:
1126cca6fc52SDaniel Fojt 	freezero(sdec, sdec_len);
1127cca6fc52SDaniel Fojt 	EVP_CIPHER_CTX_free(cctx);
1128cca6fc52SDaniel Fojt 	HMAC_CTX_free(hctx);
1129cca6fc52SDaniel Fojt 	SSL_SESSION_free(sess);
1130cca6fc52SDaniel Fojt 
1131cca6fc52SDaniel Fojt 	return ret;
1132f5b1c8a1SJohn Marino }
1133