Import OpenSSL-1.0.0f.
authorPeter Avalos <pavalos@dragonflybsd.org>
Thu, 5 Jan 2012 00:06:12 +0000 (16:06 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Thu, 5 Jan 2012 00:06:12 +0000 (16:06 -0800)
      o Fix for DTLS plaintext recovery attack CVE-2011-4108
      o Clear block padding bytes of SSL 3.0 records CVE-2011-4576
      o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619
      o Check parameters are not NULL in GOST ENGINE CVE-2012-0027
      o Check for malformed RFC3779 data CVE-2011-4577

37 files changed:
crypto/openssl/CHANGES
crypto/openssl/FAQ
crypto/openssl/NEWS
crypto/openssl/README
crypto/openssl/README.DELETED
crypto/openssl/apps/cms.c
crypto/openssl/apps/openssl.cnf
crypto/openssl/apps/x509.c
crypto/openssl/crypto/bio/bf_buff.c
crypto/openssl/crypto/bio/bio.h
crypto/openssl/crypto/bn/asm/x86-mont.pl
crypto/openssl/crypto/bn/bn_blind.c
crypto/openssl/crypto/ec/ec2_smpl.c
crypto/openssl/crypto/opensslv.h
crypto/openssl/crypto/rand/rand_unix.c
crypto/openssl/crypto/rsa/rsa_eay.c
crypto/openssl/crypto/x509/x509_vfy.c
crypto/openssl/crypto/x509v3/v3_addr.c
crypto/openssl/doc/ssl/SSL_clear.pod
crypto/openssl/e_os2.h
crypto/openssl/engines/ccgost/gost2001_keyx.c
crypto/openssl/engines/ccgost/gost94_keyx.c
crypto/openssl/ssl/d1_both.c
crypto/openssl/ssl/d1_lib.c
crypto/openssl/ssl/d1_pkt.c
crypto/openssl/ssl/d1_srvr.c
crypto/openssl/ssl/s3_clnt.c
crypto/openssl/ssl/s3_enc.c
crypto/openssl/ssl/s3_lib.c
crypto/openssl/ssl/s3_srvr.c
crypto/openssl/ssl/ssl.h
crypto/openssl/ssl/ssl3.h
crypto/openssl/ssl/ssl_ciph.c
crypto/openssl/ssl/ssl_err.c
crypto/openssl/ssl/ssl_lib.c
crypto/openssl/ssl/ssl_locl.h
crypto/openssl/ssl/t1_lib.c

index a0de5ab..03e744a 100644 (file)
@@ -2,6 +2,63 @@
  OpenSSL CHANGES
  _______________
 
+ Changes between 1.0.0e and 1.0.0f [4 Jan 2012]
+
+  *) Nadhem Alfardan and Kenny Paterson have discovered an extension
+     of the Vaudenay padding oracle attack on CBC mode encryption
+     which enables an efficient plaintext recovery attack against
+     the OpenSSL implementation of DTLS. Their attack exploits timing
+     differences arising during decryption processing. A research
+     paper describing this attack can be found at:
+                  http://www.isg.rhul.ac.uk/~kp/dtls.pdf
+     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+     Security Group at Royal Holloway, University of London
+     (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
+     <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
+     for preparing the fix. (CVE-2011-4108)
+     [Robin Seggelmann, Michael Tuexen]
+
+  *) Clear bytes used for block padding of SSL 3.0 records.
+     (CVE-2011-4576)
+     [Adam Langley (Google)]
+
+  *) Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
+     [Adam Langley (Google)]
+
+  *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
+     [Andrey Kulikov <amdeich@gmail.com>]
+
+  *) Prevent malformed RFC3779 data triggering an assertion failure.
+     Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
+     and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
+     [Rob Austein <sra@hactrn.net>]
+
+  *) Improved PRNG seeding for VOS.
+     [Paul Green <Paul.Green@stratus.com>]
+
+  *) Fix ssl_ciph.c set-up race.
+     [Adam Langley (Google)]
+
+  *) Fix spurious failures in ecdsatest.c.
+     [Emilia Käsper (Google)]
+
+  *) Fix the BIO_f_buffer() implementation (which was mixing different
+     interpretations of the '..._len' fields).
+     [Adam Langley (Google)]
+
+  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
+     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
+     threads won't reuse the same blinding coefficients.
+
+     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
+     lock to call BN_BLINDING_invert_ex, and avoids one use of
+     BN_BLINDING_update for each BN_BLINDING structure (previously,
+     the last update always remained unused).
+     [Emilia Käsper (Google)]
+
+  *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf.
+     [Bob Buckholz (Google)]
+
  Changes between 1.0.0d and 1.0.0e [6 Sep 2011]
 
   *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted
   
  Changes between 0.9.8r and 0.9.8s [xx XXX xxxx]
 
+  *) Fix ssl_ciph.c set-up race.
+     [Adam Langley (Google)]
+
+  *) Fix spurious failures in ecdsatest.c.
+     [Emilia Käsper (Google)]
+
+  *) Fix the BIO_f_buffer() implementation (which was mixing different
+     interpretations of the '..._len' fields).
+     [Adam Langley (Google)]
+
+  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
+     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
+     threads won't reuse the same blinding coefficients.
+
+     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
+     lock to call BN_BLINDING_invert_ex, and avoids one use of
+     BN_BLINDING_update for each BN_BLINDING structure (previously,
+     the last update always remained unused).
+     [Emilia Käsper (Google)]
+
   *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
      for multi-threaded use of ECDH.
      [Adam Langley (Google)]
index fe54856..3b07cd3 100644 (file)
@@ -82,7 +82,7 @@ OpenSSL  -  Frequently Asked Questions
 * Which is the current version of OpenSSL?
 
 The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 1.0.0e was released on Sep 6th, 2011.
+OpenSSL 1.0.0f was released on Jan 4th, 2012.
 
 In addition to the current stable release, you can also access daily
 snapshots of the OpenSSL development version at <URL:
