After objects have been freed, NULLify the pointers so there will be no double
[openssl.git] / ssl / t1_lib.c
index ec5f33235cd7b9799c8b22c9a633de655e5751ea..9742c3f968e504e9de84c8b7b53ec6668aebc7ed 100644 (file)
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-const char *tls1_version_str="TLSv1" OPENSSL_VERSION_PTEXT;
+const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
 
 SSL3_ENC_METHOD TLSv1_enc_data={
        tls1_enc,
@@ -164,22 +164,37 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
        ret+=2;
 
        if (ret>=limit) return NULL; /* this really never occurs, but ... */
-       if (s->servername_done == 0 && s->tlsext_hostname != NULL)
+       if (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;
+               /* check for enough space.
+                   4 for the servername type and entension length
+                   2 for servernamelist length
+                   1 for the hostname type
+                   2 for hostname length
+                   + hostname length 
+               */
+                   
+               if ((lenmax = limit - p - 9) < 0 
+               || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
+                       return NULL;
+                       
+               /* extension type and length */
+               s2n(TLSEXT_TYPE_server_name,ret); 
+               s2n(size_str+5,ret);
                
-               s2n(TLSEXT_TYPE_server_name,ret);
+               /* length of servername list */
                s2n(size_str+3,ret);
+       
+               /* hostname type, length and hostname */
                *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
                s2n(size_str,ret);
-       
                memcpy(ret, s->tlsext_hostname, size_str);
                ret+=size_str;
+
                }
 #ifndef OPENSSL_NO_EC
        if (s->tlsext_ecpointformatlist != NULL)
@@ -206,18 +221,23 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                /* Add TLS extension EllipticCurves to the ClientHello message */
                long lenmax; 
 
-               if ((lenmax = limit - p - 5) < 0) return NULL; 
+               if ((lenmax = limit - p - 6) < 0) return NULL; 
                if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
-               if (s->tlsext_ellipticcurvelist_length > 255)
+               if (s->tlsext_ellipticcurvelist_length > 65532)
                        {
                        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
                        return NULL;
                        }
                
                s2n(TLSEXT_TYPE_elliptic_curves,ret);
-               s2n(s->tlsext_ellipticcurvelist_length + 2,ret);
-               *(ret++) = (unsigned char) ((s->tlsext_ellipticcurvelist_length >> 8) & 0xFF);
-               *(ret++) = (unsigned char) (s->tlsext_ellipticcurvelist_length & 0xFF);
+               s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
+
+               /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
+                * elliptic_curve_list, but the examples use two bytes.
+                * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
+                * resolves this to two bytes.
+                */
+               s2n(s->tlsext_ellipticcurvelist_length, ret);
                memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
                ret+=s->tlsext_ellipticcurvelist_length;
                }
@@ -264,6 +284,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
                memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
                ret+=s->tlsext_ecpointformatlist_length;
+
                }
        /* Currently the server should not respond with a SupportedCurves extension */
 #endif /* OPENSSL_NO_EC */
@@ -281,9 +302,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
        unsigned short size;
        unsigned short len;
        unsigned char *data = *p;
-#if 0
-       fprintf(stderr,"ssl_parse_clienthello_tlsext %s\n",s->session->tlsext_hostname?s->session->tlsext_hostname:"NULL");
-#endif
        s->servername_done = 0;
 
        if (data >= (d+n-2))
