Ignore zero length constructed segments.
[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
197         ret+=2;
198         if (ret>=limit) return NULL; /* this really never occurs, but ... */
199
200         if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
201                 { 
202                 if (limit - p - 4 < 0) return NULL; 
203
204                 s2n(TLSEXT_TYPE_server_name,ret);
205                 s2n(0,ret);
206                 }
207         
208         if ((extdatalen = ret-p-2)== 0) 
209                 return p;
210
211         s2n(extdatalen,p);
212         return ret;
213 }
214
215 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
216         {
217         unsigned short type;
218         unsigned short size;
219         unsigned short len;
220         unsigned char *data = *p;
221 #if 0
222         fprintf(stderr,"ssl_parse_clienthello_tlsext %s\n",s->session->tlsext_hostname?s->session->tlsext_hostname:"NULL");
223 #endif
224         s->servername_done = 0;
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 /* The servername extension is treated as follows:
242
243    - Only the hostname type is supported with a maximum length of 255.
244    - The servername is rejected if too long or if it contains zeros,
245      in which case an fatal alert is generated.
246    - The servername field is maintained together with the session cache.
247    - When a session is resumed, the servername call back invoked in order
248      to allow the application to position itself to the right context. 
249    - The servername is acknowledged if it is new for a session or when 
250      it is identical to a previously used for the same session. 
251      Applications can control the behaviour.  They can at any time
252      set a 'desirable' servername for a new SSL object. This can be the
253      case for example with HTTPS when a Host: header field is received and
254      a renegotiation is requested. In this case, a possible servername
255      presented in the new client hello is only acknowledged if it matches
256      the value of the Host: field. 
257    - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
258      if they provide for changing an explicit servername context for the session,
259      i.e. when the session has been established with a servername extension. 
260    - On session reconnect, the servername extension may be absent. 
261
262 */      
263
264                 if (type == TLSEXT_TYPE_server_name)
265                         {
266                         unsigned char *sdata = data;
267                         int servname_type;
268                         int dsize = size-3 ;
269                         
270                         if (dsize > 0 )
271                                 {
272                                 servname_type = *(sdata++); 
273                                 n2s(sdata,len);
274                                 if (len != dsize) 
275                                         {
276                                         *al = SSL_AD_DECODE_ERROR;
277                                         return 0;
278                                         }
279
280                                 switch (servname_type)
281                                         {
282                                 case TLSEXT_NAMETYPE_host_name:
283                                         if (s->session->tlsext_hostname == NULL)
284                                                 {
285                                                 if (len > TLSEXT_MAXLEN_host_name || 
286                                                         ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
287                                                         {
288                                                         *al = TLS1_AD_UNRECOGNIZED_NAME;
289                                                         return 0;
290                                                         }
291                                                 memcpy(s->session->tlsext_hostname, sdata, len);
292                                                 s->session->tlsext_hostname[len]='\0';
293                                                 if (strlen(s->session->tlsext_hostname) != len) {
294                                                         OPENSSL_free(s->session->tlsext_hostname);
295                                                         *al = TLS1_AD_UNRECOGNIZED_NAME;
296                                                         return 0;
297                                                 }
298                                                 s->servername_done = 1; 
299
300 #if 0
301                                                 fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_hostname %s\n",s->session->tlsext_hostname);
302 #endif
303                                                 }
304                                         else 
305                                                 s->servername_done = strlen(s->session->tlsext_hostname) == len 
306                                                         && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
307                                         
308                                         break;
309
310                                 default:
311                                         break;
312                                         }
313                                  
314                                 }
315                         }
316
317                 data+=size;             
318                 }
319
320         *p = data;
321         return 1;
322 }
323
324 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
325         {
326         unsigned short type;
327         unsigned short size;
328         unsigned short len;  
329         unsigned char *data = *p;
330
331         int tlsext_servername = 0;
332
333         if (data >= (d+n-2))
334                 return 1;
335
336         n2s(data,len);
337
338         while(data <= (d+n-4))
339                 {
340                 n2s(data,type);
341                 n2s(data,size);
342
343                 if (data+size > (d+n))
344                         return 1;
345
346                 if (type == TLSEXT_TYPE_server_name)
347                         {
348                         if (s->tlsext_hostname == NULL || size > 0)
349                                 {
350                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
351                                 return 0;
352                                 }
353                         tlsext_servername = 1;   
354                         }
355
356                 data+=size;             
357                 }
358
359         if (data != d+n)
360                 {
361                 *al = SSL_AD_DECODE_ERROR;
362                 return 0;
363                 }
364
365         if (!s->hit && tlsext_servername == 1)
366                 {
367                 if (s->tlsext_hostname)
368                         {
369                         if (s->session->tlsext_hostname == NULL)
370                                 {
371                                 s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);   
372                                 if (!s->session->tlsext_hostname)
373                                         {
374                                         *al = SSL_AD_UNRECOGNIZED_NAME;
375                                         return 0;
376                                         }
377                                 }
378                         else 
379                                 {
380                                 *al = SSL_AD_DECODE_ERROR;
381                                 return 0;
382                                 }
383                         }
384                 }
385
386         *p = data;
387         return 1;
388 }
389
390 int ssl_check_tlsext(SSL *s, int is_server)
391         {
392         int ret=SSL_TLSEXT_ERR_NOACK;
393
394         int al = SSL_AD_UNRECOGNIZED_NAME;
395
396         if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
397                 ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
398         else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)             
399                 ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
400
401         switch (ret) {
402                 case SSL_TLSEXT_ERR_ALERT_FATAL:
403                         ssl3_send_alert(s,SSL3_AL_FATAL,al); 
404                         return -1;
405
406                 case SSL_TLSEXT_ERR_ALERT_WARNING:
407                         ssl3_send_alert(s,SSL3_AL_WARNING,al);
408                         return 1; 
409                                         
410                 case SSL_TLSEXT_ERR_NOACK:
411                         s->servername_done=0;
412                         default:
413                 return 1;
414         }
415 }
416 #endif