index 672810d..1fb25c6 100644 (file)
@@ -5,6 +5,14 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f:
+
+      o Fix for DTLS plaintext recovery attack CVE-2011-4108
+      o Clear block padding bytes of SSL 3.0 records CVE-2011-4576
+      o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619
+      o Check parameters are not NULL in GOST ENGINE CVE-2012-0027
+      o Check for malformed RFC3779 data CVE-2011-4577
+
   Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e:
 
       o Fix for CRL vulnerability issue CVE-2011-3207
index 8984379..50d54d5 100644 (file)
@@ -1,5 +1,5 @@
 
- OpenSSL 1.0.0e 6 Sep 2011
+ OpenSSL 1.0.0f 4 Jan 2012
 
  Copyright (c) 1998-2011 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
index 75a1ece..f44d5f1 100644 (file)
@@ -12,7 +12,6 @@ INSTALL.W64
 INSTALL.WCE
 MacOS/
 Makefile
-Makefile.bak
 Makefile.org
 Makefile.shared
 Netware/
index d29a884..3f5ee1b 100644 (file)
@@ -618,7 +618,7 @@ int MAIN(int argc, char **argv)
                BIO_printf (bio_err, "-certsout file certificate output file\n");
                BIO_printf (bio_err, "-signer file   signer certificate file\n");
                BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
-               BIO_printf (bio_err, "-skeyid        use subject key identifier\n");
+               BIO_printf (bio_err, "-keyid        use subject key identifier\n");
                BIO_printf (bio_err, "-in file       input file\n");
                BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
                BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
index 9d2cd5b..18760c6 100644 (file)
@@ -145,7 +145,7 @@ localityName                        = Locality Name (eg, city)
 organizationalUnitName         = Organizational Unit Name (eg, section)
 #organizationalUnitName_default        =
 
-commonName                     = Common Name (eg, YOUR name)
+commonName                     = Common Name (e.g. server FQDN or YOUR name)
 commonName_max                 = 64
 
 emailAddress                   = Email Address
index ed1e8c6..9f5eaeb 100644 (file)
@@ -987,7 +987,7 @@ bad:
                                else
                                        {
                                        pk=load_key(bio_err,
-                                               keyfile, FORMAT_PEM, 0,
+                                               keyfile, keyformat, 0,
                                                passin, e, "request key");
                                        if (pk == NULL) goto end;
                                        }
index c1fd75a..4b5a132 100644 (file)
@@ -209,7 +209,7 @@ start:
        /* add to buffer and return */
        if (i >= inl)
                {
-               memcpy(&(ctx->obuf[ctx->obuf_len]),in,inl);
+               memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl);
                ctx->obuf_len+=inl;
                return(num+inl);
                }
@@ -219,7 +219,7 @@ start:
                {
                if (i > 0) /* lets fill it up if we can */
                        {
-                       memcpy(&(ctx->obuf[ctx->obuf_len]),in,i);
+                       memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i);
                        in+=i;
                        inl-=i;
                        num+=i;
@@ -294,9 +294,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
        case BIO_C_GET_BUFF_NUM_LINES:
                ret=0;
                p1=ctx->ibuf;
-               for (i=ctx->ibuf_off; i<ctx->ibuf_len; i++)
+               for (i=0; i<ctx->ibuf_len; i++)
                        {
-                       if (p1[i] == '\n') ret++;
+                       if (p1[ctx->ibuf_off + i] == '\n') ret++;
                        }
                break;
        case BIO_CTRL_WPENDING:
@@ -399,17 +399,18 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
                for (;;)
                        {
                        BIO_clear_retry_flags(b);
-                       if (ctx->obuf_len > ctx->obuf_off)
+                       if (ctx->obuf_len > 0)
                                {
                                r=BIO_write(b->next_bio,
                                        &(ctx->obuf[ctx->obuf_off]),
-                                       ctx->obuf_len-ctx->obuf_off);
+                                       ctx->obuf_len);
 #if 0
-fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_off,r);
+fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r);
 #endif
                                BIO_copy_next_retry(b);
                                if (r <= 0) return((long)r);
                                ctx->obuf_off+=r;
+                               ctx->obuf_len-=r;
                                }
                        else
                                {
index 152802f..ab47abc 100644 (file)
@@ -306,6 +306,15 @@ DECLARE_STACK_OF(BIO)
 
 typedef struct bio_f_buffer_ctx_struct
        {
+       /* Buffers are setup like this:
+        *
+        * <---------------------- size ----------------------->
+        * +---------------------------------------------------+
+        * | consumed | remaining          | free space        |
+        * +---------------------------------------------------+
+        * <-- off --><------- len ------->
+        */
+
        /* BIO *bio; */ /* this is now in the BIO struct */
        int ibuf_size;  /* how big is the input buffer */
        int obuf_size;  /* how big is the output buffer */
index 5cd3cd2..e8f6b05 100755 (executable)
@@ -527,8 +527,10 @@ $sbit=$num;
        &jle    (&label("sqradd"));
 
        &mov    ($carry,"edx");
-       &lea    ("edx",&DWP(0,$sbit,"edx",2));
+       &add    ("edx","edx");
        &shr    ($carry,31);
+       &add    ("edx",$sbit);
+       &adc    ($carry,0);
 &set_label("sqrlast");
        &mov    ($word,$_n0);
        &mov    ($inp,$_np);
index e060592..9ed8bc2 100644 (file)
@@ -126,7 +126,7 @@ struct bn_blinding_st
                                  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
 #endif
        CRYPTO_THREADID tid;
-       unsigned int  counter;
+       int counter;
        unsigned long flags;
        BN_MONT_CTX *m_ctx;
        int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
@@ -160,7 +160,10 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
        if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
                BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
 
-       ret->counter = BN_BLINDING_COUNTER;
+       /* Set the counter to the special value -1
+        * to indicate that this is never-used fresh blinding
+        * that does not need updating before first use. */
+       ret->counter = -1;
        CRYPTO_THREADID_current(&ret->tid);
        return(ret);
 err:
@@ -190,7 +193,10 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
                goto err;
                }
 
-       if (--(b->counter) == 0 && b->e != NULL &&
+       if (b->counter == -1)
+               b->counter = 0;
+
+       if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
                !(b->flags & BN_BLINDING_NO_RECREATE))
                {
                /* re-create blinding parameters */
@@ -205,8 +211,8 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
 
        ret=1;
 err:
-       if (b->counter == 0)
-               b->counter = BN_BLINDING_COUNTER;
+       if (b->counter == BN_BLINDING_COUNTER)
+               b->counter = 0;
        return(ret);
        }
 
@@ -227,6 +233,12 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
                return(0);
                }
 