@@ -326,20 +344,36 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 
                if (type == TLSEXT_TYPE_server_name)
                        {
-                       unsigned char *sdata = data;
+                       unsigned char *sdata;
                        int servname_type;
-                       int dsize = size-3 ;
-                        
-                       if (dsize > 0 )
+                       int dsize
+               
+                       if (size < 2) 
                                {
-                               servname_type = *(sdata++); 
+                               *al = SSL_AD_DECODE_ERROR;
+                               return 0;
+                               }
+                       n2s(data,dsize);  
+                       size -= 2;                    
+                       if (dsize > size  ) 
+                               {
+                               *al = SSL_AD_DECODE_ERROR;
+                               return 0;
+                               } 
+
+                       sdata = data;
+                       while (dsize > 3) 
+                               {
+                               servname_type = *(sdata++); 
                                n2s(sdata,len);
-                               if (len != dsize) 
+                               dsize -= 3;
+
+                               if (len > dsize) 
                                        {
                                        *al = SSL_AD_DECODE_ERROR;
                                        return 0;
                                        }
-
+                               if (s->servername_done == 0)
                                switch (servname_type)
                                        {
                                case TLSEXT_NAMETYPE_host_name:
@@ -360,9 +394,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                                }
                                                s->servername_done = 1; 
 
-#if 0
-                                               fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_hostname %s\n",s->session->tlsext_hostname);
-#endif
                                                }
                                        else 
                                                s->servername_done = strlen(s->session->tlsext_hostname) == len 
@@ -374,7 +405,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                        break;
                                        }
                                  
+                               dsize -= len;
+                               }
+                       if (dsize != 0) 
+                               {
+                               *al = SSL_AD_DECODE_ERROR;
+                               return 0;
                                }
+
                        }
 
 #ifndef OPENSSL_NO_EC
@@ -536,6 +574,104 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
        return 1;
 }
 
