1204477Ssimon/* ssl/t1_reneg.c */
2204477Ssimon/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3204477Ssimon * All rights reserved.
4204477Ssimon *
5204477Ssimon * This package is an SSL implementation written
6204477Ssimon * by Eric Young (eay@cryptsoft.com).
7204477Ssimon * The implementation was written so as to conform with Netscapes SSL.
8204477Ssimon *
9204477Ssimon * This library is free for commercial and non-commercial use as long as
10204477Ssimon * the following conditions are aheared to.  The following conditions
11204477Ssimon * apply to all code found in this distribution, be it the RC4, RSA,
12204477Ssimon * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13204477Ssimon * included with this distribution is covered by the same copyright terms
14204477Ssimon * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15204477Ssimon *
16204477Ssimon * Copyright remains Eric Young's, and as such any Copyright notices in
17204477Ssimon * the code are not to be removed.
18204477Ssimon * If this package is used in a product, Eric Young should be given attribution
19204477Ssimon * as the author of the parts of the library used.
20204477Ssimon * This can be in the form of a textual message at program startup or
21204477Ssimon * in documentation (online or textual) provided with the package.
22204477Ssimon *
23204477Ssimon * Redistribution and use in source and binary forms, with or without
24204477Ssimon * modification, are permitted provided that the following conditions
25204477Ssimon * are met:
26204477Ssimon * 1. Redistributions of source code must retain the copyright
27204477Ssimon *    notice, this list of conditions and the following disclaimer.
28204477Ssimon * 2. Redistributions in binary form must reproduce the above copyright
29204477Ssimon *    notice, this list of conditions and the following disclaimer in the
30204477Ssimon *    documentation and/or other materials provided with the distribution.
31204477Ssimon * 3. All advertising materials mentioning features or use of this software
32204477Ssimon *    must display the following acknowledgement:
33204477Ssimon *    "This product includes cryptographic software written by
34204477Ssimon *     Eric Young (eay@cryptsoft.com)"
35204477Ssimon *    The word 'cryptographic' can be left out if the rouines from the library
36204477Ssimon *    being used are not cryptographic related :-).
37204477Ssimon * 4. If you include any Windows specific code (or a derivative thereof) from
38204477Ssimon *    the apps directory (application code) you must include an acknowledgement:
39204477Ssimon *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40204477Ssimon *
41204477Ssimon * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42204477Ssimon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43204477Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44204477Ssimon * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45204477Ssimon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46204477Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47204477Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48204477Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49204477Ssimon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50204477Ssimon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51204477Ssimon * SUCH DAMAGE.
52204477Ssimon *
53204477Ssimon * The licence and distribution terms for any publically available version or
54204477Ssimon * derivative of this code cannot be changed.  i.e. this code cannot simply be
55204477Ssimon * copied and put under another distribution licence
56204477Ssimon * [including the GNU Public Licence.]
57204477Ssimon */
58204477Ssimon/* ====================================================================
59204477Ssimon * Copyright (c) 1998-2009 The OpenSSL Project.  All rights reserved.
60204477Ssimon *
61204477Ssimon * Redistribution and use in source and binary forms, with or without
62204477Ssimon * modification, are permitted provided that the following conditions
63204477Ssimon * are met:
64204477Ssimon *
65204477Ssimon * 1. Redistributions of source code must retain the above copyright
66204477Ssimon *    notice, this list of conditions and the following disclaimer.
67204477Ssimon *
68204477Ssimon * 2. Redistributions in binary form must reproduce the above copyright
69204477Ssimon *    notice, this list of conditions and the following disclaimer in
70204477Ssimon *    the documentation and/or other materials provided with the
71204477Ssimon *    distribution.
72204477Ssimon *
73204477Ssimon * 3. All advertising materials mentioning features or use of this
74204477Ssimon *    software must display the following acknowledgment:
75204477Ssimon *    "This product includes software developed by the OpenSSL Project
76204477Ssimon *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77204477Ssimon *
78204477Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79204477Ssimon *    endorse or promote products derived from this software without
80204477Ssimon *    prior written permission. For written permission, please contact
81204477Ssimon *    openssl-core@openssl.org.
82204477Ssimon *
83204477Ssimon * 5. Products derived from this software may not be called "OpenSSL"
84204477Ssimon *    nor may "OpenSSL" appear in their names without prior written
85204477Ssimon *    permission of the OpenSSL Project.
86204477Ssimon *
87204477Ssimon * 6. Redistributions of any form whatsoever must retain the following
88204477Ssimon *    acknowledgment:
89204477Ssimon *    "This product includes software developed by the OpenSSL Project
90204477Ssimon *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91204477Ssimon *
92204477Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93204477Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94204477Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95204477Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96204477Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97204477Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98204477Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99204477Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100204477Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101204477Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102204477Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103204477Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
104204477Ssimon * ====================================================================
105204477Ssimon *
106204477Ssimon * This product includes cryptographic software written by Eric Young
107204477Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
108204477Ssimon * Hudson (tjh@cryptsoft.com).
109204477Ssimon *
110204477Ssimon */
111204477Ssimon#include <stdio.h>
112204477Ssimon#include <openssl/objects.h>
113204477Ssimon#include "ssl_locl.h"
114204477Ssimon
115204477Ssimon/* Add the client's renegotiation binding */
116204477Ssimonint ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
117204477Ssimon					int maxlen)
118204477Ssimon    {
119204477Ssimon    if(p)
120204477Ssimon        {
121204477Ssimon	if((s->s3->previous_client_finished_len+1) > maxlen)
122204477Ssimon            {
123204477Ssimon            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
124204477Ssimon            return 0;
125204477Ssimon            }
126204477Ssimon
127204477Ssimon        /* Length byte */
128204477Ssimon	*p = s->s3->previous_client_finished_len;
129204477Ssimon        p++;
130204477Ssimon
131204477Ssimon        memcpy(p, s->s3->previous_client_finished,
132204477Ssimon	       s->s3->previous_client_finished_len);
133204477Ssimon#ifdef OPENSSL_RI_DEBUG
134204477Ssimon    fprintf(stderr, "%s RI extension sent by client\n",
135204477Ssimon		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
136204477Ssimon#endif
137204477Ssimon        }
138204477Ssimon
139204477Ssimon    *len=s->s3->previous_client_finished_len + 1;
140204477Ssimon
141204477Ssimon
142204477Ssimon    return 1;
143204477Ssimon    }
144204477Ssimon
145204477Ssimon/* Parse the client's renegotiation binding and abort if it's not
146204477Ssimon   right */
147204477Ssimonint ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
148204477Ssimon					  int *al)
149204477Ssimon    {
150204477Ssimon    int ilen;
151204477Ssimon
152204477Ssimon    /* Parse the length byte */
153204477Ssimon    if(len < 1)
154204477Ssimon        {
155204477Ssimon        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
156204477Ssimon        *al=SSL_AD_ILLEGAL_PARAMETER;
157204477Ssimon        return 0;
158204477Ssimon        }
159204477Ssimon    ilen = *d;
160204477Ssimon    d++;
161204477Ssimon
162204477Ssimon    /* Consistency check */
163204477Ssimon    if((ilen+1) != len)
164204477Ssimon        {
165204477Ssimon        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
166204477Ssimon        *al=SSL_AD_ILLEGAL_PARAMETER;
167204477Ssimon        return 0;
168204477Ssimon        }
169204477Ssimon
170204477Ssimon    /* Check that the extension matches */
171204477Ssimon    if(ilen != s->s3->previous_client_finished_len)
172204477Ssimon        {
173204477Ssimon        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
174204477Ssimon        *al=SSL_AD_HANDSHAKE_FAILURE;
175204477Ssimon        return 0;
176204477Ssimon        }
177204477Ssimon
178204477Ssimon    if(memcmp(d, s->s3->previous_client_finished,
179204477Ssimon	      s->s3->previous_client_finished_len))
180204477Ssimon        {
181204477Ssimon        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
182204477Ssimon        *al=SSL_AD_HANDSHAKE_FAILURE;
183204477Ssimon        return 0;
184204477Ssimon        }
185204477Ssimon#ifdef OPENSSL_RI_DEBUG
186204477Ssimon    fprintf(stderr, "%s RI extension received by server\n",
187204477Ssimon				ilen ? "Non-empty" : "Empty");
188204477Ssimon#endif
189204477Ssimon
190204477Ssimon    s->s3->send_connection_binding=1;
191204477Ssimon
192204477Ssimon    return 1;
193204477Ssimon    }
194204477Ssimon
195204477Ssimon/* Add the server's renegotiation binding */
196204477Ssimonint ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
197204477Ssimon					int maxlen)
198204477Ssimon    {
199204477Ssimon    if(p)
200204477Ssimon        {
201204477Ssimon        if((s->s3->previous_client_finished_len +
202204477Ssimon            s->s3->previous_server_finished_len + 1) > maxlen)
203204477Ssimon            {
204204477Ssimon            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
205204477Ssimon            return 0;
206204477Ssimon            }
207204477Ssimon
208204477Ssimon        /* Length byte */
209204477Ssimon        *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
210204477Ssimon        p++;
211204477Ssimon
212204477Ssimon        memcpy(p, s->s3->previous_client_finished,
213204477Ssimon	       s->s3->previous_client_finished_len);
214204477Ssimon        p += s->s3->previous_client_finished_len;
215204477Ssimon
216204477Ssimon        memcpy(p, s->s3->previous_server_finished,
217204477Ssimon	       s->s3->previous_server_finished_len);
218204477Ssimon#ifdef OPENSSL_RI_DEBUG
219204477Ssimon    fprintf(stderr, "%s RI extension sent by server\n",
220204477Ssimon    		s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
221204477Ssimon#endif
222204477Ssimon        }
223204477Ssimon
224204477Ssimon    *len=s->s3->previous_client_finished_len
225204477Ssimon	+ s->s3->previous_server_finished_len + 1;
226204477Ssimon
227204477Ssimon    return 1;
228204477Ssimon    }
229204477Ssimon
230204477Ssimon/* Parse the server's renegotiation binding and abort if it's not
231204477Ssimon   right */
232204477Ssimonint ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
233204477Ssimon					  int *al)
234204477Ssimon    {
235204477Ssimon    int expected_len=s->s3->previous_client_finished_len
236204477Ssimon	+ s->s3->previous_server_finished_len;
237204477Ssimon    int ilen;
238204477Ssimon
239204477Ssimon    /* Check for logic errors */
240204477Ssimon    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
241204477Ssimon    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
242204477Ssimon
243204477Ssimon    /* Parse the length byte */
244204477Ssimon    if(len < 1)
245204477Ssimon        {
246204477Ssimon        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
247204477Ssimon        *al=SSL_AD_ILLEGAL_PARAMETER;
248204477Ssimon        return 0;
249204477Ssimon        }
250204477Ssimon    ilen = *d;
251204477Ssimon    d++;
252204477Ssimon
253204477Ssimon    /* Consistency check */
254204477Ssimon    if(ilen+1 != len)
255204477Ssimon        {
256204477Ssimon        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
257204477Ssimon        *al=SSL_AD_ILLEGAL_PARAMETER;
258204477Ssimon        return 0;
259204477Ssimon        }
260204477Ssimon
261204477Ssimon    /* Check that the extension matches */
262204477Ssimon    if(ilen != expected_len)
263204477Ssimon        {
264204477Ssimon        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
265204477Ssimon        *al=SSL_AD_HANDSHAKE_FAILURE;
266204477Ssimon        return 0;
267204477Ssimon        }
268204477Ssimon
269204477Ssimon    if(memcmp(d, s->s3->previous_client_finished,
270204477Ssimon	      s->s3->previous_client_finished_len))
271204477Ssimon        {
272204477Ssimon        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
273204477Ssimon        *al=SSL_AD_HANDSHAKE_FAILURE;
274204477Ssimon        return 0;
275204477Ssimon        }
276204477Ssimon    d += s->s3->previous_client_finished_len;
277204477Ssimon
278204477Ssimon    if(memcmp(d, s->s3->previous_server_finished,
279204477Ssimon	      s->s3->previous_server_finished_len))
280204477Ssimon        {
281204477Ssimon        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
282204477Ssimon        *al=SSL_AD_ILLEGAL_PARAMETER;
283204477Ssimon        return 0;
284204477Ssimon        }
285204477Ssimon#ifdef OPENSSL_RI_DEBUG
286204477Ssimon    fprintf(stderr, "%s RI extension received by client\n",
287204477Ssimon				ilen ? "Non-empty" : "Empty");
288204477Ssimon#endif
289204477Ssimon    s->s3->send_connection_binding=1;
290204477Ssimon
291204477Ssimon    return 1;
292204477Ssimon    }
293