+       if (b->counter == -1)
+               /* Fresh blinding, doesn't need updating. */
+               b->counter = 0;
+       else if (!BN_BLINDING_update(b,ctx))
+               return(0);
+
        if (r != NULL)
                {
                if (!BN_copy(r, b->Ai)) ret=0;
@@ -247,22 +259,19 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ct
        int ret;
 
        bn_check_top(n);
-       if ((b->A == NULL) || (b->Ai == NULL))
-               {
-               BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED);
-               return(0);
-               }
 
        if (r != NULL)
                ret = BN_mod_mul(n, n, r, b->mod, ctx);
        else
-               ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
-
-       if (ret >= 0)
                {
-               if (!BN_BLINDING_update(b,ctx))
+               if (b->Ai == NULL)
+                       {
+                       BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED);
                        return(0);
+                       }
+               ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
                }
+
        bn_check_top(n);
        return(ret);
        }
index af94458..03deae6 100644 (file)
@@ -887,7 +887,7 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_
        field_sqr = group->meth->field_sqr;     
 
        /* only support affine coordinates */
-       if (!point->Z_is_one) goto err;
+       if (!point->Z_is_one) return -1;
 
        if (ctx == NULL)
                {
index 310a338..d6d61a0 100644 (file)
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER 0x1000005fL
+#define OPENSSL_VERSION_NUMBER 0x1000006fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.0e-fips 6 Sep 2011"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.0f-fips 4 Jan 2012"
 #else
-#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.0e 6 Sep 2011"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.0f 4 Jan 2012"
 #endif
 #define OPENSSL_VERSION_PTEXT  " part of " OPENSSL_VERSION_TEXT
 
index e9ead3a..e3a6557 100644 (file)
 # define FD_SETSIZE (8*sizeof(fd_set))
 #endif
 
-#ifdef __VOS__
+#if defined(OPENSSL_SYS_VOS)
+
+/* The following algorithm repeatedly samples the real-time clock
+   (RTC) to generate a sequence of unpredictable data.  The algorithm
+   relies upon the uneven execution speed of the code (due to factors
+   such as cache misses, interrupts, bus activity, and scheduling) and
+   upon the rather large relative difference between the speed of the
+   clock and the rate at which it can be read.
+
+   If this code is ported to an environment where execution speed is
+   more constant or where the RTC ticks at a much slower rate, or the
+   clock can be read with fewer instructions, it is likely that the
+   results would be far more predictable.
+
+   As a precaution, we generate 4 times the minimum required amount of
+   seed data.  */
+
 int RAND_poll(void)
 {
-       unsigned char buf[ENTROPY_NEEDED];
+       short int code;
+       gid_t curr_gid;
        pid_t curr_pid;
        uid_t curr_uid;
-       static int first=1;
-       int i;
-       long rnd = 0;
+       int i, k;
        struct timespec ts;
-       unsigned seed;
-
-/* The VOS random() function starts from a static seed so its
-   initial value is predictable.  If random() returns the
-   initial value, reseed it with dynamic data.  The VOS
-   real-time clock has a granularity of 1 nsec so it should be
-   reasonably difficult to predict its exact value.  Do not
-   gratuitously reseed the PRNG because other code in this
-   process or thread may be using it.  */
-
-       if (first) {
-               first = 0;
-               rnd = random ();
-               if (rnd == 1804289383) {
-                       clock_gettime (CLOCK_REALTIME, &ts);
-                       curr_pid = getpid();
-                       curr_uid = getuid();
-                       seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid;
-                       srandom (seed);
-               }
-       }
+       unsigned char v;
 
-       for (i = 0; i < sizeof(buf); i++) {
-               if (i % 4 == 0)
-                       rnd = random();
-               buf[i] = rnd;
-               rnd >>= 8;
-       }
-       RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
-       memset(buf, 0, sizeof(buf));
+#ifdef OPENSSL_SYS_VOS_HPPA
+       long duration;
+       extern void s$sleep (long *_duration, short int *_code);
+#else
+#ifdef OPENSSL_SYS_VOS_IA32
+       long long duration;
+       extern void s$sleep2 (long long *_duration, short int *_code);
+#else
+#error "Unsupported Platform."
+#endif /* OPENSSL_SYS_VOS_IA32 */
+#endif /* OPENSSL_SYS_VOS_HPPA */
+
+       /* Seed with the gid, pid, and uid, to ensure *some*
+          variation between different processes.  */
+
+       curr_gid = getgid();
+       RAND_add (&curr_gid, sizeof curr_gid, 1);
+       curr_gid = 0;
+
+       curr_pid = getpid();
+       RAND_add (&curr_pid, sizeof curr_pid, 1);
+       curr_pid = 0;
+
+       curr_uid = getuid();
+       RAND_add (&curr_uid, sizeof curr_uid, 1);
+       curr_uid = 0;
 
+       for (i=0; i<(ENTROPY_NEEDED*4); i++)
+       {
+               /* burn some cpu; hope for interrupts, cache
+                  collisions, bus interference, etc.  */
+               for (k=0; k<99; k++)
+                       ts.tv_nsec = random ();
+
+#ifdef OPENSSL_SYS_VOS_HPPA
+               /* sleep for 1/1024 of a second (976 us).  */
+               duration = 1;
+               s$sleep (&duration, &code);
+#else
+#ifdef OPENSSL_SYS_VOS_IA32
+               /* sleep for 1/65536 of a second (15 us).  */
+               duration = 1;
+               s$sleep2 (&duration, &code);
+#endif /* OPENSSL_SYS_VOS_IA32 */
+#endif /* OPENSSL_SYS_VOS_HPPA */
+
+               /* get wall clock time.  */
+               clock_gettime (CLOCK_REALTIME, &ts);
+
+               /* take 8 bits */
+               v = (unsigned char) (ts.tv_nsec % 256);
+               RAND_add (&v, sizeof v, 1);
+               v = 0;
+       }
        return 1;
 }
 #elif defined __OpenBSD__
index 7c94188..2e1ddd4 100644 (file)
@@ -314,51 +314,56 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
        return ret;
 }
 
