Avoid contradictive error code assignments.
[openssl.git] / ssl / t1_lib.c
index ff5bc58ce705b84dacf3125405e1e6c934a052f4..b248dab36171d8e01303149d8dfe5541720fbf6b 100644 (file)
  * 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>
@@ -101,41 +154,43 @@ void tls1_clear(SSL *s)
        s->version=TLS1_VERSION;
        }
 
+
 #ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_add_ClientHello_TLS_extensions(SSL *s, unsigned char *p, unsigned char *limit) {
+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) { 
+       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;
+               *(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_TLS_extensions(SSL *s, unsigned char *p, unsigned char *limit) {
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+       {
        int extdatalen=0;
        unsigned char *ret = p;
        if (s->hit || s->servername_done == 2)
@@ -146,78 +201,92 @@ unsigned char *ssl_add_ServerHello_TLS_extensions(SSL *s, unsigned char *p, unsi
 
        if (ret>=limit) return NULL; /* this really never occurs, but ... */
 
-       if (s->session->tlsext_hostname != NULL) { 
-
+       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) {
+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;
+       unsigned char *data = *p;
 
        if (data >= (d+n-2))
-          return SSL_ERROR_NONE;
+               return 1;
        n2s(data,len);
 
         if (data > (d+n-len)) 
-          return SSL_ERROR_NONE;
+               return 1;
 
-       while(data <= (d+n-4)){
+       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) {
+                       return 1;
+               
+               if (type == TLSEXT_TYPE_server_name)
+                       {
                        unsigned char *sdata = data;
                        int servname_type;
                        int dsize = size-3 ;
                         
-                       if (dsize > 0 ) {
+                       if (dsize > 0 )
+                               {
                                servname_type = *(sdata++); 
                                n2s(sdata,len);
                                if (len != dsize) 
-                                       return SSL_ERROR_SSL;
+                                       {
+                                       *al = SSL_AD_DECODE_ERROR;
+                                       return 0;
+                                       }
 
-                               switch (servname_type) {
-                               case TLSEXT_TYPE_SERVER_host:
-                                        if (s->session->tlsext_hostname == NULL) {
+                               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))
-                                                       return SSL_ERROR_SSL;
+                                                       {
+                                                       *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 SSL_ERROR_NONE;
+       *p = data;
+       return 1;
 }
-int ssl_parse_ServerHello_TLS_extensions(SSL *s, unsigned char **p, unsigned char *d, int n) {
+
+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;  
@@ -226,61 +295,76 @@ int ssl_parse_ServerHello_TLS_extensions(SSL *s, unsigned char **p, unsigned cha
        int tlsext_servername = 0;
 
        if (data >= (d+n-2))
-          return SSL_ERROR_NONE;
-
+               return 1;
 
        n2s(data,len);
 
-       while(data <= (d+n-4)){
+       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;
-                       }
+                       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)
-               return SSL_ERROR_SSL;
+               {
+               *al = SSL_AD_DECODE_ERROR;
+               return 0;
+               }
 
-       if (!s->hit && tlsext_servername == 1) {
-               if (s->tlsext_hostname) {
-                       if (s->session->tlsext_hostname == NULL) {
+       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;
+                                       {
+                                       *al = SSL_AD_UNRECOGNIZED_NAME;
+                                       return 0;
+                                       }
+                               }
+                       else 
+                               {
+                               *al = SSL_AD_DECODE_ERROR;
+                               return 0;
+                               }
                        }
-               } else 
-                       return SSL_ERROR_SSL;
-       }
-       *p = data;
+               }
 
-       return SSL_ERROR_NONE;
+       *p = data;
+       return 1;
 }
 
-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)       
+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 ret;
-}
+       
+       return 1;
+       }
 #endif
-