*/
#include <stdio.h>
-#include "objects.h"
+#include <openssl/objects.h>
#include "ssl_locl.h"
-char *tls1_version_str="TLSv1 part of OpenSSL 0.9.1c 23-Dec-1998";
+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()
+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()
- {
- return(&TLSv1_data);
- }
-
-int tls1_new(s)
-SSL *s;
+int tls1_new(SSL *s)
{
if (!ssl3_new(s)) return(0);
s->method->ssl_clear(s);
return(1);
}
-void tls1_free(s)
-SSL *s;
+void tls1_free(SSL *s)
{
ssl3_free(s);
}
-void tls1_clear(s)
-SSL *s;
+void tls1_clear(SSL *s)
{
ssl3_clear(s);
s->version=TLS1_VERSION;
}
-#if 0
-long tls1_ctrl(s,cmd,larg,parg)
-SSL *s;
-int cmd;
-long larg;
-char *parg;
- {
- return(0);
+#ifndef OPENSSL_NO_TLSEXT
+unsigned char *ssl_add_ClientHello_TLS_extensions(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_TYPE_SERVER_host;
+ 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_TLS_extensions(SSL *s, unsigned char *p, unsigned char *limit) {
+ 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_TLS_extensions(SSL *s, unsigned char **p, unsigned char *d, int n) {
+ unsigned short type;
+ unsigned short size;
+ unsigned short len;
+ unsigned char * data = *p;
+
+ if (data >= (d+n-2))
+ return SSL_ERROR_NONE;
+ n2s(data,len);
+
+ if (data > (d+n-len))
+ return SSL_ERROR_NONE;
+
+ while(data <= (d+n-4)){
+ n2s(data,type);
+ n2s(data,size);
+
+ if (data+size > (d+n))
+ return SSL_ERROR_SSL;
+
+ 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)
+ return SSL_ERROR_SSL;
+
+ switch (servname_type) {
+ case TLSEXT_TYPE_SERVER_host:
+ if (s->session->tlsext_hostname == NULL) {
+ if (len > 255 ||
+ ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
+ return SSL_ERROR_SSL;
+ memcpy(s->session->tlsext_hostname, sdata, len);
+ s->session->tlsext_hostname[len]='\0';
+ }
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
+
+ data+=size;
+ }
+ *p = data;
+
+ return SSL_ERROR_NONE;
+}
+int ssl_parse_ServerHello_TLS_extensions(SSL *s, unsigned char **p, unsigned char *d, int n) {
+ unsigned short type;
+ unsigned short size;
+ unsigned short len;
+ unsigned char *data = *p;
+
+ int tlsext_servername = 0;
+
+ if (data >= (d+n-2))
+ return SSL_ERROR_NONE;
+
+
+ n2s(data,len);
+
+ while(data <= (d+n-4)){
+ n2s(data,type);
+ n2s(data,size);
+
+ if (data+size > (d+n))
+ return SSL_ERROR_SSL;
+
+ if (type == TLSEXT_TYPE_server_name) {
+ if ( s->tlsext_hostname == NULL || size > 0 ) {
+ return SSL_ERROR_SSL;
+ }
+ tlsext_servername = 1;
+ }
+
+ data+=size;
+ }
+
+
+
+ if (data != d+n)
+ return SSL_ERROR_SSL;
+
+ 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)
+ return SSL_ERROR_SSL;
+ }
+ } else
+ return SSL_ERROR_SSL;
+ }
+ *p = data;
+
+ return SSL_ERROR_NONE;
+}
+
+int ssl_check_Hello_TLS_extensions(SSL *s,int *ad)
+{
+ int ret = SSL_ERROR_NONE;
+
+ *ad = SSL_AD_UNRECOGNIZED_NAME;
+ if (s->servername_done == 0 && (s->ctx != NULL && s->ctx->tlsext_servername_callback != NULL)
+ && ((ret = s->ctx->tlsext_servername_callback(s, ad, s->ctx->tlsext_servername_arg))!= SSL_ERROR_NONE))
+ return ret;
+
+ else if (s->servername_done == 1)
+ s->servername_done = 2;
+
+ return ret;
+}
#endif
+