-static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
-       BIGNUM *r, BN_CTX *ctx)
-{
-       if (local)
+static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+       BN_CTX *ctx)
+       {
+       if (unblind == NULL)
+               /* Local blinding: store the unblinding factor
+                * in BN_BLINDING. */
                return BN_BLINDING_convert_ex(f, NULL, b, ctx);
        else
                {
-               int ret;
-               CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
-               ret = BN_BLINDING_convert_ex(f, r, b, ctx);
-               CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
-               return ret;
-               }
-}
-
-static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
-       BIGNUM *r, BN_CTX *ctx)
-{
-       if (local)
-               return BN_BLINDING_invert_ex(f, NULL, b, ctx);
-       else
-               {
+               /* Shared blinding: store the unblinding factor
+                * outside BN_BLINDING. */
                int ret;
                CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
-               ret = BN_BLINDING_invert_ex(f, r, b, ctx);
+               ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
                CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
                return ret;
                }
-}
+       }
+
+static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+       BN_CTX *ctx)
+       {
+       /* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
+        * will use the unblinding factor stored in BN_BLINDING.
+        * If BN_BLINDING is shared between threads, unblind must be non-null:
+        * BN_BLINDING_invert_ex will then use the local unblinding factor,
+        * and will only read the modulus from BN_BLINDING.
+        * In both cases it's safe to access the blinding without a lock.
+        */
+       return BN_BLINDING_invert_ex(f, unblind, b, ctx);
+       }
 
 /* signing */
 static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
             unsigned char *to, RSA *rsa, int padding)
        {
-       BIGNUM *f, *ret, *br, *res;
+       BIGNUM *f, *ret, *res;
        int i,j,k,num=0,r= -1;
        unsigned char *buf=NULL;
        BN_CTX *ctx=NULL;
        int local_blinding = 0;
+       /* Used only if the blinding structure is shared. A non-NULL unblind
+        * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+        * the unblinding factor outside the blinding structure. */
+       BIGNUM *unblind = NULL;
        BN_BLINDING *blinding = NULL;
 
        if ((ctx=BN_CTX_new()) == NULL) goto err;
        BN_CTX_start(ctx);
        f   = BN_CTX_get(ctx);
-       br  = BN_CTX_get(ctx);
        ret = BN_CTX_get(ctx);
        num = BN_num_bytes(rsa->n);
        buf = OPENSSL_malloc(num);
@@ -406,8 +411,15 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
                }
        
        if (blinding != NULL)
-               if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+               {
+               if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
+                       {
+                       RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
+                       goto err;
+                       }
+               if (!rsa_blinding_convert(blinding, f, unblind, ctx))
                        goto err;
+               }
 
        if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
                ((rsa->p != NULL) &&
@@ -441,7 +453,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
                }
 
        if (blinding)
-               if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+               if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
                        goto err;
 
        if (padding == RSA_X931_PADDING)
@@ -480,18 +492,21 @@ err:
 static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
             unsigned char *to, RSA *rsa, int padding)
        {
-       BIGNUM *f, *ret, *br;
+       BIGNUM *f, *ret;
        int j,num=0,r= -1;
        unsigned char *p;
        unsigned char *buf=NULL;
        BN_CTX *ctx=NULL;
        int local_blinding = 0;
+       /* Used only if the blinding structure is shared. A non-NULL unblind
+        * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+        * the unblinding factor outside the blinding structure. */
+       BIGNUM *unblind = NULL;
        BN_BLINDING *blinding = NULL;
 
        if((ctx = BN_CTX_new()) == NULL) goto err;
        BN_CTX_start(ctx);
        f   = BN_CTX_get(ctx);
-       br  = BN_CTX_get(ctx);
        ret = BN_CTX_get(ctx);
        num = BN_num_bytes(rsa->n);
        buf = OPENSSL_malloc(num);
@@ -529,8 +544,15 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
                }
        
        if (blinding != NULL)
-               if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+               {
+               if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
+                       {
+                       RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
                        goto err;
+                       }
+               if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+                       goto err;
+               }
 
        /* do the decrypt */
        if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
@@ -564,7 +586,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
                }
 
        if (blinding)
-               if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+               if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
                        goto err;
 
        p=buf;
index 5a0b024..701ec56 100644 (file)
@@ -1732,7 +1732,7 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
        atm.length=sizeof(buff2);
        atm.data=(unsigned char *)buff2;
 
-       if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL)
+       if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
                return 0;
 
        if (ctm->type == V_ASN1_UTCTIME)
index 0d70e86..df46a49 100644 (file)
@@ -142,12 +142,13 @@ unsigned int v3_addr_get_afi(const IPAddressFamily *f)
  * Expand the bitstring form of an address into a raw byte array.
  * At the moment this is coded for simplicity, not speed.
  */