+#ifndef OPENSSL_NO_EC
+static int nid_list[] =
+       {
+               NID_sect163k1, /* sect163k1 (1) */
+               NID_sect163r1, /* sect163r1 (2) */
+               NID_sect163r2, /* sect163r2 (3) */
+               NID_sect193r1, /* sect193r1 (4) */ 
+               NID_sect193r2, /* sect193r2 (5) */ 
+               NID_sect233k1, /* sect233k1 (6) */
+               NID_sect233r1, /* sect233r1 (7) */ 
+               NID_sect239k1, /* sect239k1 (8) */ 
+               NID_sect283k1, /* sect283k1 (9) */
+               NID_sect283r1, /* sect283r1 (10) */ 
+               NID_sect409k1, /* sect409k1 (11) */ 
+               NID_sect409r1, /* sect409r1 (12) */
+               NID_sect571k1, /* sect571k1 (13) */ 
+               NID_sect571r1, /* sect571r1 (14) */ 
+               NID_secp160k1, /* secp160k1 (15) */
+               NID_secp160r1, /* secp160r1 (16) */ 
+               NID_secp160r2, /* secp160r2 (17) */ 
+               NID_secp192k1, /* secp192k1 (18) */
+               NID_X9_62_prime192v1, /* secp192r1 (19) */ 
+               NID_secp224k1, /* secp224k1 (20) */ 
+               NID_secp224r1, /* secp224r1 (21) */
+               NID_secp256k1, /* secp256k1 (22) */ 
+               NID_X9_62_prime256v1, /* secp256r1 (23) */ 
+               NID_secp384r1, /* secp384r1 (24) */
+               NID_secp521r1  /* secp521r1 (25) */     
+       };
+       
+int tls1_ec_curve_id2nid(int curve_id)
+       {
+       /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+       if ((curve_id < 1) || (curve_id > sizeof(nid_list)/sizeof(nid_list[0]))) return 0;
+       return nid_list[curve_id-1];
+       }
+
+int tls1_ec_nid2curve_id(int nid)
+       {
+       /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+       switch (nid)
+               {
+       case NID_sect163k1: /* sect163k1 (1) */
+               return 1;
+       case NID_sect163r1: /* sect163r1 (2) */
+               return 2;
+       case NID_sect163r2: /* sect163r2 (3) */
+               return 3;
+       case NID_sect193r1: /* sect193r1 (4) */ 
+               return 4;
+       case NID_sect193r2: /* sect193r2 (5) */ 
+               return 5;
+       case NID_sect233k1: /* sect233k1 (6) */
+               return 6;
+       case NID_sect233r1: /* sect233r1 (7) */ 
+               return 7;
+       case NID_sect239k1: /* sect239k1 (8) */ 
+               return 8;
+       case NID_sect283k1: /* sect283k1 (9) */
+               return 9;
+       case NID_sect283r1: /* sect283r1 (10) */ 
+               return 10;
+       case NID_sect409k1: /* sect409k1 (11) */ 
+               return 11;
+       case NID_sect409r1: /* sect409r1 (12) */
+               return 12;
+       case NID_sect571k1: /* sect571k1 (13) */ 
+               return 13;
+       case NID_sect571r1: /* sect571r1 (14) */ 
+               return 14;
+       case NID_secp160k1: /* secp160k1 (15) */
+               return 15;
+       case NID_secp160r1: /* secp160r1 (16) */ 
+               return 16;
+       case NID_secp160r2: /* secp160r2 (17) */ 
+               return 17;
+       case NID_secp192k1: /* secp192k1 (18) */
+               return 18;
+       case NID_X9_62_prime192v1: /* secp192r1 (19) */ 
+               return 19;
+       case NID_secp224k1: /* secp224k1 (20) */ 
+               return 20;
+       case NID_secp224r1: /* secp224r1 (21) */
+               return 21;
+       case NID_secp256k1: /* secp256k1 (22) */ 
+               return 22;
+       case NID_X9_62_prime256v1: /* secp256r1 (23) */ 
+               return 23;
+       case NID_secp384r1: /* secp384r1 (24) */
+               return 24;
+       case NID_secp521r1:  /* secp521r1 (25) */       
+               return 25;
+       default:
+               return 0;
+               }
+       }
+#endif /* OPENSSL_NO_EC */
+
 int ssl_prepare_clienthello_tlsext(SSL *s)
        {
 #ifndef OPENSSL_NO_EC
@@ -550,7 +686,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
        for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
                {
                algs = (sk_SSL_CIPHER_value(cipher_stack, i))->algorithms;
-               if ((algs & SSL_kECDH) || (algs & SSL_kECDHE) || (algs & SSL_aECDSA)) 
+               if ((algs & SSL_kECDH) || (algs & SSL_kEECDH) || (algs & SSL_aECDSA)) 
                        {
                        using_ecc = 1;
                        break;
@@ -570,19 +706,18 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
                s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
                s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
                s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+
                /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
                if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
-               if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(50)) == NULL)
+               s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2;
+               if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
                        {
+                       s->tlsext_ellipticcurvelist_length = 0;
                        SSLerr(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
                        return -1;
                        }
-               s->tlsext_ellipticcurvelist_length = 50;
-               for (i = 1, j = s->tlsext_ellipticcurvelist; i <= 25; i++)
-                       {
-                       *(j++) = 0x00;
-                       *(j++) = i;
-                       }
+               for (i = 1, j = s->tlsext_ellipticcurvelist; i <= sizeof(nid_list)/sizeof(nid_list[0]); i++)
+                       s2n(i,j);
                }
 #endif /* OPENSSL_NO_EC */
        return 1;
@@ -596,7 +731,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s)
         * supposed to send an EllipticCurves extension.
         */
        int algs = s->s3->tmp.new_cipher->algorithms;
-       int using_ecc = (algs & SSL_kECDH) || (algs & SSL_kECDHE) || (algs & SSL_aECDSA);
+       int using_ecc = (algs & SSL_kECDH) || (algs & SSL_kEECDH) || (algs & SSL_aECDSA);
        using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
 
        if (using_ecc)
@@ -662,7 +797,7 @@ int ssl_check_serverhello_tlsext(SSL *s)
         */
        int algs = s->s3->tmp.new_cipher->algorithms;
        if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) && 
-           ((algs & SSL_kECDH) || (algs & SSL_kECDHE) || (algs & SSL_aECDSA))) 
+           ((algs & SSL_kECDH) || (algs & SSL_kEECDH) || (algs & SSL_aECDSA))) 
                {
                /* we are using an ECC cipher */
                size_t i;
@@ -713,101 +848,3 @@ int ssl_check_serverhello_tlsext(SSL *s)
 }
 #endif
 
