summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libcrypto/bio/bf_buff.c15
-rw-r--r--lib/libcrypto/bio/bio.h9
-rw-r--r--lib/libcrypto/bn/bn_blind.c37
-rw-r--r--lib/libcrypto/ec/ec2_smpl.c2
-rw-r--r--lib/libcrypto/opensslv.h6
-rw-r--r--lib/libcrypto/rand/rand_unix.c108
-rw-r--r--lib/libcrypto/rsa/rsa_eay.c80
-rw-r--r--lib/libcrypto/util/mkerr.pl2
-rw-r--r--lib/libcrypto/x509/x509_vfy.c2
-rw-r--r--lib/libcrypto/x509v3/v3_addr.c125
-rw-r--r--lib/libssl/d1_pkt.c26
-rw-r--r--lib/libssl/d1_srvr.c2
-rw-r--r--lib/libssl/doc/openssl.cnf2
-rw-r--r--lib/libssl/s3_clnt.c6
-rw-r--r--lib/libssl/s3_lib.c3
-rw-r--r--lib/libssl/s3_srvr.c11
-rw-r--r--lib/libssl/ssl.h2
-rw-r--r--lib/libssl/ssl3.h11
-rw-r--r--lib/libssl/ssl_ciph.c1
-rw-r--r--lib/libssl/ssl_err.c4
-rw-r--r--lib/libssl/ssl_lib.c3
-rw-r--r--lib/libssl/ssl_locl.h1
-rw-r--r--lib/libssl/t1_lib.c6
-rw-r--r--lib/libssl/test/testssl8
24 files changed, 322 insertions, 150 deletions
diff --git a/lib/libcrypto/bio/bf_buff.c b/lib/libcrypto/bio/bf_buff.c
index c1fd75aaad8..4b5a132d8a1 100644
--- a/lib/libcrypto/bio/bf_buff.c
+++ b/lib/libcrypto/bio/bf_buff.c
@@ -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
{
diff --git a/lib/libcrypto/bio/bio.h b/lib/libcrypto/bio/bio.h
index 152802fbdf2..ab47abcf143 100644
--- a/lib/libcrypto/bio/bio.h
+++ b/lib/libcrypto/bio/bio.h
@@ -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 */
diff --git a/lib/libcrypto/bn/bn_blind.c b/lib/libcrypto/bn/bn_blind.c
index e060592fdc5..9ed8bc2b40b 100644
--- a/lib/libcrypto/bn/bn_blind.c
+++ b/lib/libcrypto/bn/bn_blind.c
@@ -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);
}
diff --git a/lib/libcrypto/ec/ec2_smpl.c b/lib/libcrypto/ec/ec2_smpl.c
index af94458ca7b..03deae66746 100644
--- a/lib/libcrypto/ec/ec2_smpl.c
+++ b/lib/libcrypto/ec/ec2_smpl.c
@@ -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)
{
diff --git a/lib/libcrypto/opensslv.h b/lib/libcrypto/opensslv.h
index 310a3387be2..d6d61a0c7d4 100644
--- a/lib/libcrypto/opensslv.h
+++ b/lib/libcrypto/opensslv.h
@@ -25,11 +25,11 @@
* (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
diff --git a/lib/libcrypto/rand/rand_unix.c b/lib/libcrypto/rand/rand_unix.c
index 4bb9666e49d..3316388443e 100644
--- a/lib/libcrypto/rand/rand_unix.c
+++ b/lib/libcrypto/rand/rand_unix.c
@@ -133,47 +133,87 @@
# 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__
diff --git a/lib/libcrypto/rsa/rsa_eay.c b/lib/libcrypto/rsa/rsa_eay.c
index 7c941885f07..2e1ddd48d35 100644
--- a/lib/libcrypto/rsa/rsa_eay.c
+++ b/lib/libcrypto/rsa/rsa_eay.c
@@ -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;
diff --git a/lib/libcrypto/util/mkerr.pl b/lib/libcrypto/util/mkerr.pl
index 2c99467d340..aec401c7731 100644
--- a/lib/libcrypto/util/mkerr.pl
+++ b/lib/libcrypto/util/mkerr.pl
@@ -769,7 +769,7 @@ EOF
undef %err_reason_strings;
}
-if($debug && defined(%notrans)) {
+if($debug && %notrans) {
print STDERR "The following function codes were not translated:\n";
foreach(sort keys %notrans)
{
diff --git a/lib/libcrypto/x509/x509_vfy.c b/lib/libcrypto/x509/x509_vfy.c
index 5a0b0249b40..701ec565e93 100644
--- a/lib/libcrypto/x509/x509_vfy.c
+++ b/lib/libcrypto/x509/x509_vfy.c
@@ -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)
diff --git a/lib/libcrypto/x509v3/v3_addr.c b/lib/libcrypto/x509v3/v3_addr.c
index 0d70e8696d9..df46a4983be 100644
--- a/lib/libcrypto/x509v3/v3_addr.c
+++ b/lib/libcrypto/x509v3/v3_addr.c
@@ -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);
diff --git a/lib/libssl/d1_pkt.c b/lib/libssl/d1_pkt.c
index 39aac73e104..e0c0f0cc9a9 100644
--- a/lib/libssl/d1_pkt.c
+++ b/lib/libssl/d1_pkt.c
@@ -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)
{
diff --git a/lib/libssl/d1_srvr.c b/lib/libssl/d1_srvr.c
index a6a4c87ea64..149983be30f 100644
--- a/lib/libssl/d1_srvr.c
+++ b/lib/libssl/d1_srvr.c
@@ -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))
{
diff --git a/lib/libssl/doc/openssl.cnf b/lib/libssl/doc/openssl.cnf
index 9d2cd5bfa52..18760c6e673 100644
--- a/lib/libssl/doc/openssl.cnf
+++ b/lib/libssl/doc/openssl.cnf
@@ -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
diff --git a/lib/libssl/s3_clnt.c b/lib/libssl/s3_clnt.c
index 50bd415b568..53223bd38d1 100644
--- a/lib/libssl/s3_clnt.c
+++ b/lib/libssl/s3_clnt.c
@@ -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;
}
diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c
index 62c791cb724..1130244aeb6 100644
--- a/lib/libssl/s3_lib.c
+++ b/lib/libssl/s3_lib.c
@@ -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);
diff --git a/lib/libssl/s3_srvr.c b/lib/libssl/s3_srvr.c
index c3b5ff33ff8..d734c359fb2 100644
--- a/lib/libssl/s3_srvr.c
+++ b/lib/libssl/s3_srvr.c
@@ -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;
}
diff --git a/lib/libssl/ssl.h b/lib/libssl/ssl.h
index e4c3f650106..8f922eea72a 100644
--- a/lib/libssl/ssl.h
+++ b/lib/libssl/ssl.h
@@ -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
diff --git a/lib/libssl/ssl3.h b/lib/libssl/ssl3.h
index baaa89e7170..9c2c41287a5 100644
--- a/lib/libssl/ssl3.h
+++ b/lib/libssl/ssl3.h
@@ -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
{
diff --git a/lib/libssl/ssl_ciph.c b/lib/libssl/ssl_ciph.c
index a8ce186b783..54ba7ef5b4a 100644
--- a/lib/libssl/ssl_ciph.c
+++ b/lib/libssl/ssl_ciph.c
@@ -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();
}
diff --git a/lib/libssl/ssl_err.c b/lib/libssl/ssl_err.c
index 0eed4647491..e9be77109fd 100644
--- a/lib/libssl/ssl_err.c
+++ b/lib/libssl/ssl_err.c
@@ -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"},
diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c
index a3c9309488a..7755476de3b 100644
--- a/lib/libssl/ssl_lib.c
+++ b/lib/libssl/ssl_lib.c
@@ -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)
{
diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h
index 4c78393f3f7..cea622a2a69 100644
--- a/lib/libssl/ssl_locl.h
+++ b/lib/libssl/ssl_locl.h
@@ -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);
diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c
index 85371c87b8e..26cbae449e9 100644
--- a/lib/libssl/t1_lib.c
+++ b/lib/libssl/t1_lib.c
@@ -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);
diff --git a/lib/libssl/test/testssl b/lib/libssl/test/testssl
index f9d7c5d65ff..b55364ae888 100644
--- a/lib/libssl/test/testssl
+++ b/lib/libssl/test/testssl
@@ -100,8 +100,8 @@ echo test sslv2/sslv3 via BIO pair
$ssltest $extra || exit 1
if [ $dsa_cert = NO ]; then
- echo test sslv2/sslv3 w/o DHE via BIO pair
- $ssltest -bio_pair -no_dhe $extra || exit 1
+ echo 'test sslv2/sslv3 w/o (EC)DHE via BIO pair'
+ $ssltest -bio_pair -no_dhe -no_ecdhe $extra || exit 1
fi
echo test sslv2/sslv3 with 1024bit DHE via BIO pair
@@ -131,8 +131,8 @@ fi
if ../util/shlib_wrap.sh ../apps/openssl no-rsa; then
echo skipping RSA tests
else
- echo test tls1 with 1024bit RSA, no DHE, multiple handshakes
- ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -num 10 -f -time $extra || exit 1
+ echo 'test tls1 with 1024bit RSA, no (EC)DHE, multiple handshakes'
+ ../util/shlib_wrap.sh ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -no_ecdhe -num 10 -f -time $extra || exit 1
if ../util/shlib_wrap.sh ../apps/openssl no-dh; then
echo skipping RSA+DHE tests