-static void addr_expand(unsigned char *addr,
+static int addr_expand(unsigned char *addr,
                        const ASN1_BIT_STRING *bs,
                        const int length,
                        const unsigned char fill)
 {
-  OPENSSL_assert(bs->length >= 0 && bs->length <= length);
+  if (bs->length < 0 || bs->length > length)
+    return 0;
   if (bs->length > 0) {
     memcpy(addr, bs->data, bs->length);
     if ((bs->flags & 7) != 0) {
@@ -159,6 +160,7 @@ static void addr_expand(unsigned char *addr,
     }
   }
   memset(addr + bs->length, fill, length - bs->length);
+  return 1;
 }
 
 /*
@@ -181,15 +183,13 @@ static int i2r_address(BIO *out,
     return 0;
   switch (afi) {
   case IANA_AFI_IPV4:
-    if (bs->length > 4)
+    if (!addr_expand(addr, bs, 4, fill))
       return 0;
-    addr_expand(addr, bs, 4, fill);
     BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
     break;
   case IANA_AFI_IPV6:
-    if (bs->length > 16)
+    if (!addr_expand(addr, bs, 16, fill))
       return 0;
-    addr_expand(addr, bs, 16, fill);
     for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
       ;
     for (i = 0; i < n; i += 2)
@@ -315,6 +315,12 @@ static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
 /*
  * Sort comparison function for a sequence of IPAddressOrRange
  * elements.
+ *
+ * There's no sane answer we can give if addr_expand() fails, and an
+ * assertion failure on externally supplied data is seriously uncool,
+ * so we just arbitrarily declare that if given invalid inputs this
+ * function returns -1.  If this messes up your preferred sort order
+ * for garbage input, tough noogies.
  */
 static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
                                const IPAddressOrRange *b,
@@ -326,22 +332,26 @@ static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
 
   switch (a->type) {
   case IPAddressOrRange_addressPrefix:
-    addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
+    if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
+      return -1;
     prefixlen_a = addr_prefixlen(a->u.addressPrefix);
     break;
   case IPAddressOrRange_addressRange:
-    addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
+    if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
+      return -1;
     prefixlen_a = length * 8;
     break;
   }
 
   switch (b->type) {
   case IPAddressOrRange_addressPrefix:
-    addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
+    if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
+      return -1;
     prefixlen_b = addr_prefixlen(b->u.addressPrefix);
     break;
   case IPAddressOrRange_addressRange:
-    addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
+    if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
+      return -1;
     prefixlen_b = length * 8;
     break;
   }
@@ -383,6 +393,7 @@ static int range_should_be_prefix(const unsigned char *min,
   unsigned char mask;
   int i, j;
 
+  OPENSSL_assert(memcmp(min, max, length) <= 0);
   for (i = 0; i < length && min[i] == max[i]; i++)
     ;
   for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
@@ -601,10 +612,10 @@ static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
     return NULL;
   switch (afi) {
   case IANA_AFI_IPV4:
-    sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+    (void) sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
     break;
   case IANA_AFI_IPV6:
-    sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+    (void) sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
     break;
   }
   f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
@@ -656,22 +667,22 @@ int v3_addr_add_range(IPAddrBlocks *addr,
 /*
  * Extract min and max values from an IPAddressOrRange.
  */
-static void extract_min_max(IPAddressOrRange *aor,
+static int extract_min_max(IPAddressOrRange *aor,
                            unsigned char *min,
                            unsigned char *max,
                            int length)
 {
-  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+  if (aor == NULL || min == NULL || max == NULL)
+    return 0;
   switch (aor->type) {
   case IPAddressOrRange_addressPrefix:
-    addr_expand(min, aor->u.addressPrefix, length, 0x00);
-    addr_expand(max, aor->u.addressPrefix, length, 0xFF);
-    return;
+    return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
+           addr_expand(max, aor->u.addressPrefix, length, 0xFF));
   case IPAddressOrRange_addressRange:
-    addr_expand(min, aor->u.addressRange->min, length, 0x00);
-    addr_expand(max, aor->u.addressRange->max, length, 0xFF);
-    return;
+    return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
+           addr_expand(max, aor->u.addressRange->max, length, 0xFF));
   }
+  return 0;
 }
 
 /*
@@ -687,9 +698,10 @@ int v3_addr_get_range(IPAddressOrRange *aor,
   if (aor == NULL || min == NULL || max == NULL ||
       afi_length == 0 || length < afi_length ||
       (aor->type != IPAddressOrRange_addressPrefix &&
-       aor->type != IPAddressOrRange_addressRange))
+       aor->type != IPAddressOrRange_addressRange) ||
+      !extract_min_max(aor, min, max, afi_length))
     return 0;
-  extract_min_max(aor, min, max, afi_length);
+
   return afi_length;
 }
 
@@ -771,8 +783,9 @@ int v3_addr_is_canonical(IPAddrBlocks *addr)
       IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
       IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
 
-      extract_min_max(a, a_min, a_max, length);
-      extract_min_max(b, b_min, b_max, length);
+      if (!extract_min_max(a, a_min, a_max, length) ||
+         !extract_min_max(b, b_min, b_max, length))
+       return 0;
 
       /*
        * Punt misordered list, overlapping start, or inverted range.
@@ -800,14 +813,17 @@ int v3_addr_is_canonical(IPAddrBlocks *addr)
     }
 
     /*
-     * Check final range to see if it should be a prefix.
+     * Check range to see if it's inverted or should be a
+     * prefix.
      */
     j = sk_IPAddressOrRange_num(aors) - 1;
     {
       IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
-      if (a->type == IPAddressOrRange_addressRange) {
-       extract_min_max(a, a_min, a_max, length);
-       if (range_should_be_prefix(a_min, a_max, length) >= 0)
+      if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+       if (!extract_min_max(a, a_min, a_max, length))
+         return 0;
+       if (memcmp(a_min, a_max, length) > 0 ||
+           range_should_be_prefix(a_min, a_max, length) >= 0)
          return 0;
       }
     }
@@ -841,8 +857,16 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
     unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
     unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
 
-    extract_min_max(a, a_min, a_max, length);
-    extract_min_max(b, b_min, b_max, length);
+    if (!extract_min_max(a, a_min, a_max, length) ||
+       !extract_min_max(b, b_min, b_max, length))
+      return 0;
+
+    /*
+     * Punt inverted ranges.
+     */
+    if (memcmp(a_min, a_max, length) > 0 ||
+       memcmp(b_min, b_max, length) > 0)
+      return 0;
 
     /*
      * Punt overlaps.
@@ -860,8 +884,8 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
       IPAddressOrRange *merged;
       if (!make_addressRange(&merged, a_min, b_max, length))
        return 0;
-      sk_IPAddressOrRange_set(aors, i, merged);
-      sk_IPAddressOrRange_delete(aors, i + 1);
+      (void) sk_IPAddressOrRange_set(aors, i, merged);
+      (void) sk_IPAddressOrRange_delete(aors, i + 1);
       IPAddressOrRange_free(a);
       IPAddressOrRange_free(b);
       --i;
@@ -869,6 +893,20 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
     }
   }
 
+  /*
+   * Check for inverted final range.
+   */
+  j = sk_IPAddressOrRange_num(aors) - 1;
+  {
+    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+    if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+      unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+      extract_min_max(a, a_min, a_max, length);
+      if (memcmp(a_min, a_max, length) > 0)
+       return 0;
+    }
+  }
+
   return 1;
 }
 
@@ -885,7 +923,7 @@ int v3_addr_canonize(IPAddrBlocks *addr)
                                    v3_addr_get_afi(f)))
       return 0;
   }
