* 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 <stdio.h>
#include <openssl/objects.h>
#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,
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);
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