Fix for PEM_X509_INFO_read_bio.
[openssl.git] / ssl / d1_enc.c
index 7b369644ff8fbbbe8247772e4ade44706c4270c4..712c4647f24cb072beddda21a79d993f583a100d 100644 (file)
 
 #include <stdio.h>
 #include "ssl_locl.h"
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 #include <openssl/rand.h>
+#ifdef KSSL_DEBUG
+#include <openssl/des.h>
+#endif
 
-
+/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occured. */
 int dtls1_enc(SSL *s, int send)
        {
        SSL3_RECORD *rec;
        EVP_CIPHER_CTX *ds;
        unsigned long l;
-       int bs,i,ii,j,k,n=0;
+       int bs,i,j,k,mac_size=0;
        const EVP_CIPHER *enc;
 
        if (send)
                {
-               if (s->write_hash != NULL)
-                       n=EVP_MD_size(s->write_hash);
+               if (EVP_MD_CTX_md(s->write_hash))
+                       {
+                       mac_size=EVP_MD_CTX_size(s->write_hash);
+                       if (mac_size < 0)
+                               return -1;
+                       }
                ds=s->enc_write_ctx;
                rec= &(s->s3->wrec);
                if (s->enc_write_ctx == NULL)
@@ -146,13 +162,19 @@ int dtls1_enc(SSL *s, int send)
                                fprintf(stderr, "%s:%d: rec->data != rec->input\n",
                                        __FILE__, __LINE__);
                        else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
-                               RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher));
+                               {
+                               if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
+                                       return -1;
+                               }
                        }
                }
        else
                {
-               if (s->read_hash != NULL)
-                       n=EVP_MD_size(s->read_hash);
+               if (EVP_MD_CTX_md(s->read_hash))
+                       {
+                       mac_size=EVP_MD_CTX_size(s->read_hash);
+                       OPENSSL_assert(mac_size >= 0);
+                       }
                ds=s->enc_read_ctx;
                rec= &(s->s3->rrec);
                if (s->enc_read_ctx == NULL)
@@ -216,11 +238,7 @@ int dtls1_enc(SSL *s, int send)
                if (!send)
                        {
                        if (l == 0 || l%bs != 0)
-                               {
-                               SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
-                               ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
                                return 0;
-                               }
                        }
                
                EVP_Cipher(ds,rec->data,rec->input,l);
@@ -235,43 +253,7 @@ int dtls1_enc(SSL *s, int send)
 #endif /* KSSL_DEBUG */
 
                if ((bs != 1) && !send)
-                       {
-                       ii=i=rec->data[l-1]; /* padding_length */
-                       i++;
-                       if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
-                               {
-                               /* First packet is even in size, so check */
-                               if ((memcmp(s->s3->read_sequence,
-                                       "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
-                                       s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
-                               if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
-                                       i--;
-                               }
-                       /* TLS 1.0 does not bound the number of padding bytes by the block size.
-                        * All of them must have value 'padding_length'. */
-                       if (i > (int)rec->length)
-                               {
-                               /* Incorrect padding. SSLerr() and ssl3_alert are done
-                                * by caller: we don't want to reveal whether this is
-                                * a decryption error or a MAC verification failure
-                                * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
-                                */
-                               return -1;
-                               }
-                       for (j=(int)(l-i); j<(int)l; j++)
-                               {
-                               if (rec->data[j] != ii)
-                                       {
-                                       /* Incorrect padding */
-                                       return -1;
-                                       }
-                               }
-                       rec->length-=i;
-
-                       rec->data += bs;    /* skip the implicit IV */
-                       rec->input += bs;
-                       rec->length -= bs;
-                       }
+                       return tls1_cbc_remove_padding(s, rec, bs, mac_size);
                }
        return(1);
        }