-  sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
+  (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
   sk_IPAddressFamily_sort(addr);
   OPENSSL_assert(v3_addr_is_canonical(addr));
   return 1;
@@ -1017,6 +1055,11 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
        X509V3_conf_err(val);
        goto err;
       }
+      if (memcmp(min, max, length_from_afi(afi)) > 0) {
+       X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+       X509V3_conf_err(val);
+       goto err;
+      }
       if (!v3_addr_add_range(addr, afi, safi, min, max)) {
        X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
        goto err;
@@ -1102,13 +1145,15 @@ static int addr_contains(IPAddressOrRanges *parent,
 
   p = 0;
   for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
-    extract_min_max(sk_IPAddressOrRange_value(child, c),
-                   c_min, c_max, length);
+    if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
+                        c_min, c_max, length))
+      return -1;
     for (;; p++) {
       if (p >= sk_IPAddressOrRange_num(parent))
        return 0;
-      extract_min_max(sk_IPAddressOrRange_value(parent, p),
-                     p_min, p_max, length);
+      if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
+                          p_min, p_max, length))
+       return 0;
       if (memcmp(p_max, c_max, length) < 0)
        continue;
       if (memcmp(p_min, c_min, length) > 0)
@@ -1130,7 +1175,7 @@ int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
     return 1;
   if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
     return 0;
-  sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+  (void) sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
   for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
     IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
     int j = sk_IPAddressFamily_find(b, fa);
@@ -1195,7 +1240,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
   }
   if (!v3_addr_is_canonical(ext))
     validation_err(X509_V_ERR_INVALID_EXTENSION);
-  sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+  (void) sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
   if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
     X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
     ret = 0;
@@ -1221,7 +1266,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
       }
       continue;
     }
-    sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
+    (void) sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
     for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
       IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
       int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
index 8e077e3..d4df1bf 100644 (file)
@@ -39,10 +39,16 @@ for a description of the method's properties.
 SSL_clear() resets the SSL object to allow for another connection. The
 reset operation however keeps several settings of the last sessions
 (some of these settings were made automatically during the last
-handshake). It only makes sense when opening a new session (or reusing
-an old one) with the same peer that shares these settings.
-SSL_clear() is not a short form for the sequence
-L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>; .
+handshake). It only makes sense for a new connection with the exact
+same peer that shares these settings, and may fail if that peer
+changes its settings between connections. Use the sequence
+L<SSL_get_session(3)|SSL_get_session(3)>;
+L<SSL_new(3)|SSL_new(3)>;
+L<SSL_set_session(3)|SSL_set_session(3)>;
+L<SSL_free(3)|SSL_free(3)>
+instead to avoid such failures
+(or simply L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>
+if session reuse is not desired).
 
 =head1 RETURN VALUES
 
index 4c785c6..d30724d 100644 (file)
@@ -193,8 +193,14 @@ extern "C" {
 #endif
 
 /* --------------------------------- VOS ----------------------------------- */
-#ifdef OPENSSL_SYSNAME_VOS
+#if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
 # define OPENSSL_SYS_VOS
+#ifdef __HPPA__
+# define OPENSSL_SYS_VOS_HPPA
+#endif
+#ifdef __IA32__
+# define OPENSSL_SYS_VOS_IA32
+#endif
 #endif
 
 /* ------------------------------- VxWorks --------------------------------- */
index 00759bc..c748102 100644 (file)
@@ -280,6 +280,10 @@ int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_l
                }
                
        param = get_encryption_params(gkt->key_agreement_info->cipher);
+    if(!param){
+        goto err;
+    }
+
        gost_init(&ctx,param->sblock);  
        OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
        memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
index 624be58..0d7d3ff 100644 (file)
@@ -261,6 +261,10 @@ int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len
                }
 
        param = get_encryption_params(gkt->key_agreement_info->cipher);
+    if(!param){
+        goto err;
+    }
+       
        gost_init(&cctx,param->sblock); 
        OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
        memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
index 2180c6d..9f898d6 100644 (file)
@@ -158,7 +158,6 @@ static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1
 /* XDTLS:  figure out the right values */
 static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
 
