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.
8280297Sjkim *
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).
15280297Sjkim *
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.
22280297Sjkim *
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 :-).
37280297Sjkim * 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)"
40280297Sjkim *
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.
52280297Sjkim *
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
66280297Sjkim *    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,
117280297Sjkim                                        int maxlen)
118280297Sjkim{
119280297Sjkim    if (p) {
120280297Sjkim        if ((s->s3->previous_client_finished_len + 1) > maxlen) {
121280297Sjkim            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,
122280297Sjkim                   SSL_R_RENEGOTIATE_EXT_TOO_LONG);
123204477Ssimon            return 0;
124280297Sjkim        }
125280297Sjkim
126204477Ssimon        /* Length byte */
127280297Sjkim        *p = s->s3->previous_client_finished_len;
128204477Ssimon        p++;
129204477Ssimon
130204477Ssimon        memcpy(p, s->s3->previous_client_finished,
131280297Sjkim               s->s3->previous_client_finished_len);
132204477Ssimon#ifdef OPENSSL_RI_DEBUG
133280297Sjkim        fprintf(stderr, "%s RI extension sent by client\n",
134280297Sjkim                s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
135204477Ssimon#endif
136280297Sjkim    }
137204477Ssimon
138280297Sjkim    *len = s->s3->previous_client_finished_len + 1;
139280297Sjkim
140204477Ssimon    return 1;
141280297Sjkim}
142204477Ssimon
143280297Sjkim/*
144280297Sjkim * Parse the client's renegotiation binding and abort if it's not right
145280297Sjkim */
146204477Ssimonint ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
147280297Sjkim                                          int *al)
148280297Sjkim{
149204477Ssimon    int ilen;
150204477Ssimon
151204477Ssimon    /* Parse the length byte */
152280297Sjkim    if (len < 1) {
153280297Sjkim        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
154280297Sjkim               SSL_R_RENEGOTIATION_ENCODING_ERR);
155280297Sjkim        *al = SSL_AD_ILLEGAL_PARAMETER;
156204477Ssimon        return 0;
157280297Sjkim    }
158204477Ssimon    ilen = *d;
159204477Ssimon    d++;
160204477Ssimon
161204477Ssimon    /* Consistency check */
162280297Sjkim    if ((ilen + 1) != len) {
163280297Sjkim        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
164280297Sjkim               SSL_R_RENEGOTIATION_ENCODING_ERR);
165280297Sjkim        *al = SSL_AD_ILLEGAL_PARAMETER;
166204477Ssimon        return 0;
167280297Sjkim    }
168204477Ssimon
169204477Ssimon    /* Check that the extension matches */
170280297Sjkim    if (ilen != s->s3->previous_client_finished_len) {
171280297Sjkim        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
172280297Sjkim               SSL_R_RENEGOTIATION_MISMATCH);
173280297Sjkim        *al = SSL_AD_HANDSHAKE_FAILURE;
174204477Ssimon        return 0;
175280297Sjkim    }
176280297Sjkim
177280297Sjkim    if (memcmp(d, s->s3->previous_client_finished,
178280297Sjkim               s->s3->previous_client_finished_len)) {
179280297Sjkim        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
180280297Sjkim               SSL_R_RENEGOTIATION_MISMATCH);
181280297Sjkim        *al = SSL_AD_HANDSHAKE_FAILURE;
182204477Ssimon        return 0;
183280297Sjkim    }
184204477Ssimon#ifdef OPENSSL_RI_DEBUG
185204477Ssimon    fprintf(stderr, "%s RI extension received by server\n",
186280297Sjkim            ilen ? "Non-empty" : "Empty");
187204477Ssimon#endif
188204477Ssimon
189280297Sjkim    s->s3->send_connection_binding = 1;
190204477Ssimon
191204477Ssimon    return 1;
192280297Sjkim}
193204477Ssimon
194204477Ssimon/* Add the server's renegotiation binding */
195204477Ssimonint ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
196280297Sjkim                                        int maxlen)
197280297Sjkim{
198280297Sjkim    if (p) {
199280297Sjkim        if ((s->s3->previous_client_finished_len +
200280297Sjkim             s->s3->previous_server_finished_len + 1) > maxlen) {
201280297Sjkim            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,
202280297Sjkim                   SSL_R_RENEGOTIATE_EXT_TOO_LONG);
203204477Ssimon            return 0;
204280297Sjkim        }
205280297Sjkim
206204477Ssimon        /* Length byte */
207280297Sjkim        *p = s->s3->previous_client_finished_len +
208280297Sjkim            s->s3->previous_server_finished_len;
209204477Ssimon        p++;
210204477Ssimon
211204477Ssimon        memcpy(p, s->s3->previous_client_finished,
212280297Sjkim               s->s3->previous_client_finished_len);
213204477Ssimon        p += s->s3->previous_client_finished_len;
214204477Ssimon
215204477Ssimon        memcpy(p, s->s3->previous_server_finished,
216280297Sjkim               s->s3->previous_server_finished_len);
217204477Ssimon#ifdef OPENSSL_RI_DEBUG
218280297Sjkim        fprintf(stderr, "%s RI extension sent by server\n",
219280297Sjkim                s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
220204477Ssimon#endif
221204477Ssimon    }
222204477Ssimon
223280297Sjkim    *len = s->s3->previous_client_finished_len
224280297Sjkim        + s->s3->previous_server_finished_len + 1;
225280297Sjkim
226280297Sjkim    return 1;
227280297Sjkim}
228280297Sjkim
229280297Sjkim/*
230280297Sjkim * Parse the server's renegotiation binding and abort if it's not right
231280297Sjkim */
232204477Ssimonint ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
233280297Sjkim                                          int *al)
234280297Sjkim{
235280297Sjkim    int expected_len = s->s3->previous_client_finished_len
236280297Sjkim        + 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);
242280297Sjkim
243204477Ssimon    /* Parse the length byte */
244280297Sjkim    if (len < 1) {
245280297Sjkim        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
246280297Sjkim               SSL_R_RENEGOTIATION_ENCODING_ERR);
247280297Sjkim        *al = SSL_AD_ILLEGAL_PARAMETER;
248204477Ssimon        return 0;
249280297Sjkim    }
250204477Ssimon    ilen = *d;
251204477Ssimon    d++;
252204477Ssimon
253204477Ssimon    /* Consistency check */
254280297Sjkim    if (ilen + 1 != len) {
255280297Sjkim        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
256280297Sjkim               SSL_R_RENEGOTIATION_ENCODING_ERR);
257280297Sjkim        *al = SSL_AD_ILLEGAL_PARAMETER;
258204477Ssimon        return 0;
259280297Sjkim    }
260280297Sjkim
261204477Ssimon    /* Check that the extension matches */
262280297Sjkim    if (ilen != expected_len) {
263280297Sjkim        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
264280297Sjkim               SSL_R_RENEGOTIATION_MISMATCH);
265280297Sjkim        *al = SSL_AD_HANDSHAKE_FAILURE;
266204477Ssimon        return 0;
267280297Sjkim    }
268204477Ssimon
269280297Sjkim    if (memcmp(d, s->s3->previous_client_finished,
270280297Sjkim               s->s3->previous_client_finished_len)) {
271280297Sjkim        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
272280297Sjkim               SSL_R_RENEGOTIATION_MISMATCH);
273280297Sjkim        *al = SSL_AD_HANDSHAKE_FAILURE;
274204477Ssimon        return 0;
275280297Sjkim    }
276204477Ssimon    d += s->s3->previous_client_finished_len;
277204477Ssimon
278280297Sjkim    if (memcmp(d, s->s3->previous_server_finished,
279280297Sjkim               s->s3->previous_server_finished_len)) {
280280297Sjkim        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
281280297Sjkim               SSL_R_RENEGOTIATION_MISMATCH);
282280297Sjkim        *al = SSL_AD_ILLEGAL_PARAMETER;
283204477Ssimon        return 0;
284280297Sjkim    }
285204477Ssimon#ifdef OPENSSL_RI_DEBUG
286204477Ssimon    fprintf(stderr, "%s RI extension received by client\n",
287280297Sjkim            ilen ? "Non-empty" : "Empty");
288204477Ssimon#endif
289280297Sjkim    s->s3->send_connection_binding = 1;
290204477Ssimon
291204477Ssimon    return 1;
292280297Sjkim}
293