prepare for additional RFC3546 alerts
[openssl.git] / ssl / t1_enc.c
index ecd2d6cbb557640bf8afb5c875e0d48e6314a809..fb1ea50153937f2492e87ba64812856c5d703f93 100644 (file)
  */
 
 #include <stdio.h>
+#include "ssl_locl.h"
 #include <openssl/comp.h>
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
-#include "ssl_locl.h"
 #include <openssl/md5.h>
 
 static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
@@ -124,7 +124,7 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
        unsigned int j;
        HMAC_CTX ctx;
        HMAC_CTX ctx_tmp;
-       unsigned char A1[HMAC_MAX_MD_CBLOCK];
+       unsigned char A1[EVP_MAX_MD_SIZE];
        unsigned int A1_len;
        
        chunk=EVP_MD_size(md);
@@ -161,7 +161,7 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
                }
        HMAC_CTX_cleanup(&ctx);
        HMAC_CTX_cleanup(&ctx_tmp);
-       memset(A1,0,sizeof(A1));
+       OPENSSL_cleanse(A1,sizeof(A1));
        }
 
 static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
@@ -231,7 +231,9 @@ int tls1_change_cipher_state(SSL *s, int which)
        int client_write;
        EVP_CIPHER_CTX *dd;
        const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
        const SSL_COMP *comp;
+#endif
        const EVP_MD *m;
        int is_export,n,i,j,k,exp_label_len,cl;
        int reuse_dd = 0;
@@ -239,7 +241,9 @@ int tls1_change_cipher_state(SSL *s, int which)
        is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
        c=s->s3->tmp.new_sym_enc;
        m=s->s3->tmp.new_hash;
+#ifndef OPENSSL_NO_COMP
        comp=s->s3->tmp.new_compression;
+#endif
        key_block=s->s3->tmp.key_block;
 
 #ifdef KSSL_DEBUG
@@ -265,6 +269,7 @@ int tls1_change_cipher_state(SSL *s, int which)
                        goto err;
                dd= s->enc_read_ctx;
                s->read_hash=m;
+#ifndef OPENSSL_NO_COMP
                if (s->expand != NULL)
                        {
                        COMP_CTX_free(s->expand);
@@ -284,7 +289,10 @@ int tls1_change_cipher_state(SSL *s, int which)
                        if (s->s3->rrec.comp == NULL)
                                goto err;
                        }
-               memset(&(s->s3->read_sequence[0]),0,8);
+#endif
+               /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
+               if (s->version != DTLS1_VERSION)
+                       memset(&(s->s3->read_sequence[0]),0,8);
                mac_secret= &(s->s3->read_mac_secret[0]);
                }
        else
@@ -299,6 +307,7 @@ int tls1_change_cipher_state(SSL *s, int which)
                        goto err;
                dd= s->enc_write_ctx;
                s->write_hash=m;
+#ifndef OPENSSL_NO_COMP
                if (s->compress != NULL)
                        {
                        COMP_CTX_free(s->compress);
@@ -313,7 +322,10 @@ int tls1_change_cipher_state(SSL *s, int which)
                                goto err2;
                                }
                        }
-               memset(&(s->s3->write_sequence[0]),0,8);
+#endif
+               /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
+               if (s->version != DTLS1_VERSION)
+                       memset(&(s->s3->write_sequence[0]),0,8);
                mac_secret= &(s->s3->write_mac_secret[0]);
                }
 
@@ -418,10 +430,10 @@ printf("\niv=");
 printf("\n");
 #endif
 
-       memset(tmp1,0,sizeof(tmp1));
-       memset(tmp2,0,sizeof(tmp1));
-       memset(iv1,0,sizeof(iv1));
-       memset(iv2,0,sizeof(iv2));
+       OPENSSL_cleanse(tmp1,sizeof(tmp1));
+       OPENSSL_cleanse(tmp2,sizeof(tmp1));
+       OPENSSL_cleanse(iv1,sizeof(iv1));
+       OPENSSL_cleanse(iv2,sizeof(iv2));
        return(1);
 err:
        SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
@@ -476,7 +488,7 @@ printf("pre-master\n");
 { int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
 #endif
        tls1_generate_key_block(s,p1,p2,num);
-       memset(p2,0,num);
+       OPENSSL_cleanse(p2,num);
        OPENSSL_free(p2);
 #ifdef TLS_DEBUG
 printf("\nkey block\n");
@@ -490,10 +502,16 @@ printf("\nkey block\n");
                 */
                s->s3->need_empty_fragments = 1;
 
-#ifndef NO_RC4
-               if ((s->session->cipher != NULL) && ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4))
-                       s->s3->need_empty_fragments = 0;
+               if (s->session->cipher != NULL)
+                       {
+                       if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL)
+                               s->s3->need_empty_fragments = 0;
+                       
+#ifndef OPENSSL_NO_RC4
+                       if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
+                               s->s3->need_empty_fragments = 0;
 #endif
+                       }
                }
                
        return(1);
@@ -677,10 +695,10 @@ int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
 
        tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf),
                s->session->master_key,s->session->master_key_length,
-               out,buf2,12);
+               out,buf2,sizeof buf2);
        EVP_MD_CTX_cleanup(&ctx);
 
-       return((int)12);
+       return sizeof buf2;
        }
 
 int tls1_mac(SSL *ssl, unsigned char *md, int send)
@@ -736,10 +754,13 @@ printf("rec=");
 {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
 #endif
 
-       for (i=7; i>=0; i--)
-               {
-               ++seq[i];
-               if (seq[i] != 0) break; 
+    if ( SSL_version(ssl) != DTLS1_VERSION)
+           {
+               for (i=7; i>=0; i--)
+                       {
+                       ++seq[i];
+                       if (seq[i] != 0) break; 
+                       }
                }
 
 #ifdef TLS_DEBUG
@@ -767,7 +788,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
                s->s3->server_random,SSL3_RANDOM_SIZE);
        tls1_PRF(s->ctx->md5,s->ctx->sha1,
                buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len,
-               s->session->master_key,buff,SSL3_MASTER_SECRET_SIZE);
+               s->session->master_key,buff,sizeof buff);
 #ifdef KSSL_DEBUG
        printf ("tls1_generate_master_secret() complete\n");
 #endif /* KSSL_DEBUG */
@@ -802,6 +823,13 @@ int tls1_alert_code(int code)
        case SSL_AD_INTERNAL_ERROR:     return(TLS1_AD_INTERNAL_ERROR);
        case SSL_AD_USER_CANCELLED:     return(TLS1_AD_USER_CANCELLED);
        case SSL_AD_NO_RENEGOTIATION:   return(TLS1_AD_NO_RENEGOTIATION);
+       case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
+       case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
+       case SSL_AD_UNRECOGNIZED_NAME:  return(TLS1_AD_UNRECOGNIZED_NAME);
+       case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
+       case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
+       case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
+                                         (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
        default:                        return(-1);
                }
        }