X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=b248dab36171d8e01303149d8dfe5541720fbf6b;hp=ddf5c15799efd1b6c15cf54d6db79dccc3003ed9;hb=f1fd4544a3747682010ed89ac908713fe90b8304;hpb=ec577822f95a8bca0023c5c77cef1a4916822d4a diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index ddf5c15799..b248dab361 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -55,20 +55,67 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #include #include #include "ssl_locl.h" -char *tls1_version_str="TLSv1" OPENSSL_VERSION_PTEXT; +const char *tls1_version_str="TLSv1" OPENSSL_VERSION_PTEXT; -#ifndef NO_PROTO -static long tls1_default_timeout(void); -#else -static long tls1_default_timeout(); -#endif - -static SSL3_ENC_METHOD TLSv1_enc_data={ +SSL3_ENC_METHOD TLSv1_enc_data={ tls1_enc, tls1_mac, tls1_setup_key_block, @@ -82,43 +129,13 @@ static SSL3_ENC_METHOD TLSv1_enc_data={ tls1_alert_code, }; -static SSL_METHOD TLSv1_data= { - TLS1_VERSION, - tls1_new, - tls1_clear, - tls1_free, - ssl_undefined_function, - ssl_undefined_function, - ssl3_read, - ssl3_peek, - ssl3_write, - ssl3_shutdown, - ssl3_renegotiate, - ssl3_renegotiate_check, - ssl3_ctrl, - ssl3_ctx_ctrl, - ssl3_get_cipher_by_char, - ssl3_put_cipher_by_char, - ssl3_pending, - ssl3_num_ciphers, - ssl3_get_cipher, - ssl_bad_method, - tls1_default_timeout, - &TLSv1_enc_data, - }; - -static long tls1_default_timeout(void) +long tls1_default_timeout(void) { /* 2 hours, the 24 hours mentioned in the TLSv1 spec * is way too long for http, the cache would over fill */ return(60*60*2); } -SSL_METHOD *tlsv1_base_method(void) - { - return(&TLSv1_data); - } - int tls1_new(SSL *s) { if (!ssl3_new(s)) return(0); @@ -137,9 +154,217 @@ void tls1_clear(SSL *s) s->version=TLS1_VERSION; } -#if 0 -long tls1_ctrl(SSL *s, int cmd, long larg, char *parg) + +#ifndef OPENSSL_NO_TLSEXT +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) + { + int extdatalen=0; + unsigned char *ret = p; + + ret+=2; + + if (ret>=limit) return NULL; /* this really never occurs, but ... */ + if (s->servername_done == 0 && s->tlsext_hostname != NULL) + { + /* Add TLS extension servername to the Client Hello message */ + unsigned long size_str; + long lenmax; + + if ((lenmax = limit - p - 7) < 0) return NULL; + if ((size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) return NULL; + + s2n(TLSEXT_TYPE_server_name,ret); + s2n(size_str+3,ret); + *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name; + s2n(size_str,ret); + + memcpy(ret, s->tlsext_hostname, size_str); + ret+=size_str; + } + + if ((extdatalen = ret-p-2)== 0) + return p; + + s2n(extdatalen,p); + return ret; +} + +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) { - return(0); + int extdatalen=0; + unsigned char *ret = p; + if (s->hit || s->servername_done == 2) + return p; + ret+=2; + if (s->servername_done == 1) + s->servername_done = 2; + + if (ret>=limit) return NULL; /* this really never occurs, but ... */ + + if (s->session->tlsext_hostname != NULL) + { + if (limit - p - 4 < 0) return NULL; + + s2n(TLSEXT_TYPE_server_name,ret); + s2n(0,ret); + } + + if ((extdatalen = ret-p-2)== 0) + return p; + + s2n(extdatalen,p); + return ret; +} + +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) + { + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + + if (data >= (d+n-2)) + return 1; + n2s(data,len); + + if (data > (d+n-len)) + return 1; + + while (data <= (d+n-4)) + { + n2s(data,type); + n2s(data,size); + + if (data+size > (d+n)) + return 1; + + if (type == TLSEXT_TYPE_server_name) + { + unsigned char *sdata = data; + int servname_type; + int dsize = size-3 ; + + if (dsize > 0 ) + { + servname_type = *(sdata++); + n2s(sdata,len); + if (len != dsize) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + switch (servname_type) + { + case TLSEXT_NAMETYPE_host_name: + if (s->session->tlsext_hostname == NULL) + { + if (len > 255 || + ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)) + { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + + memcpy(s->session->tlsext_hostname, sdata, len); + s->session->tlsext_hostname[len]='\0'; + } + break; + + default: + break; + } + + } + } + + data+=size; + } + + *p = data; + return 1; +} + +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) + { + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + + int tlsext_servername = 0; + + if (data >= (d+n-2)) + return 1; + + n2s(data,len); + + while(data <= (d+n-4)) + { + n2s(data,type); + n2s(data,size); + + if (data+size > (d+n)) + return 1; + + if (type == TLSEXT_TYPE_server_name) + { + if (s->tlsext_hostname == NULL || size > 0) + { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + tlsext_servername = 1; + } + + data+=size; + } + + if (data != d+n) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit && tlsext_servername == 1) + { + if (s->tlsext_hostname) + { + if (s->session->tlsext_hostname == NULL) + { + s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (!s->session->tlsext_hostname) + { + *al = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + } + else + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + } + + *p = data; + return 1; +} + +int ssl_check_tlsext(SSL *s,int *al) + { + int ret; + + *al = SSL_AD_UNRECOGNIZED_NAME; + if (s->servername_done == 0 && (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)) + { + ret = s->ctx->tlsext_servername_callback(s, al, s->ctx->tlsext_servername_arg); + if (ret <= 0) + return ret; + } + if (s->servername_done == 1) + s->servername_done = 2; + + return 1; } #endif