Add support for Camellia HMAC-Based cipher suites from RFC6367
[openssl.git] / ssl / t1_lib.c
index c4e27b972b26c673cb985989aee19dd96ea53f76..ac00a2ac4c85b457c26b73091f8d2e09a2999299 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,
@@ -1088,6 +1088,13 @@ void ssl_set_client_disabled(SSL *s)
                c->mask_k |= SSL_kPSK;
                }
 #endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+       if (!(s->srp_ctx.srp_Mask & SSL_kSRP))
+               {
+               c->mask_a |= SSL_aSRP;
+               c->mask_k |= SSL_kSRP;
+               }
+#endif
        c->valid = 1;
        }
 
@@ -1106,10 +1113,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 +1146,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 +1195,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 +1424,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 +1468,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);
@@ -1472,17 +1482,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                 }
 
        /* Add custom TLS Extensions to ClientHello */
-       if (s->ctx->custom_cli_ext_records_count)
+       if (s->cert->custom_cli_ext_records_count)
                {
                size_t i;
                custom_cli_ext_record* record;
 
-               for (i = 0; i < s->ctx->custom_cli_ext_records_count; i++)
+               for (i = 0; i < s->cert->custom_cli_ext_records_count; i++)
                        {
                        const unsigned char* out = NULL;
                        unsigned short outlen = 0;
 
-                       record = &s->ctx->custom_cli_ext_records[i];
+                       record = &s->cert->custom_cli_ext_records[i];
                        /* NULL callback sends empty extension */ 
                        /* -1 from callback omits extension */
                        if (record->fn1)
@@ -1539,17 +1549,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 +1574,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 +1597,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 +1677,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 +1709,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:
@@ -1734,13 +1747,13 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                }
 #endif
 
-       for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++)
+       for (i = 0; i < s->cert->custom_srv_ext_records_count; i++)
                {
                const unsigned char *out = NULL;
                unsigned short outlen = 0;
                int cb_retval = 0;
 
-               record = &s->ctx->custom_srv_ext_records[i];
+               record = &s->cert->custom_srv_ext_records[i];
 
                /* NULL callback or -1 omits extension */
                if (!record->fn2)
@@ -1790,10 +1803,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;
        }
 
@@ -2490,13 +2503,13 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                 * so call the callback and record the extension number so that
                 * an appropriate ServerHello may be later returned.
                 */
-               else if (!s->hit && s->ctx->custom_srv_ext_records_count)
+               else if (!s->hit && s->cert->custom_srv_ext_records_count)
                        {
                        custom_srv_ext_record *record;
 
-                       for (i=0; i < s->ctx->custom_srv_ext_records_count; i++)
+                       for (i=0; i < s->cert->custom_srv_ext_records_count; i++)
                                {
-                               record = &s->ctx->custom_srv_ext_records[i];
+                               record = &s->cert->custom_srv_ext_records[i];
                                if (type == record->ext_type)
                                        {
                                        if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
@@ -2641,15 +2654,18 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                                *al = TLS1_AD_DECODE_ERROR;
                                return 0;
                                }
-                       s->session->tlsext_ecpointformatlist_length = 0;
-                       if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
-                       if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+                       if (!s->hit)
                                {
-                               *al = TLS1_AD_INTERNAL_ERROR;
-                               return 0;
+                               s->session->tlsext_ecpointformatlist_length = 0;
+                               if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+                               if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+                                       {
+                                       *al = TLS1_AD_INTERNAL_ERROR;
+                                       return 0;
+                                       }
+                               s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+                               memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
                                }
-                       s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
-                       memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
 #if 0
                        fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
                        sdata = s->session->tlsext_ecpointformatlist;
@@ -2832,14 +2848,14 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                /* If this extension type was not otherwise handled, but 
                 * matches a custom_cli_ext_record, then send it to the c
                 * callback */
-               else if (s->ctx->custom_cli_ext_records_count)
+               else if (s->cert->custom_cli_ext_records_count)
                        {
                        size_t i;
                        custom_cli_ext_record* record;
 
-                       for (i = 0; i < s->ctx->custom_cli_ext_records_count; i++)
+                       for (i = 0; i < s->cert->custom_cli_ext_records_count; i++)
                                {
-                               record = &s->ctx->custom_cli_ext_records[i];
+                               record = &s->cert->custom_cli_ext_records[i];
                                if (record->ext_type == type)
                                        {
                                        if (record->fn2 && !record->fn2(s, type, data, size, al, record->arg))
@@ -3451,7 +3467,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;