Various changes in the new TLS extension code, including the following:
[openssl.git] / ssl / t1_lib.c
1 /* ssl/t1_lib.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 /* ====================================================================
59  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60  *
61  * Redistribution and use in source and binary forms, with or without
62  * modification, are permitted provided that the following conditions
63  * are met:
64  *
65  * 1. Redistributions of source code must retain the above copyright
66  *    notice, this list of conditions and the following disclaimer. 
67  *
68  * 2. Redistributions in binary form must reproduce the above copyright
69  *    notice, this list of conditions and the following disclaimer in
70  *    the documentation and/or other materials provided with the
71  *    distribution.
72  *
73  * 3. All advertising materials mentioning features or use of this
74  *    software must display the following acknowledgment:
75  *    "This product includes software developed by the OpenSSL Project
76  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77  *
78  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79  *    endorse or promote products derived from this software without
80  *    prior written permission. For written permission, please contact
81  *    openssl-core@openssl.org.
82  *
83  * 5. Products derived from this software may not be called "OpenSSL"
84  *    nor may "OpenSSL" appear in their names without prior written
85  *    permission of the OpenSSL Project.
86  *
87  * 6. Redistributions of any form whatsoever must retain the following
88  *    acknowledgment:
89  *    "This product includes software developed by the OpenSSL Project
90  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91  *
92  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103  * OF THE POSSIBILITY OF SUCH DAMAGE.
104  * ====================================================================
105  *
106  * This product includes cryptographic software written by Eric Young
107  * (eay@cryptsoft.com).  This product includes software written by Tim
108  * Hudson (tjh@cryptsoft.com).
109  *
110  */
111
112 #include <stdio.h>
113 #include <openssl/objects.h>
114 #include "ssl_locl.h"
115
116 const char *tls1_version_str="TLSv1" OPENSSL_VERSION_PTEXT;
117
118 SSL3_ENC_METHOD TLSv1_enc_data={
119         tls1_enc,
120         tls1_mac,
121         tls1_setup_key_block,
122         tls1_generate_master_secret,
123         tls1_change_cipher_state,
124         tls1_final_finish_mac,
125         TLS1_FINISH_MAC_LENGTH,
126         tls1_cert_verify_mac,
127         TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
128         TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
129         tls1_alert_code,
130         };
131
132 long tls1_default_timeout(void)
133         {
134         /* 2 hours, the 24 hours mentioned in the TLSv1 spec
135          * is way too long for http, the cache would over fill */
136         return(60*60*2);
137         }
138
139 int tls1_new(SSL *s)
140         {
141         if (!ssl3_new(s)) return(0);
142         s->method->ssl_clear(s);
143         return(1);
144         }
145
146 void tls1_free(SSL *s)
147         {
148         ssl3_free(s);
149         }
150
151 void tls1_clear(SSL *s)
152         {
153         ssl3_clear(s);
154         s->version=TLS1_VERSION;
155         }
156
157
158 #ifndef OPENSSL_NO_TLSEXT
159 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
160         {
161         int extdatalen=0;
162         unsigned char *ret = p;
163
164         ret+=2;
165
166         if (ret>=limit) return NULL; /* this really never occurs, but ... */
167         if (s->servername_done == 0 && s->tlsext_hostname != NULL)
168                 { 
169                 /* Add TLS extension servername to the Client Hello message */
170                 unsigned long size_str;
171                 long lenmax; 
172
173                 if ((lenmax = limit - p - 7) < 0) return NULL; 
174                 if ((size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) return NULL;
175                 
176                 s2n(TLSEXT_TYPE_server_name,ret);
177                 s2n(size_str+3,ret);
178                 *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
179                 s2n(size_str,ret);
180         
181                 memcpy(ret, s->tlsext_hostname, size_str);
182                 ret+=size_str;
183                 }
184
185         if ((extdatalen = ret-p-2)== 0) 
186                 return p;
187
188         s2n(extdatalen,p);
189         return ret;
190 }
191
192 unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
193         {
194         int extdatalen=0;
195         unsigned char *ret = p;
196         if (s->hit || s->servername_done == 2)
197                 return p;
198         ret+=2;
199         if (s->servername_done == 1)  
200                 s->servername_done = 2;
201
202         if (ret>=limit) return NULL; /* this really never occurs, but ... */
203
204         if (s->session->tlsext_hostname != NULL)
205                 { 
206                 if (limit - p - 4 < 0) return NULL; 
207
208                 s2n(TLSEXT_TYPE_server_name,ret);
209                 s2n(0,ret);
210                 }
211         
212         if ((extdatalen = ret-p-2)== 0) 
213                 return p;
214
215         s2n(extdatalen,p);
216         return ret;
217 }
218
219 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
220         {
221         unsigned short type;
222         unsigned short size;
223         unsigned short len;
224         unsigned char *data = *p;
225
226         if (data >= (d+n-2))
227                 return 1;
228         n2s(data,len);
229
230         if (data > (d+n-len)) 
231                 return 1;
232
233         while (data <= (d+n-4))
234                 {
235                 n2s(data,type);
236                 n2s(data,size);
237
238                 if (data+size > (d+n))
239                         return 1;
240                 
241                 if (type == TLSEXT_TYPE_server_name)
242                         {
243                         unsigned char *sdata = data;
244                         int servname_type;
245                         int dsize = size-3 ;
246                         
247                         if (dsize > 0 )
248                                 {
249                                 servname_type = *(sdata++); 
250                                 n2s(sdata,len);
251                                 if (len != dsize) 
252                                         {
253                                         *al = SSL_AD_DECODE_ERROR;
254                                         return 0;
255                                         }
256
257                                 switch (servname_type)
258                                         {
259                                 case TLSEXT_NAMETYPE_host_name:
260                                         if (s->session->tlsext_hostname == NULL)
261                                                 {
262                                                 if (len > 255 || 
263                                                         ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
264                                                         {
265                                                         *al = TLS1_AD_UNRECOGNIZED_NAME;
266                                                         return 0;
267                                                         }
268                                                 
269                                                 memcpy(s->session->tlsext_hostname, sdata, len);
270                                                 s->session->tlsext_hostname[len]='\0'; 
271                                                 }
272                                         break;
273
274                                 default:
275                                         break;
276                                         }
277                                  
278                                 }
279                         }
280
281                 data+=size;             
282                 }
283
284         *p = data;
285         return 1;
286 }
287
288 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
289         {
290         unsigned short type;
291         unsigned short size;
292         unsigned short len;  
293         unsigned char *data = *p;
294
295         int tlsext_servername = 0;
296
297         if (data >= (d+n-2))
298                 return 1;
299
300         n2s(data,len);
301
302         while(data <= (d+n-4))
303                 {
304                 n2s(data,type);
305                 n2s(data,size);
306
307                 if (data+size > (d+n))
308                         return 1;
309
310                 if (type == TLSEXT_TYPE_server_name)
311                         {
312                         if (s->tlsext_hostname == NULL || size > 0)
313                                 {
314                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
315                                 return 0;
316                                 }
317                         tlsext_servername = 1;   
318                         }
319
320                 data+=size;             
321                 }
322
323         if (data != d+n)
324                 {
325                 *al = SSL_AD_DECODE_ERROR;
326                 return 0;
327                 }
328
329         if (!s->hit && tlsext_servername == 1)
330                 {
331                 if (s->tlsext_hostname)
332                         {
333                         if (s->session->tlsext_hostname == NULL)
334                                 {
335                                 s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);   
336                                 if (!s->session->tlsext_hostname)
337                                         {
338                                         *al = SSL_AD_UNRECOGNIZED_NAME;
339                                         return 0;
340                                         }
341                                 }
342                         else 
343                                 {
344                                 *al = SSL_AD_DECODE_ERROR;
345                                 return 0;
346                                 }
347                         }
348                 }
349
350         *p = data;
351         return 1;
352 }
353
354 int ssl_check_tlsext(SSL *s,int *al)
355         {
356         int ret;
357
358         *al = SSL_AD_UNRECOGNIZED_NAME;
359         if (s->servername_done == 0 && (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0))
360                 {
361                 ret = s->ctx->tlsext_servername_callback(s, al, s->ctx->tlsext_servername_arg);
362                 if (ret <= 0)
363                         return ret;
364                 }
365         if (s->servername_done == 1)    
366                 s->servername_done = 2;
367         
368         return 1;
369         }
370 #endif