-static unsigned int dtls1_min_mtu(void);
 static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
 static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, 
        unsigned long frag_len);
@@ -264,11 +263,10 @@ int dtls1_do_write(SSL *s, int type)
                        return ret;
                mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
                }
-
-       OPENSSL_assert(mtu > 0);  /* should have something reasonable now */
-
 #endif
 
+       OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());  /* should have something reasonable now */
+
        if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)
                OPENSSL_assert(s->init_num == 
                        (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
@@ -795,7 +793,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
                *ok = 0;
                return i;
                }
-       OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH);
+       /* Handshake fails if message header is incomplete */
+       if (i != DTLS1_HM_HEADER_LENGTH)
+               {
+               al=SSL_AD_UNEXPECTED_MESSAGE;
+               SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
+               goto f_err;
+               }
 
        /* parse the message fragment header */
        dtls1_get_message_header(wire, &msg_hdr);
@@ -867,7 +871,12 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
 
        /* XDTLS:  an incorrectly formatted fragment should cause the 
         * handshake to fail */
-       OPENSSL_assert(i == (int)frag_len);
+       if (i != (int)frag_len)
+               {
+               al=SSL3_AD_ILLEGAL_PARAMETER;
+               SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETER);
+               goto f_err;
+               }
 
        *ok = 1;
 
@@ -1367,7 +1376,7 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
        return p;
        }
 
-static unsigned int 
+unsigned int 
 dtls1_min_mtu(void)
        {
        return (g_probable_mtu[(sizeof(g_probable_mtu) / 
index 48e8b6f..c3b77c8 100644 (file)
@@ -204,7 +204,8 @@ void dtls1_clear(SSL *s)
     pqueue buffered_messages;
        pqueue sent_messages;
        pqueue buffered_app_data;
-       
+       unsigned int mtu;
+
        if (s->d1)
                {
                unprocessed_rcds = s->d1->unprocessed_rcds.q;
@@ -212,6 +213,7 @@ void dtls1_clear(SSL *s)
                buffered_messages = s->d1->buffered_messages;
                sent_messages = s->d1->sent_messages;
                buffered_app_data = s->d1->buffered_app_data.q;
+               mtu = s->d1->mtu;
 
                dtls1_clear_queues(s);
 
@@ -222,6 +224,11 @@ void dtls1_clear(SSL *s)
                        s->d1->cookie_len = sizeof(s->d1->cookie);
                        }
 
+               if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
+                       {
+                       s->d1->mtu = mtu;
+                       }
+
                s->d1->unprocessed_rcds.q = unprocessed_rcds;
                s->d1->processed_rcds.q = processed_rcds;
                s->d1->buffered_messages = buffered_messages;
index 39aac73..e0c0f0c 100644 (file)
@@ -375,6 +375,7 @@ dtls1_process_record(SSL *s)
        SSL3_RECORD *rr;
        unsigned int mac_size;
        unsigned char md[EVP_MAX_MD_SIZE];
+       int decryption_failed_or_bad_record_mac = 0;
 
 
        rr= &(s->s3->rrec);
@@ -409,13 +410,10 @@ dtls1_process_record(SSL *s)
        enc_err = s->method->ssl3_enc->enc(s,0);
        if (enc_err <= 0)
                {
-               /* decryption failed, silently discard message */
-               if (enc_err < 0)
-                       {
-                       rr->length = 0;
-                       s->packet_length = 0;
-                       }
-               goto err;
+               /* To minimize information leaked via timing, we will always
+                * perform all computations before discarding the message.
+                */
+               decryption_failed_or_bad_record_mac = 1;
                }
 
 #ifdef TLS_DEBUG
@@ -445,7 +443,7 @@ printf("\n");
                        SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
                        goto f_err;
 #else
-                       goto err;
+                       decryption_failed_or_bad_record_mac = 1;
 #endif                 
                        }
                /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
@@ -456,17 +454,25 @@ printf("\n");
                        SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
                        goto f_err;
 #else
-                       goto err;
+                       decryption_failed_or_bad_record_mac = 1;
 #endif
                        }
                rr->length-=mac_size;
                i=s->method->ssl3_enc->mac(s,md,0);
                if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
                        {
-                       goto err;
+                       decryption_failed_or_bad_record_mac = 1;
                        }
                }
 
+       if (decryption_failed_or_bad_record_mac)
+               {
+               /* decryption failed, silently discard message */
+               rr->length = 0;
+               s->packet_length = 0;
+               goto err;
+               }
+
        /* r->length is now just compressed */
        if (s->expand != NULL)
                {
index a6a4c87..149983b 100644 (file)
@@ -1271,7 +1271,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
                                EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
                                EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
-                               EVP_SignUpdate(&md_ctx,&(d[4]),n);
+                               EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
                                if (!EVP_SignFinal(&md_ctx,&(p[2]),
                                        (unsigned int *)&i,pkey))
                                        {
index 50bd415..53223bd 100644 (file)
@@ -953,7 +953,7 @@ int ssl3_get_server_hello(SSL *s)
                /* wrong packet length */
                al=SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
-               goto err;
+               goto f_err;
                }
 
        return(1);
@@ -1837,7 +1837,7 @@ int ssl3_get_new_session_ticket(SSL *s)
        if (n < 6)
                {
                /* need at least ticket_lifetime_hint + ticket length */
-               al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
+               al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
@@ -1848,7 +1848,7 @@ int ssl3_get_new_session_ticket(SSL *s)
        /* ticket_lifetime_hint + ticket_length + ticket */
        if (ticklen + 6 != n)
                {
-               al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR;
+               al = SSL_AD_DECODE_ERROR;
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
index 58386e1..b145970 100644 (file)
@@ -511,6 +511,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);
                        }
index 62c791c..1130244 100644 (file)
@@ -2177,6 +2177,7 @@ void ssl3_clear(SSL *s)
        {
        unsigned char *rp,*wp;
        size_t rlen, wlen;
+       int init_extra;
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
        if (s->s3->client_opaque_prf_input != NULL)
@@ -2215,6 +2216,7 @@ void ssl3_clear(SSL *s)
        wp = s->s3->wbuf.buf;
        rlen = s->s3->rbuf.len;
        wlen = s->s3->wbuf.len;
+       init_extra = s->s3->init_extra;
        if (s->s3->handshake_buffer) {
                BIO_free(s->s3->handshake_buffer);
                s->s3->handshake_buffer = NULL;
@@ -2227,6 +2229,7 @@ void ssl3_clear(SSL *s)
        s->s3->wbuf.buf = wp;
        s->s3->rbuf.len = rlen;
        s->s3->wbuf.len = wlen;
+       s->s3->init_extra = init_extra;
 
        ssl_free_wbio_buffer(s);
 
index c3b5ff3..d734c35 100644 (file)
@@ -258,6 +258,7 @@ int ssl3_accept(SSL *s)
                                }
 
                        s->init_num=0;
+                       s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 
                        if (s->state != SSL_ST_RENEGOTIATE)
                                {
@@ -755,6 +756,14 @@ int ssl3_check_client_hello(SSL *s)
        int ok;
        long n;
 
+       /* We only allow the client to restart the handshake once per
+        * negotiation. */
+       if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
+               {
+               SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
+               return -1;
+               }
+
        /* this function is called when we really expect a Certificate message,
         * so permit appropriate message length */
        n=s->method->ssl_get_message(s,
@@ -783,6 +792,7 @@ int ssl3_check_client_hello(SSL *s)
                        s->s3->tmp.ecdh = NULL;
                        }
 #endif
+               s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
                return 2;
                }
        return 1;
@@ -2130,6 +2140,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                if (i <= 0)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+                       BN_clear_free(pub);
                        goto err;
                        }
 
index e4c3f65..8f922ee 100644 (file)
@@ -1882,6 +1882,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL3_CALLBACK_CTRL                        233
 #define SSL_F_SSL3_CHANGE_CIPHER_STATE                  129
 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM             130
+#define SSL_F_SSL3_CHECK_CLIENT_HELLO                   304
 #define SSL_F_SSL3_CLIENT_HELLO                                 131
 #define SSL_F_SSL3_CONNECT                              132
 #define SSL_F_SSL3_CTRL                                         213
@@ -2139,6 +2140,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_MISSING_TMP_RSA_KEY                       172
 #define SSL_R_MISSING_TMP_RSA_PKEY                      173
 #define SSL_R_MISSING_VERIFY_MESSAGE                    174
+#define SSL_R_MULTIPLE_SGC_RESTARTS                     346
 #define SSL_R_NON_SSLV2_INITIAL_PACKET                  175
 #define SSL_R_NO_CERTIFICATES_RETURNED                  176
 #define SSL_R_NO_CERTIFICATE_ASSIGNED                   177
index baaa89e..9c2c412 100644 (file)
@@ -379,6 +379,17 @@ typedef struct ssl3_buffer_st
 #define SSL3_FLAGS_POP_BUFFER                  0x0004
 #define TLS1_FLAGS_TLS_PADDING_BUG             0x0008
 #define TLS1_FLAGS_SKIP_CERT_VERIFY            0x0010
+/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
+ * restart a handshake because of MS SGC and so prevents us
+ * from restarting the handshake in a loop. It's reset on a
+ * renegotiation, so effectively limits the client to one restart
+ * per negotiation. This limits the possibility of a DDoS
+ * attack where the client handshakes in a loop using SGC to
+ * restart. Servers which permit renegotiation can still be
+ * effected, but we can't prevent that.
+ */
+#define SSL3_FLAGS_SGC_RESTART_DONE            0x0040
 
 typedef struct ssl3_state_st
        {
index a8ce186..54ba7ef 100644 (file)
@@ -446,6 +446,7 @@ static void load_builtin_compressions(void)
                                                sk_SSL_COMP_push(ssl_comp_methods,comp);
                                                }
                                        }
+                                       sk_SSL_COMP_sort(ssl_comp_methods);
                                }
                        MemCheck_on();
                        }