-#ifndef OPENSSL_NO_EC
-int tls1_ec_curve_id2nid(int curve_id)
-{
-       /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
-       static int nid_list[26] =
-       {
-               0,
-               NID_sect163k1, /* sect163k1 (1) */
-               NID_sect163r1, /* sect163r1 (2) */
-               NID_sect163r2, /* sect163r2 (3) */
-               NID_sect193r1, /* sect193r1 (4) */ 
-               NID_sect193r2, /* sect193r2 (5) */ 
-               NID_sect233k1, /* sect233k1 (6) */
-               NID_sect233r1, /* sect233r1 (7) */ 
-               NID_sect239k1, /* sect239k1 (8) */ 
-               NID_sect283k1, /* sect283k1 (9) */
-               NID_sect283r1, /* sect283r1 (10) */ 
-               NID_sect409k1, /* sect409k1 (11) */ 
-               NID_sect409r1, /* sect409r1 (12) */
-               NID_sect571k1, /* sect571k1 (13) */ 
-               NID_sect571r1, /* sect571r1 (14) */ 
-               NID_secp160k1, /* secp160k1 (15) */
-               NID_secp160r1, /* secp160r1 (16) */ 
-               NID_secp160r2, /* secp160r2 (17) */ 
-               NID_secp192k1, /* secp192k1 (18) */
-               NID_X9_62_prime192v1, /* secp192r1 (19) */ 
-               NID_secp224k1, /* secp224k1 (20) */ 
-               NID_secp224r1, /* secp224r1 (21) */
-               NID_secp256k1, /* secp256k1 (22) */ 
-               NID_X9_62_prime256v1, /* secp256r1 (23) */ 
-               NID_secp384r1, /* secp384r1 (24) */
-               NID_secp521r1  /* secp521r1 (25) */     
-       };
-       
-       if ((curve_id < 1) || (curve_id > 25)) return 0;
-
-       return nid_list[curve_id];
-}
-
-int tls1_ec_nid2curve_id(int nid)
-{
-       /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
-       switch (nid) {
-       case NID_sect163k1: /* sect163k1 (1) */
-               return 1;
-       case NID_sect163r1: /* sect163r1 (2) */
-               return 2;
-       case NID_sect163r2: /* sect163r2 (3) */
-               return 3;
-       case NID_sect193r1: /* sect193r1 (4) */ 
-               return 4;
-       case NID_sect193r2: /* sect193r2 (5) */ 
-               return 5;
-       case NID_sect233k1: /* sect233k1 (6) */
-               return 6;
-       case NID_sect233r1: /* sect233r1 (7) */ 
-               return 7;
-       case NID_sect239k1: /* sect239k1 (8) */ 
-               return 8;
-       case NID_sect283k1: /* sect283k1 (9) */
-               return 9;
-       case NID_sect283r1: /* sect283r1 (10) */ 
-               return 10;
-       case NID_sect409k1: /* sect409k1 (11) */ 
-               return 11;
-       case NID_sect409r1: /* sect409r1 (12) */
-               return 12;
-       case NID_sect571k1: /* sect571k1 (13) */ 
-               return 13;
-       case NID_sect571r1: /* sect571r1 (14) */ 
-               return 14;
-       case NID_secp160k1: /* secp160k1 (15) */
-               return 15;
-       case NID_secp160r1: /* secp160r1 (16) */ 
-               return 16;
-       case NID_secp160r2: /* secp160r2 (17) */ 
-               return 17;
-       case NID_secp192k1: /* secp192k1 (18) */
-               return 18;
-       case NID_X9_62_prime192v1: /* secp192r1 (19) */ 
-               return 19;
-       case NID_secp224k1: /* secp224k1 (20) */ 
-               return 20;
-       case NID_secp224r1: /* secp224r1 (21) */
-               return 21;
-       case NID_secp256k1: /* secp256k1 (22) */ 
-               return 22;
-       case NID_X9_62_prime256v1: /* secp256r1 (23) */ 
-               return 23;
-       case NID_secp384r1: /* secp384r1 (24) */
-               return 24;
-       case NID_secp521r1:  /* secp521r1 (25) */       
-               return 25;
-       default:
-               return 0;
-       }
-}
-#endif /* OPENSSL_NO_EC */