New compile time option OPENSSL_SSL_TRACE_CRYPTO, when set this passes
[openssl.git] / ssl / s3_enc.c
index 00faadf8984ef0151b915f38e13fbf811f7d294c..d54babc96d2b4a730638c0260b20c9319f578e16 100644 (file)
@@ -170,6 +170,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
 #endif
        k=0;
        EVP_MD_CTX_init(&m5);
+       EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        EVP_MD_CTX_init(&s1);
        for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
                {
@@ -214,7 +215,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
 
 int ssl3_change_cipher_state(SSL *s, int which)
        {
-       unsigned char *p,*key_block,*mac_secret;
+       unsigned char *p,*mac_secret;
        unsigned char exp_key[EVP_MAX_KEY_LENGTH];
        unsigned char exp_iv[EVP_MAX_IV_LENGTH];
        unsigned char *ms,*key,*iv,*er1,*er2;
@@ -239,7 +240,6 @@ int ssl3_change_cipher_state(SSL *s, int which)
        else
                comp=s->s3->tmp.new_compression->method;
 #endif
-       key_block=s->s3->tmp.key_block;
 
        if (which & SSL3_CC_READ)
                {
@@ -375,6 +375,27 @@ int ssl3_change_cipher_state(SSL *s, int which)
 
        EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
 
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+       if (s->msg_callback)
+               {
+               int wh = which & SSL3_CC_WRITE ?
+                               TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ;
+               s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
+                                               mac_secret, EVP_MD_size(m),
+                                               s, s->msg_callback_arg);
+               if (c->key_len)
+                       s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
+                                               key, c->key_len,
+                                               s, s->msg_callback_arg);
+               if (k)
+                       {
+                       s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV,
+                                               iv, k, s, s->msg_callback_arg);
+                       }
+               }
+#endif
+
        OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
        OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
        EVP_MD_CTX_cleanup(&md);
@@ -512,6 +533,9 @@ int ssl3_enc(SSL *s, int send)
 
                        /* we need to add 'i-1' padding bytes */
                        l+=i;
+                       /* the last of these zero bytes will be overwritten
+                        * with the padding length. */
+                       memset(&rec->input[rec->length], 0, i);
                        rec->length+=i;
                        rec->input[l-1]=(i-1);
                        }
@@ -569,12 +593,12 @@ void ssl3_free_digest_list(SSL *s)
        OPENSSL_free(s->s3->handshake_dgst);
        s->s3->handshake_dgst=NULL;
        }       
-               
+
 
 
 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
        {
-       if (s->s3->handshake_buffer) 
+       if (s->s3->handshake_buffer && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)
                {
                BIO_write (s->s3->handshake_buffer,(void *)buf,len);
                } 
@@ -611,9 +635,16 @@ int ssl3_digest_cached_records(SSL *s)
        /* Loop through bitso of algorithm2 field and create MD_CTX-es */
        for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++) 
                {
-               if ((mask & s->s3->tmp.new_cipher->algorithm2) && md) 
+               if ((mask & ssl_get_algorithm2(s)) && md) 
                        {
                        s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
+#ifdef OPENSSL_FIPS
+                       if (EVP_MD_nid(md) == NID_md5)
+                               {
+                               EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
+                                               EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+                               }
+#endif
                        EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
                        EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen);
                        } 
@@ -622,9 +653,12 @@ int ssl3_digest_cached_records(SSL *s)
                        s->s3->handshake_dgst[i]=NULL;
                        }
                }
-       /* Free handshake_buffer BIO */
-       BIO_free(s->s3->handshake_buffer);
-       s->s3->handshake_buffer = NULL;
+       if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
+               {
+               /* Free handshake_buffer BIO */
+               BIO_free(s->s3->handshake_buffer);
+               s->s3->handshake_buffer = NULL;
+               }
 
        return 1;
        }
@@ -655,7 +689,7 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
                if (!ssl3_digest_cached_records(s))
                        return 0;
 
-       /* Search for djgest of specified type  in the handshake_dgst
+       /* Search for digest of specified type in the handshake_dgst
         * array*/
        for (i=0;i<SSL_MAX_DIGEST;i++) 
                {
@@ -670,6 +704,7 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
                return 0;
        }       
        EVP_MD_CTX_init(&ctx);
+       EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
        EVP_MD_CTX_copy_ex(&ctx,d);
        n=EVP_MD_CTX_size(&ctx);
        if (n < 0)
@@ -783,6 +818,9 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
        EVP_MD_CTX ctx;
        int i,ret=0;
        unsigned int n;
+#ifdef SSL_TRACE_CRYPTO_DEBUG
+       unsigned char *tmpout = out;
+#endif
 
        EVP_MD_CTX_init(&ctx);
        for (i=0; i<3; i++)
@@ -804,6 +842,23 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
                ret+=n;
                }
        EVP_MD_CTX_cleanup(&ctx);
+
+#ifdef SSL_TRACE_CRYPTO_DEBUG
+       if (s->msg_callback)
+               {
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
+                                               p, len, s, s->msg_callback_arg);
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
+                                       s->s3->client_random, SSL3_RANDOM_SIZE,
+                                               s, s->msg_callback_arg);
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
+                                       s->s3->server_random, SSL3_RANDOM_SIZE,
+                                       s, s->msg_callback_arg);
+               s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
+                                       tmpout, SSL3_MASTER_SECRET_SIZE,
+                                       s, s->msg_callback_arg);
+               }
+#endif
        return(ret);
        }