Fix possible buffer overrun.
[openssl.git] / ssl / t1_lib.c
index c4e27b972b26c673cb985989aee19dd96ea53f76..4374d6aadd3d5b0804d13d338b27408d8102e8b5 100644 (file)
@@ -131,7 +131,7 @@ static int ssl_check_clienthello_tlsext_early(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 #endif
 
-SSL3_ENC_METHOD TLSv1_enc_data={
+SSL3_ENC_METHOD const TLSv1_enc_data={
        tls1_enc,
        tls1_mac,
        tls1_setup_key_block,
@@ -150,7 +150,7 @@ SSL3_ENC_METHOD TLSv1_enc_data={
        ssl3_handshake_write
        };
 
-SSL3_ENC_METHOD TLSv1_1_enc_data={
+SSL3_ENC_METHOD const TLSv1_1_enc_data={
        tls1_enc,
        tls1_mac,
        tls1_setup_key_block,
@@ -169,7 +169,7 @@ SSL3_ENC_METHOD TLSv1_1_enc_data={
        ssl3_handshake_write
        };
 
-SSL3_ENC_METHOD TLSv1_2_enc_data={
+SSL3_ENC_METHOD const TLSv1_2_enc_data={
        tls1_enc,
        tls1_mac,
        tls1_setup_key_block,
@@ -1106,10 +1106,11 @@ static int tls_use_ticket(SSL *s)
        return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
        }
 
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al)
        {
        int extdatalen=0;
-       unsigned char *ret = p;
+       unsigned char *orig = buf;
+       unsigned char *ret = buf;
 #ifndef OPENSSL_NO_EC
        /* See if we support any ECC ciphersuites */
        int using_ecc = 0;
@@ -1138,7 +1139,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
        /* don't add extensions for SSLv3 unless doing secure renegotiation */
        if (s->client_version == SSL3_VERSION
                                        && !s->s3->send_connection_binding)
-               return p;
+               return orig;
 
        ret+=2;
 
@@ -1187,7 +1188,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
               return NULL;
               }
 
-          if((limit - p - 4 - el) < 0) return NULL;
+          if((limit - ret - 4 - el) < 0) return NULL;
           
           s2n(TLSEXT_TYPE_renegotiate,ret);
           s2n(el,ret);
@@ -1416,6 +1417,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
 
 #ifndef OPENSSL_NO_HEARTBEATS
        /* Add Heartbeat extension */
+       if ((limit - ret - 4 - 1) < 0)
+               return NULL;
        s2n(TLSEXT_TYPE_heartbeat,ret);
        s2n(1,ret);
        /* Set mode:
@@ -1458,7 +1461,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
 
                 ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
                 
-                if((limit - p - 4 - el) < 0) return NULL;
+                if((limit - ret - 4 - el) < 0) return NULL;
 
                 s2n(TLSEXT_TYPE_use_srtp,ret);
                 s2n(el,ret);
@@ -1539,17 +1542,18 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                        }
                }
 
-       if ((extdatalen = ret-p-2) == 0)
-               return p;
+       if ((extdatalen = ret-orig-2)== 0) 
+               return orig;
 
-       s2n(extdatalen,p);
+       s2n(extdatalen, orig);
        return ret;
        }
 
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al)
        {
        int extdatalen=0;
-       unsigned char *ret = p;
+       unsigned char *orig = buf;
+       unsigned char *ret = buf;
        size_t i;
        custom_srv_ext_record *record;
 #ifndef OPENSSL_NO_NEXTPROTONEG
@@ -1563,7 +1567,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 #endif
        /* don't add extensions for SSLv3, unless doing secure renegotiation */
        if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
-               return p;
+               return orig;
        
        ret+=2;
        if (ret>=limit) return NULL; /* this really never occurs, but ... */
@@ -1586,7 +1590,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
               return NULL;
               }
 
-          if((limit - p - 4 - el) < 0) return NULL;
+          if((limit - ret - 4 - el) < 0) return NULL;
           
           s2n(TLSEXT_TYPE_renegotiate,ret);
           s2n(el,ret);
@@ -1666,7 +1670,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 
                 ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
                 
-                if((limit - p - 4 - el) < 0) return NULL;
+                if((limit - ret - 4 - el) < 0) return NULL;
 
                 s2n(TLSEXT_TYPE_use_srtp,ret);
                 s2n(el,ret);
@@ -1698,6 +1702,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
        /* Add Heartbeat extension if we've received one */
        if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
                {
+               if ((limit - ret - 4 - 1) < 0)
+                       return NULL;
                s2n(TLSEXT_TYPE_heartbeat,ret);
                s2n(1,ret);
                /* Set mode:
@@ -1790,10 +1796,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                ret += len;
                }
 
-       if ((extdatalen = ret-p-2)== 0) 
-               return p;
+       if ((extdatalen = ret-orig-2)== 0) 
+               return orig;
 
-       s2n(extdatalen,p);
+       s2n(extdatalen, orig);
        return ret;
        }
 
@@ -3451,7 +3457,11 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
                }
        EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
        if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
+               {
+               EVP_CIPHER_CTX_cleanup(&ctx);
+               OPENSSL_free(sdec);
                return 2;
+               }
        slen += mlen;
        EVP_CIPHER_CTX_cleanup(&ctx);
        p = sdec;