index 0eed464..e9be771 100644 (file)
@@ -1,6 +1,6 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -137,6 +137,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL),   "SSL3_CALLBACK_CTRL"},
 {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE),     "SSL3_CHANGE_CIPHER_STATE"},
 {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),        "SSL3_CHECK_CERT_AND_ALGORITHM"},
+{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO),      "SSL3_CHECK_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO),    "SSL3_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"},
 {ERR_FUNC(SSL_F_SSL3_CTRL),    "SSL3_CTRL"},
@@ -397,6 +398,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY)   ,"missing tmp rsa key"},
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY)  ,"missing tmp rsa pkey"},
 {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"},
+{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"},
 {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"},
 {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"},
 {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"},
index 4673279..8e89911 100644 (file)
@@ -1054,6 +1054,9 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
                s->max_cert_list=larg;
                return(l);
        case SSL_CTRL_SET_MTU:
+               if (larg < (long)dtls1_min_mtu())
+                       return 0;
+
                if (SSL_version(s) == DTLS1_VERSION ||
                    SSL_version(s) == DTLS1_BAD_VER)
                        {
index 4c78393..cea622a 100644 (file)
@@ -950,6 +950,7 @@ void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
 int dtls1_send_newsession_ticket(SSL *s);
+unsigned int dtls1_min_mtu(void);
 
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
index 85371c8..26cbae4 100644 (file)
@@ -971,6 +971,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                sdata = data;
                                if (dsize > 0)
                                        {
+                                       if (s->tlsext_ocsp_exts)
+                                               {
+                                               sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
+                                                                          X509_EXTENSION_free);
+                                               }
+
                                        s->tlsext_ocsp_exts =
                                                d2i_X509_EXTENSIONS(NULL,
                                                        &sdata, dsize);