summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2015-06-12 07:23:55 +0000
committerdelphij <delphij@FreeBSD.org>2015-06-12 07:23:55 +0000
commit17b1c22cf566ffc540a06c72a7e24903d70bdbbc (patch)
treeeaf6fd09e0241c3694090ffd493ceed2d38ba00d
parent1c7c9a70bbeba057be18a74724e6575871e447fb (diff)
downloadFreeBSD-src-17b1c22cf566ffc540a06c72a7e24903d70bdbbc.zip
FreeBSD-src-17b1c22cf566ffc540a06c72a7e24903d70bdbbc.tar.gz
Fix OpenSSL multiple vulnerabilities.
Security: FreeBSD-SA-15:10.openssl Approved by: so
-rw-r--r--UPDATING3
-rw-r--r--crypto/openssl/apps/dhparam.c4
-rw-r--r--crypto/openssl/apps/gendh.c2
-rw-r--r--crypto/openssl/apps/s_server.c103
-rw-r--r--crypto/openssl/crypto/bio/bio_lib.c8
-rw-r--r--crypto/openssl/crypto/bn/bn_gf2m.c16
-rw-r--r--crypto/openssl/crypto/bn/bn_print.c7
-rw-r--r--crypto/openssl/crypto/buffer/buffer.c2
-rw-r--r--crypto/openssl/crypto/cms/cms_smime.c2
-rw-r--r--crypto/openssl/crypto/ec/ec2_oct.c3
-rw-r--r--crypto/openssl/crypto/ec/ec_check.c2
-rw-r--r--crypto/openssl/crypto/ec/ec_key.c2
-rw-r--r--crypto/openssl/crypto/ec/ec_lib.c10
-rw-r--r--crypto/openssl/crypto/ec/ecp_oct.c3
-rw-r--r--crypto/openssl/crypto/ec/ectest.c24
-rw-r--r--crypto/openssl/crypto/evp/e_aes.c5
-rw-r--r--crypto/openssl/crypto/evp/e_rc4_hmac_md5.c3
-rw-r--r--crypto/openssl/crypto/evp/evp.h1
-rw-r--r--crypto/openssl/crypto/hmac/hmac.c1
-rw-r--r--crypto/openssl/crypto/modes/gcm128.c2
-rw-r--r--crypto/openssl/crypto/objects/obj_dat.c3
-rw-r--r--crypto/openssl/crypto/pkcs12/p12_mutl.c4
-rw-r--r--crypto/openssl/crypto/pkcs7/pk7_doit.c8
-rw-r--r--crypto/openssl/crypto/x509/x509_vfy.c150
-rw-r--r--crypto/openssl/crypto/x509/x509type.c3
-rw-r--r--crypto/openssl/doc/apps/dhparam.pod13
-rw-r--r--crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod106
-rw-r--r--crypto/openssl/ssl/d1_both.c33
-rw-r--r--crypto/openssl/ssl/d1_lib.c3
-rw-r--r--crypto/openssl/ssl/d1_pkt.c2
-rw-r--r--crypto/openssl/ssl/s3_cbc.c2
-rw-r--r--crypto/openssl/ssl/s3_clnt.c165
-rw-r--r--crypto/openssl/ssl/s3_srvr.c21
-rw-r--r--crypto/openssl/ssl/ssl.h2
-rw-r--r--crypto/openssl/ssl/ssl_err.c2
-rw-r--r--crypto/openssl/ssl/ssl_locl.h1
-rw-r--r--crypto/openssl/ssl/ssl_sess.c124
-rw-r--r--crypto/openssl/ssl/t1_lib.c133
-rw-r--r--sys/conf/newvers.sh2
39 files changed, 619 insertions, 361 deletions
diff --git a/UPDATING b/UPDATING
index f4ec148..d06f8a9 100644
--- a/UPDATING
+++ b/UPDATING
@@ -16,6 +16,9 @@ from older versions of FreeBSD, try WITHOUT_CLANG to bootstrap to the tip of
stable/10, and then rebuild without this option. The bootstrap process from
older version of current is a bit fragile.
+20150612: p12 FreeBSD-SA-15:10.openssl
+ Fix multiple vulnerabilities in OpenSSL. [SA-15:10]
+
20150609: p11 FreeBSD-EN-15:06.file
FreeBSD-EN-15:07.zfs
diff --git a/crypto/openssl/apps/dhparam.c b/crypto/openssl/apps/dhparam.c
index 1297d6f..b0c05be 100644
--- a/crypto/openssl/apps/dhparam.c
+++ b/crypto/openssl/apps/dhparam.c
@@ -130,7 +130,7 @@
#undef PROG
#define PROG dhparam_main
-#define DEFBITS 512
+#define DEFBITS 2048
/* -inform arg - input format - default PEM (DER or PEM)
* -outform arg - output format - default PEM
@@ -253,7 +253,7 @@ bad:
BIO_printf(bio_err," -C Output C code\n");
BIO_printf(bio_err," -2 generate parameters using 2 as the generator value\n");
BIO_printf(bio_err," -5 generate parameters using 5 as the generator value\n");
- BIO_printf(bio_err," numbits number of bits in to generate (default 512)\n");
+ BIO_printf(bio_err," numbits number of bits in to generate (default 2048)\n");
#ifndef OPENSSL_NO_ENGINE
BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
#endif
diff --git a/crypto/openssl/apps/gendh.c b/crypto/openssl/apps/gendh.c
index 4ec776b..8df8c62 100644
--- a/crypto/openssl/apps/gendh.c
+++ b/crypto/openssl/apps/gendh.c
@@ -78,7 +78,7 @@
#include <openssl/x509.h>
#include <openssl/pem.h>
-#define DEFBITS 512
+#define DEFBITS 2048
#undef PROG
#define PROG gendh_main
diff --git a/crypto/openssl/apps/s_server.c b/crypto/openssl/apps/s_server.c
index f47328a..7586314 100644
--- a/crypto/openssl/apps/s_server.c
+++ b/crypto/openssl/apps/s_server.c
@@ -214,7 +214,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
unsigned int *id_len);
#ifndef OPENSSL_NO_DH
static DH *load_dh_param(const char *dhfile);
-static DH *get_dh512(void);
+static DH *get_dh2048(void);
#endif
#ifdef MONOLITH
@@ -222,29 +222,49 @@ static void s_server_init(void);
#endif
#ifndef OPENSSL_NO_DH
-static unsigned char dh512_p[]={
- 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
- 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
- 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
- 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
- 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
- 0x47,0x74,0xE8,0x33,
- };
-static unsigned char dh512_g[]={
+static unsigned char dh2048_p[] = {
+ 0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
+ 0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
+ 0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
+ 0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
+ 0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
+ 0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
+ 0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
+ 0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
+ 0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
+ 0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
+ 0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
+ 0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
+ 0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
+ 0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
+ 0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
+ 0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
+ 0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
+ 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
+ 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
+ 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
+ 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
+ 0xE9,0x32,0x0B,0x3B,
+};
+
+static unsigned char dh2048_g[] = {
0x02,
- };
+};
-static DH *get_dh512(void)
- {
- DH *dh=NULL;
-
- if ((dh=DH_new()) == NULL) return(NULL);
- dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
- dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
- if ((dh->p == NULL) || (dh->g == NULL))
- return(NULL);
- return(dh);
+DH *get_dh2048()
+{
+ DH *dh;
+
+ if ((dh = DH_new()) == NULL)
+ return NULL;
+ dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+ dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+ if (dh->p == NULL || dh->g == NULL) {
+ DH_free(dh);
+ return NULL;
}
+ return dh;
+}
#endif
@@ -1661,45 +1681,42 @@ bad:
#endif
#ifndef OPENSSL_NO_DH
- if (!no_dhe)
- {
- DH *dh=NULL;
+ if (!no_dhe) {
+ DH *dh = NULL;
if (dhfile)
dh = load_dh_param(dhfile);
else if (s_cert_file)
dh = load_dh_param(s_cert_file);
- if (dh != NULL)
- {
- BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+ if (dh != NULL) {
+ BIO_printf(bio_s_out, "Setting temp DH parameters\n");
+ } else {
+ BIO_printf(bio_s_out, "Using default temp DH parameters\n");
+ dh = get_dh2048();
+ if (dh == NULL) {
+ ERR_print_errors(bio_err);
+ goto end;
}
- else
- {
- BIO_printf(bio_s_out,"Using default temp DH parameters\n");
- dh=get_dh512();
}
(void)BIO_flush(bio_s_out);
- SSL_CTX_set_tmp_dh(ctx,dh);
-#ifndef OPENSSL_NO_TLSEXT
- if (ctx2)
- {
- if (!dhfile)
- {
- DH *dh2=load_dh_param(s_cert_file2);
- if (dh2 != NULL)
- {
- BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+ SSL_CTX_set_tmp_dh(ctx, dh);
+# ifndef OPENSSL_NO_TLSEXT
+ if (ctx2) {
+ if (!dhfile) {
+ DH *dh2 = load_dh_param(s_cert_file2);
+ if (dh2 != NULL) {
+ BIO_printf(bio_s_out, "Setting temp DH parameters\n");
(void)BIO_flush(bio_s_out);
DH_free(dh);
dh = dh2;
}
}
- SSL_CTX_set_tmp_dh(ctx2,dh);
+ SSL_CTX_set_tmp_dh(ctx2, dh);
}
-#endif
+# endif
DH_free(dh);
}
#endif
diff --git a/crypto/openssl/crypto/bio/bio_lib.c b/crypto/openssl/crypto/bio/bio_lib.c
index 4793a45..c977323 100644
--- a/crypto/openssl/crypto/bio/bio_lib.c
+++ b/crypto/openssl/crypto/bio/bio_lib.c
@@ -543,8 +543,10 @@ BIO *BIO_dup_chain(BIO *in)
/* copy app data */
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
- &bio->ex_data))
+ &bio->ex_data)) {
+ BIO_free(new_bio);
goto err;
+ }
if (ret == NULL)
{
@@ -559,8 +561,8 @@ BIO *BIO_dup_chain(BIO *in)
}
return(ret);
err:
- if (ret != NULL)
- BIO_free(ret);
+ BIO_free_all(ret);
+
return(NULL);
}
diff --git a/crypto/openssl/crypto/bn/bn_gf2m.c b/crypto/openssl/crypto/bn/bn_gf2m.c
index 8a4dc20..bda2aa6 100644
--- a/crypto/openssl/crypto/bn/bn_gf2m.c
+++ b/crypto/openssl/crypto/bn/bn_gf2m.c
@@ -568,10 +568,11 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
}
#else
{
- int i, ubits = BN_num_bits(u),
- vbits = BN_num_bits(v), /* v is copy of p */
- top = p->top;
- BN_ULONG *udp,*bdp,*vdp,*cdp;
+ int i;
+ int ubits = BN_num_bits(u);
+ int vbits = BN_num_bits(v); /* v is copy of p */
+ int top = p->top;
+ BN_ULONG *udp, *bdp, *vdp, *cdp;
bn_wexpand(u,top); udp = u->d;
for (i=u->top;i<top;i++) udp[i] = 0;
@@ -611,7 +612,12 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
ubits--;
}
- if (ubits<=BN_BITS2 && udp[0]==1) break;
+ if (ubits <= BN_BITS2) {
+ if (udp[0] == 0) /* poly was reducible */
+ goto err;
+ if (udp[0] == 1)
+ break;
+ }
if (ubits<vbits)
{
diff --git a/crypto/openssl/crypto/bn/bn_print.c b/crypto/openssl/crypto/bn/bn_print.c
index 1743b6a..3dde470 100644
--- a/crypto/openssl/crypto/bn/bn_print.c
+++ b/crypto/openssl/crypto/bn/bn_print.c
@@ -71,7 +71,12 @@ char *BN_bn2hex(const BIGNUM *a)
char *buf;
char *p;
- buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
+ if (a->neg && BN_is_zero(a)) {
+ /* "-0" == 3 bytes including NULL terminator */
+ buf = OPENSSL_malloc(3);
+ } else {
+ buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+ }
if (buf == NULL)
{
BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
diff --git a/crypto/openssl/crypto/buffer/buffer.c b/crypto/openssl/crypto/buffer/buffer.c
index d4a4ce4..8ae456c 100644
--- a/crypto/openssl/crypto/buffer/buffer.c
+++ b/crypto/openssl/crypto/buffer/buffer.c
@@ -88,7 +88,7 @@ void BUF_MEM_free(BUF_MEM *a)
if (a->data != NULL)
{
- memset(a->data,0,(unsigned int)a->max);
+ OPENSSL_cleanse(a->data, a->max);
OPENSSL_free(a->data);
}
OPENSSL_free(a);
diff --git a/crypto/openssl/crypto/cms/cms_smime.c b/crypto/openssl/crypto/cms/cms_smime.c
index 1af9f3a..1d7725c 100644
--- a/crypto/openssl/crypto/cms/cms_smime.c
+++ b/crypto/openssl/crypto/cms/cms_smime.c
@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *upto)
BIO_free(f);
f = tbio;
}
- while (f != upto);
+ while (f && f != upto);
}
else
BIO_free_all(f);
diff --git a/crypto/openssl/crypto/ec/ec2_oct.c b/crypto/openssl/crypto/ec/ec2_oct.c
index f1d75e5..91f13e9 100644
--- a/crypto/openssl/crypto/ec/ec2_oct.c
+++ b/crypto/openssl/crypto/ec/ec2_oct.c
@@ -390,7 +390,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
}
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ /* test required by X9.62 */
+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
diff --git a/crypto/openssl/crypto/ec/ec_check.c b/crypto/openssl/crypto/ec/ec_check.c
index 0e316b4..5ff7b28 100644
--- a/crypto/openssl/crypto/ec/ec_check.c
+++ b/crypto/openssl/crypto/ec/ec_check.c
@@ -88,7 +88,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
goto err;
}
- if (!EC_POINT_is_on_curve(group, group->generator, ctx))
+ if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0)
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
diff --git a/crypto/openssl/crypto/ec/ec_key.c b/crypto/openssl/crypto/ec/ec_key.c
index 7fa2475..577e45a 100644
--- a/crypto/openssl/crypto/ec/ec_key.c
+++ b/crypto/openssl/crypto/ec/ec_key.c
@@ -326,7 +326,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
goto err;
/* testing whether the pub_key is on the elliptic curve */
- if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
+ if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0)
{
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
diff --git a/crypto/openssl/crypto/ec/ec_lib.c b/crypto/openssl/crypto/ec/ec_lib.c
index 0992c39..37be9e9 100644
--- a/crypto/openssl/crypto/ec/ec_lib.c
+++ b/crypto/openssl/crypto/ec/ec_lib.c
@@ -972,7 +972,15 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
}
-int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+/*
+ * Check whether an EC_POINT is on the curve or not. Note that the return
+ * value for this function should NOT be treated as a boolean. Return values:
+ * 1: The point is on the curve
+ * 0: The point is not on the curve
+ * -1: An error occurred
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx)
{
if (group->meth->is_on_curve == 0)
{
diff --git a/crypto/openssl/crypto/ec/ecp_oct.c b/crypto/openssl/crypto/ec/ecp_oct.c
index 374a0ee..2e785b0 100644
--- a/crypto/openssl/crypto/ec/ecp_oct.c
+++ b/crypto/openssl/crypto/ec/ecp_oct.c
@@ -416,7 +416,8 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
}
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ /* test required by X9.62 */
+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0)
{
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
diff --git a/crypto/openssl/crypto/ec/ectest.c b/crypto/openssl/crypto/ec/ectest.c
index 8e4154d..1ac60e1 100644
--- a/crypto/openssl/crypto/ec/ectest.c
+++ b/crypto/openssl/crypto/ec/ectest.c
@@ -343,7 +343,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, "D")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, Q, ctx))
+ if (EC_POINT_is_on_curve(group, Q, ctx) <= 0)
{
if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
fprintf(stderr, "Point is not on curve: x = 0x");
@@ -439,7 +439,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -473,7 +473,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -507,7 +507,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -541,7 +541,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
"84F3B9CAC2FC632551")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -580,7 +580,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -624,7 +624,7 @@ static void prime_field_tests(void)
"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
"3C1856A429BF97E7E31C2E5BD66")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
"C9B8899C47AEBB6FB71E91386409")) ABORT;
@@ -657,7 +657,7 @@ static void prime_field_tests(void)
if (!EC_POINT_copy(Q, P)) ABORT;
if (EC_POINT_is_at_infinity(group, Q)) ABORT;
if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
@@ -771,7 +771,7 @@ static void prime_field_tests(void)
#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
if (!BN_hex2bn(&x, _x)) ABORT; \
if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
if (!BN_hex2bn(&z, _order)) ABORT; \
if (!BN_hex2bn(&cof, _cof)) ABORT; \
if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
@@ -789,7 +789,7 @@ static void prime_field_tests(void)
if (!BN_hex2bn(&x, _x)) ABORT; \
if (!BN_hex2bn(&y, _y)) ABORT; \
if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
if (!BN_hex2bn(&z, _order)) ABORT; \
if (!BN_hex2bn(&cof, _cof)) ABORT; \
if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
@@ -894,7 +894,7 @@ static void char2_field_tests(void)
if (!BN_hex2bn(&y, "8")) ABORT;
if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
#endif
- if (!EC_POINT_is_on_curve(group, Q, ctx))
+ if (EC_POINT_is_on_curve(group, Q, ctx) <= 0)
{
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
@@ -1133,7 +1133,7 @@ static void char2_field_tests(void)
if (!EC_POINT_copy(Q, P)) ABORT;
if (EC_POINT_is_at_infinity(group, Q)) ABORT;
if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
diff --git a/crypto/openssl/crypto/evp/e_aes.c b/crypto/openssl/crypto/evp/e_aes.c
index dc3c2a1..e62fcc7 100644
--- a/crypto/openssl/crypto/evp/e_aes.c
+++ b/crypto/openssl/crypto/evp/e_aes.c
@@ -50,6 +50,7 @@
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_AES
+#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
@@ -967,7 +968,7 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
EVP_GCM_TLS_TAG_LEN);
/* If tag mismatch wipe buffer */
- if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
+ if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
{
OPENSSL_cleanse(out, len);
goto err;
@@ -1351,7 +1352,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
unsigned char tag[16];
if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
{
- if (!memcmp(tag, ctx->buf, cctx->M))
+ if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M))
rv = len;
}
}
diff --git a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c
index 5656319..a70ed2e 100644
--- a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c
+++ b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c
@@ -54,6 +54,7 @@
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rc4.h>
@@ -205,7 +206,7 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH);
MD5_Final(mac,&key->md);
- if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH))
+ if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
return 0;
} else {
MD5_Update(&key->md,out+md5_off,len-md5_off);
diff --git a/crypto/openssl/crypto/evp/evp.h b/crypto/openssl/crypto/evp/evp.h
index faeb3c2..bbd51fe 100644
--- a/crypto/openssl/crypto/evp/evp.h
+++ b/crypto/openssl/crypto/evp/evp.h
@@ -103,7 +103,6 @@
#define EVP_PKS_RSA 0x0100
#define EVP_PKS_DSA 0x0200
#define EVP_PKS_EC 0x0400
-#define EVP_PKT_EXP 0x1000 /* <= 512 bit key */
#define EVP_PKEY_NONE NID_undef
#define EVP_PKEY_RSA NID_rsaEncryption
diff --git a/crypto/openssl/crypto/hmac/hmac.c b/crypto/openssl/crypto/hmac/hmac.c
index ba27cbf..70375ee 100644
--- a/crypto/openssl/crypto/hmac/hmac.c
+++ b/crypto/openssl/crypto/hmac/hmac.c
@@ -240,6 +240,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
HMAC_CTX_cleanup(&c);
return md;
err:
+ HMAC_CTX_cleanup(&c);
return NULL;
}
diff --git a/crypto/openssl/crypto/modes/gcm128.c b/crypto/openssl/crypto/modes/gcm128.c
index e1dc2b0..2cf83b1 100644
--- a/crypto/openssl/crypto/modes/gcm128.c
+++ b/crypto/openssl/crypto/modes/gcm128.c
@@ -1525,7 +1525,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
ctx->Xi.u[1] ^= ctx->EK0.u[1];
if (tag && len<=sizeof(ctx->Xi))
- return memcmp(ctx->Xi.c,tag,len);
+ return CRYPTO_memcmp(ctx->Xi.c, tag, len);
else
return -1;
}
diff --git a/crypto/openssl/crypto/objects/obj_dat.c b/crypto/openssl/crypto/objects/obj_dat.c
index 0b2f442..1783233 100644
--- a/crypto/openssl/crypto/objects/obj_dat.c
+++ b/crypto/openssl/crypto/objects/obj_dat.c
@@ -405,6 +405,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a)
if (a->nid != 0)
return(a->nid);
+ if (a->length == 0)
+ return NID_undef;
+
if (added != NULL)
{
ad.type=ADDED_DATA;
diff --git a/crypto/openssl/crypto/pkcs12/p12_mutl.c b/crypto/openssl/crypto/pkcs12/p12_mutl.c
index 96de1bd..53ab750 100644
--- a/crypto/openssl/crypto/pkcs12/p12_mutl.c
+++ b/crypto/openssl/crypto/pkcs12/p12_mutl.c
@@ -59,6 +59,7 @@
#ifndef OPENSSL_NO_HMAC
#include <stdio.h>
#include "cryptlib.h"
+#include <openssl/crypto.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/pkcs12.h>
@@ -123,7 +124,8 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
return 0;
}
if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
- || memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0;
+ || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen))
+ return 0;
return 1;
}
diff --git a/crypto/openssl/crypto/pkcs7/pk7_doit.c b/crypto/openssl/crypto/pkcs7/pk7_doit.c
index 5eb2a5b..7b138ca 100644
--- a/crypto/openssl/crypto/pkcs7/pk7_doit.c
+++ b/crypto/openssl/crypto/pkcs7/pk7_doit.c
@@ -504,6 +504,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
goto err;
}
+ /* Detached content must be supplied via in_bio instead. */
+ if (data_body == NULL && in_bio == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ goto err;
+ }
+
/* We will be checking the signature */
if (md_sk != NULL)
{
@@ -660,7 +666,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
}
#if 1
- if (PKCS7_is_detached(p7) || (in_bio != NULL))
+ if (in_bio != NULL)
{
bio=in_bio;
}
diff --git a/crypto/openssl/crypto/x509/x509_vfy.c b/crypto/openssl/crypto/x509/x509_vfy.c
index 920066a..d68ea4b 100644
--- a/crypto/openssl/crypto/x509/x509_vfy.c
+++ b/crypto/openssl/crypto/x509/x509_vfy.c
@@ -1679,83 +1679,121 @@ int X509_cmp_current_time(const ASN1_TIME *ctm)
}
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
- {
+{
char *str;
ASN1_TIME atm;
long offset;
- char buff1[24],buff2[24],*p;
- int i,j;
-
- p=buff1;
- i=ctm->length;
- str=(char *)ctm->data;
- if (ctm->type == V_ASN1_UTCTIME)
- {
- if ((i < 11) || (i > 17)) return 0;
- memcpy(p,str,10);
- p+=10;
- str+=10;
- }
- else
- {
- if (i < 13) return 0;
- memcpy(p,str,12);
- p+=12;
- str+=12;
- }
-
- if ((*str == 'Z') || (*str == '-') || (*str == '+'))
- { *(p++)='0'; *(p++)='0'; }
- else
- {
- *(p++)= *(str++);
- *(p++)= *(str++);
- /* Skip any fractional seconds... */
- if (*str == '.')
- {
+ char buff1[24], buff2[24], *p;
+ int i, j, remaining;
+
+ p = buff1;
+ remaining = ctm->length;
+ str = (char *)ctm->data;
+ /*
+ * Note that the following (historical) code allows much more slack in the
+ * time format than RFC5280. In RFC5280, the representation is fixed:
+ * UTCTime: YYMMDDHHMMSSZ
+ * GeneralizedTime: YYYYMMDDHHMMSSZ
+ */
+ if (ctm->type == V_ASN1_UTCTIME) {
+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+ int min_length = sizeof("YYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
+ memcpy(p, str, 10);
+ p += 10;
+ str += 10;
+ remaining -= 10;
+ } else {
+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
+ memcpy(p, str, 12);
+ p += 12;
+ str += 12;
+ remaining -= 12;
+ }
+
+ if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
+ *(p++) = '0';
+ *(p++) = '0';
+ } else {
+ /* SS (seconds) */
+ if (remaining < 2)
+ return 0;
+ *(p++) = *(str++);
+ *(p++) = *(str++);
+ remaining -= 2;
+ /*
+ * Skip any (up to three) fractional seconds...
+ * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+ * Can we just kill them altogether?
+ */
+ if (remaining && *str == '.') {
str++;
- while ((*str >= '0') && (*str <= '9')) str++;
+ remaining--;
+ for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
+ if (*str < '0' || *str > '9')
+ break;
}
-
}
- *(p++)='Z';
- *(p++)='\0';
- if (*str == 'Z')
- offset=0;
- else
- {
+ }
+ *(p++) = 'Z';
+ *(p++) = '\0';
+
+ /* We now need either a terminating 'Z' or an offset. */
+ if (!remaining)
+ return 0;
+ if (*str == 'Z') {
+ if (remaining != 1)
+ return 0;
+ offset = 0;
+ } else {
+ /* (+-)HHMM */
if ((*str != '+') && (*str != '-'))
return 0;
- offset=((str[1]-'0')*10+(str[2]-'0'))*60;
- offset+=(str[3]-'0')*10+(str[4]-'0');
+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+ if (remaining != 5)
+ return 0;
+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+ return 0;
+ offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
+ offset += (str[3] - '0') * 10 + (str[4] - '0');
if (*str == '-')
- offset= -offset;
+ offset = -offset;
}
- atm.type=ctm->type;
+ atm.type = ctm->type;
atm.flags = 0;
- atm.length=sizeof(buff2);
- atm.data=(unsigned char *)buff2;
+ 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)
- {
- i=(buff1[0]-'0')*10+(buff1[1]-'0');
- if (i < 50) i+=100; /* cf. RFC 2459 */
- j=(buff2[0]-'0')*10+(buff2[1]-'0');
- if (j < 50) j+=100;
+ if (ctm->type == V_ASN1_UTCTIME) {
+ i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
+ if (i < 50)
+ i += 100; /* cf. RFC 2459 */
+ j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
+ if (j < 50)
+ j += 100;
- if (i < j) return -1;
- if (i > j) return 1;
+ if (i < j)
+ return -1;
+ if (i > j)
+ return 1;
}
- i=strcmp(buff1,buff2);
+ i = strcmp(buff1, buff2);
if (i == 0) /* wait a second then return younger :-) */
return -1;
else
return i;
- }
+}
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
{
diff --git a/crypto/openssl/crypto/x509/x509type.c b/crypto/openssl/crypto/x509/x509type.c
index 9702ec5..e2bd51a 100644
--- a/crypto/openssl/crypto/x509/x509type.c
+++ b/crypto/openssl/crypto/x509/x509type.c
@@ -122,9 +122,6 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
}
}
- if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look
- for, not bytes */
- ret|=EVP_PKT_EXP;
if(pkey==NULL) EVP_PKEY_free(pk);
return(ret);
}
diff --git a/crypto/openssl/doc/apps/dhparam.pod b/crypto/openssl/doc/apps/dhparam.pod
index 6e27cf5..1cd4c76 100644
--- a/crypto/openssl/doc/apps/dhparam.pod
+++ b/crypto/openssl/doc/apps/dhparam.pod
@@ -71,8 +71,10 @@ check if the parameters are valid primes and generator.
=item B<-2>, B<-5>
-The generator to use, either 2 or 5. 2 is the default. If present then the
-input file is ignored and parameters are generated instead.
+The generator to use, either 2 or 5. If present then the
+input file is ignored and parameters are generated instead. If not
+present but B<numbits> is present, parameters are generated with the
+default generator 2.
=item B<-rand> I<file(s)>
@@ -85,9 +87,10 @@ all others.
=item I<numbits>
this option specifies that a parameter set should be generated of size
-I<numbits>. It must be the last option. If not present then a value of 512
-is used. If this option is present then the input file is ignored and
-parameters are generated instead.
+I<numbits>. It must be the last option. If this option is present then
+the input file is ignored and parameters are generated instead. If
+this option is not present but a generator (B<-2> or B<-5>) is
+present, parameters are generated with a default length of 2048 bits.
=item B<-noout>
diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
index 7a27eef..b754c16 100644
--- a/crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
+++ b/crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
@@ -61,12 +61,12 @@ negotiation is being saved.
If "strong" primes were used to generate the DH parameters, it is not strictly
necessary to generate a new key for each handshake but it does improve forward
-secrecy. If it is not assured, that "strong" primes were used (see especially
-the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used
-in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE
-has an impact on the computer time needed during negotiation, but it is not
-very large, so application authors/users should consider to always enable
-this option.
+secrecy. If it is not assured that "strong" primes were used,
+SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup
+attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the
+computer time needed during negotiation, but it is not very large, so
+application authors/users should consider always enabling this option.
+The option is required to implement perfect forward secrecy (PFS).
As generating DH parameters is extremely time consuming, an application
should not generate the parameters on the fly but supply the parameters.
@@ -74,82 +74,62 @@ DH parameters can be reused, as the actual key is newly generated during
the negotiation. The risk in reusing DH parameters is that an attacker
may specialize on a very often used DH group. Applications should therefore
generate their own DH parameters during the installation process using the
-openssl L<dhparam(1)|dhparam(1)> application. In order to reduce the computer
-time needed for this generation, it is possible to use DSA parameters
-instead (see L<dhparam(1)|dhparam(1)>), but in this case SSL_OP_SINGLE_DH_USE
-is mandatory.
+openssl L<dhparam(1)|dhparam(1)> application. This application
+guarantees that "strong" primes are used.
-Application authors may compile in DH parameters. Files dh512.pem,
-dh1024.pem, dh2048.pem, and dh4096.pem in the 'apps' directory of current
+Files dh2048.pem, and dh4096.pem in the 'apps' directory of the current
version of the OpenSSL distribution contain the 'SKIP' DH parameters,
which use safe primes and were generated verifiably pseudo-randomly.
These files can be converted into C code using the B<-C> option of the
-L<dhparam(1)|dhparam(1)> application.
-Authors may also generate their own set of parameters using
-L<dhparam(1)|dhparam(1)>, but a user may not be sure how the parameters were
-generated. The generation of DH parameters during installation is therefore
-recommended.
+L<dhparam(1)|dhparam(1)> application. Generation of custom DH
+parameters during installation should still be preferred to stop an
+attacker from specializing on a commonly used group. Files dh1024.pem
+and dh512.pem contain old parameters that must not be used by
+applications.
An application may either directly specify the DH parameters or
-can supply the DH parameters via a callback function. The callback approach
-has the advantage, that the callback may supply DH parameters for different
-key lengths.
+can supply the DH parameters via a callback function.
-The B<tmp_dh_callback> is called with the B<keylength> needed and
-the B<is_export> information. The B<is_export> flag is set, when the
-ephemeral DH key exchange is performed with an export cipher.
+Previous versions of the callback used B<is_export> and B<keylength>
+parameters to control parameter generation for export and non-export
+cipher suites. Modern servers that do not support export ciphersuites
+are advised to either use SSL_CTX_set_tmp_dh() in combination with
+SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore
+B<keylength> and B<is_export> and simply supply at least 2048-bit
+parameters in the callback.
=head1 EXAMPLES
-Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling
+Setup DH parameters with a key length of 2048 bits. (Error handling
partly left out.)
- ...
- /* Set up ephemeral DH stuff */
- DH *dh_512 = NULL;
- DH *dh_1024 = NULL;
- FILE *paramfile;
+ Command-line parameter generation:
+ $ openssl dhparam -out dh_param_2048.pem 2048
+
+ Code for setting up parameters during server initialization:
...
- /* "openssl dhparam -out dh_param_512.pem -2 512" */
- paramfile = fopen("dh_param_512.pem", "r");
+ SSL_CTX ctx = SSL_CTX_new();
+ ...
+
+ /* Set up ephemeral DH parameters. */
+ DH *dh_2048 = NULL;
+ FILE *paramfile;
+ paramfile = fopen("dh_param_2048.pem", "r");
if (paramfile) {
- dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
+ dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
fclose(paramfile);
+ } else {
+ /* Error. */
}
- /* "openssl dhparam -out dh_param_1024.pem -2 1024" */
- paramfile = fopen("dh_param_1024.pem", "r");
- if (paramfile) {
- dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
- fclose(paramfile);
+ if (dh_2048 == NULL) {
+ /* Error. */
}
- ...
-
- /* "openssl dhparam -C -2 512" etc... */
- DH *get_dh512() { ... }
- DH *get_dh1024() { ... }
-
- DH *tmp_dh_callback(SSL *s, int is_export, int keylength)
- {
- DH *dh_tmp=NULL;
-
- switch (keylength) {
- case 512:
- if (!dh_512)
- dh_512 = get_dh512();
- dh_tmp = dh_512;
- break;
- case 1024:
- if (!dh_1024)
- dh_1024 = get_dh1024();
- dh_tmp = dh_1024;
- break;
- default:
- /* Generating a key on the fly is very costly, so use what is there */
- setup_dh_parameters_like_above();
- }
- return(dh_tmp);
+ if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) {
+ /* Error. */
}
+ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
+ ...
=head1 RETURN VALUES
diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c
index 1b9d64b..f08bf36 100644
--- a/crypto/openssl/ssl/d1_both.c
+++ b/crypto/openssl/ssl/d1_both.c
@@ -481,6 +481,12 @@ again:
else if ( i <= 0 && !*ok)
return i;
+ if (mt >= 0 && s->s3->tmp.message_type != mt) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
+ goto f_err;
+ }
+
p = (unsigned char *)s->init_buf->data;
msg_len = msg_hdr->msg_len;
@@ -869,6 +875,20 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
/* parse the message fragment header */
dtls1_get_message_header(wire, &msg_hdr);
+ len = msg_hdr.msg_len;
+ frag_off = msg_hdr.frag_off;
+ frag_len = msg_hdr.frag_len;
+
+ /*
+ * We must have at least frag_len bytes left in the record to be read.
+ * Fragments must not span records.
+ */
+ if (frag_len > s->s3->rrec.length) {
+ al = SSL3_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH);
+ goto f_err;
+ }
+
/*
* if this is a future (or stale) message it gets buffered
* (or dropped)--no further processing at this time
@@ -878,10 +898,6 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1))
return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
- len = msg_hdr.msg_len;
- frag_off = msg_hdr.frag_off;
- frag_len = msg_hdr.frag_len;
-
if (frag_len && frag_len < len)
return dtls1_reassemble_fragment(s, &msg_hdr, ok);
@@ -913,16 +929,16 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
goto f_err;
- /* XDTLS: ressurect this when restart is in place */
- s->state=stn;
-
if ( frag_len > 0)
{
unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
&p[frag_off],frag_len,0);
- /* XDTLS: fix this--message fragments cannot span multiple packets */
+ /*
+ * This shouldn't ever fail due to NBIO because we already checked
+ * that we have enough data in the record
+ */
if (i <= 0)
{
s->rwstate=SSL_READING;
@@ -943,6 +959,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
}
*ok = 1;
+ s->state = stn;
/* Note that s->init_num is *not* used as current offset in
* s->init_buf->data, but as a counter summing up fragments'
diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c
index 14337b31..48de079 100644
--- a/crypto/openssl/ssl/d1_lib.c
+++ b/crypto/openssl/ssl/d1_lib.c
@@ -509,6 +509,9 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
{
int ret;
+ /* Ensure there is no state left over from a previous invocation */
+ SSL_clear(s);
+
SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
s->d1->listen = 1;
diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c
index 0059fe2..bce8619 100644
--- a/crypto/openssl/ssl/d1_pkt.c
+++ b/crypto/openssl/ssl/d1_pkt.c
@@ -1056,7 +1056,7 @@ start:
{
al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
- goto err;
+ goto f_err;
}
/* no need to check sequence number on HELLO REQUEST messages */
diff --git a/crypto/openssl/ssl/s3_cbc.c b/crypto/openssl/ssl/s3_cbc.c
index 11f13ad..e850e3e 100644
--- a/crypto/openssl/ssl/s3_cbc.c
+++ b/crypto/openssl/ssl/s3_cbc.c
@@ -143,7 +143,7 @@ int tls1_cbc_remove_padding(const SSL* s,
if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand)
{
/* First packet is even in size, so check */
- if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) &&
+ if ((CRYPTO_memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) &&
!(padding_length & 1))
{
s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index 7692716..8628f1c 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -1606,6 +1606,13 @@ int ssl3_get_key_exchange(SSL *s)
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
goto err;
}
+
+ if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
+ goto f_err;
+ }
+
s->session->sess_cert->peer_rsa_tmp=rsa;
rsa=NULL;
}
@@ -2190,7 +2197,39 @@ int ssl3_get_new_session_ticket(SSL *s)
goto f_err;
}
- p=d=(unsigned char *)s->init_msg;
+ p = d = (unsigned char *)s->init_msg;
+
+ if (s->session->session_id_length > 0) {
+ int i = s->session_ctx->session_cache_mode;
+ SSL_SESSION *new_sess;
+ /*
+ * We reused an existing session, so we need to replace it with a new
+ * one
+ */
+ if (i & SSL_SESS_CACHE_CLIENT) {
+ /*
+ * Remove the old session from the cache
+ */
+ if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) {
+ if (s->session_ctx->remove_session_cb != NULL)
+ s->session_ctx->remove_session_cb(s->session_ctx,
+ s->session);
+ } else {
+ /* We carry on if this fails */
+ SSL_CTX_remove_session(s->session_ctx, s->session);
+ }
+ }
+
+ if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+
+ SSL_SESSION_free(s->session);
+ s->session = new_sess;
+ }
+
n2l(p, s->session->tlsext_tick_lifetime_hint);
n2s(p, ticklen);
/* ticket_lifetime_hint + ticket_length + ticket */
@@ -3319,6 +3358,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
int i,idx;
long alg_k,alg_a;
EVP_PKEY *pkey=NULL;
+ int pkey_bits;
SESS_CERT *sc;
#ifndef OPENSSL_NO_RSA
RSA *rsa;
@@ -3326,6 +3366,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
#ifndef OPENSSL_NO_DH
DH *dh;
#endif
+ int al = SSL_AD_HANDSHAKE_FAILURE;
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
alg_a=s->s3->tmp.new_cipher->algorithm_auth;
@@ -3367,6 +3408,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
}
#endif
pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);
+ pkey_bits = EVP_PKEY_bits(pkey);
i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);
EVP_PKEY_free(pkey);
@@ -3385,71 +3427,108 @@ int ssl3_check_cert_and_algorithm(SSL *s)
}
#endif
#ifndef OPENSSL_NO_RSA
- if ((alg_k & SSL_kRSA) &&
- !(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL)))
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+ if (alg_k & SSL_kRSA) {
+ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+ !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_RSA_ENCRYPTING_CERT);
goto f_err;
- }
+ } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
+ if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+ if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+ goto f_err;
+ }
+ if (rsa != NULL) {
+ /* server key exchange is not allowed. */
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ }
+ }
+ }
#endif
#ifndef OPENSSL_NO_DH
- if ((alg_k & SSL_kEDH) &&
- !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
+ if ((alg_k & SSL_kEDH) && dh == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
goto f_err;
}
- else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
+ if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_DH_RSA_CERT);
goto f_err;
}
-#ifndef OPENSSL_NO_DSA
- else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
+# ifndef OPENSSL_NO_DSA
+ if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_DH_DSA_CERT);
goto f_err;
}
-#endif
-#endif
+# endif
+
+ /* Check DHE only: static DH not implemented. */
+ if (alg_k & SSL_kEDH) {
+ int dh_size = BN_num_bits(dh->p);
+ if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768)
+ || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL);
+ goto f_err;
+ }
+ }
+#endif /* !OPENSSL_NO_DH */
- if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
+ if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+ pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
{
#ifndef OPENSSL_NO_RSA
- if (alg_k & SSL_kRSA)
- {
- if (rsa == NULL
- || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
+ if (alg_k & SSL_kRSA) {
+ if (rsa == NULL) {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
goto f_err;
+ } else if (BN_num_bits(rsa->n) >
+ SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+ /* We have a temporary RSA key but it's too large. */
+ al = SSL_AD_EXPORT_RESTRICTION;
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
+ goto f_err;
}
- }
- else
+ } else
#endif
#ifndef OPENSSL_NO_DH
- if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
- {
- if (dh == NULL
- || DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY);
+ if (alg_k & SSL_kEDH) {
+ if (BN_num_bits(dh->p) >
+ SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+ /* We have a temporary DH key but it's too large. */
+ al = SSL_AD_EXPORT_RESTRICTION;
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_EXPORT_TMP_DH_KEY);
goto f_err;
}
- }
- else
+ } else if (alg_k & (SSL_kDHr | SSL_kDHd)) {
+ /* The cert should have had an export DH key. */
+ al = SSL_AD_EXPORT_RESTRICTION;
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_MISSING_EXPORT_TMP_DH_KEY);
+ goto f_err;
+ } else
#endif
{
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+ SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
goto f_err;
}
}
- return(1);
-f_err:
- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
-err:
- return(0);
- }
+ return (1);
+ f_err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+ return (0);
+}
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
int ssl3_send_next_proto(SSL *s)
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index fadca74..6852e08 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -2418,6 +2418,7 @@ int ssl3_get_client_key_exchange(SSL *s)
int padl, outl;
krb5_timestamp authtime = 0;
krb5_ticket_times ttimes;
+ int kerr = 0;
EVP_CIPHER_CTX_init(&ciph_ctx);
@@ -2530,26 +2531,30 @@ int ssl3_get_client_key_exchange(SSL *s)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (outl > SSL_MAX_MASTER_KEY_LENGTH)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
- goto err;
+ kerr = 1;
+ goto kclean;
}
outl += padl;
if (outl > SSL_MAX_MASTER_KEY_LENGTH)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff))))
{
@@ -2565,7 +2570,8 @@ int ssl3_get_client_key_exchange(SSL *s)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_AD_DECODE_ERROR);
- goto err;
+ kerr = 1;
+ goto kclean;
}
}
@@ -2591,6 +2597,11 @@ int ssl3_get_client_key_exchange(SSL *s)
** kssl_ctx = kssl_ctx_free(kssl_ctx);
** if (s->kssl_ctx) s->kssl_ctx = NULL;
*/
+
+ kclean:
+ OPENSSL_cleanse(pms, sizeof(pms));
+ if (kerr)
+ goto err;
}
else
#endif /* OPENSSL_NO_KRB5 */
diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h
index 2ba5923..1b98e29 100644
--- a/crypto/openssl/ssl/ssl.h
+++ b/crypto/openssl/ssl/ssl.h
@@ -2263,6 +2263,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_READ 223
#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187
#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188
+#define SSL_F_SSL_SESSION_DUP 348
#define SSL_F_SSL_SESSION_NEW 189
#define SSL_F_SSL_SESSION_PRINT_FP 190
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
@@ -2377,6 +2378,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_DATA_LENGTH_TOO_LONG 146
#define SSL_R_DECRYPTION_FAILED 147
#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281
+#define SSL_R_DH_KEY_TOO_SMALL 372
#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148
#define SSL_R_DIGEST_CHECK_FAILED 149
#define SSL_R_DTLS_MESSAGE_TOO_BIG 334
diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c
index 1b7eb47..7b6aa99 100644
--- a/crypto/openssl/ssl/ssl_err.c
+++ b/crypto/openssl/ssl/ssl_err.c
@@ -245,6 +245,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"},
{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
+{ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
{ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
@@ -362,6 +363,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
+{ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"},
{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"},
{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"},
diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h
index 1b8fa8c..12d07b2 100644
--- a/crypto/openssl/ssl/ssl_locl.h
+++ b/crypto/openssl/ssl/ssl_locl.h
@@ -831,6 +831,7 @@ void ssl_sess_cert_free(SESS_CERT *sc);
int ssl_set_peer_cert_type(SESS_CERT *c, int type);
int ssl_get_new_session(SSL *s, int session);
int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
ssl_cipher_id);
diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c
index 235f92d..31fbf23 100644
--- a/crypto/openssl/ssl/ssl_sess.c
+++ b/crypto/openssl/ssl/ssl_sess.c
@@ -224,6 +224,130 @@ SSL_SESSION *SSL_SESSION_new(void)
return(ss);
}
+/*
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+ SSL_SESSION *dest;
+
+ dest = OPENSSL_malloc(sizeof(*src));
+ if (dest == NULL) {
+ goto err;
+ }
+ memcpy(dest, src, sizeof(*dest));
+
+ /*
+ * Set the various pointers to NULL so that we can call SSL_SESSION_free in
+ * the case of an error whilst halfway through constructing dest
+ */
+#ifndef OPENSSL_NO_PSK
+ dest->psk_identity_hint = NULL;
+ dest->psk_identity = NULL;
+#endif
+ dest->ciphers = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ dest->tlsext_hostname = NULL;
+# ifndef OPENSSL_NO_EC
+ dest->tlsext_ecpointformatlist = NULL;
+ dest->tlsext_ellipticcurvelist = NULL;
+# endif
+#endif
+ dest->tlsext_tick = NULL;
+#ifndef OPENSSL_NO_SRP
+ dest->srp_username = NULL;
+#endif
+ memset(&dest->ex_data, 0, sizeof(dest->ex_data));
+
+ /* We deliberately don't copy the prev and next pointers */
+ dest->prev = NULL;
+ dest->next = NULL;
+
+ dest->references = 1;
+
+ if (src->sess_cert != NULL)
+ CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
+
+ if (src->peer != NULL)
+ CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
+
+#ifndef OPENSSL_NO_PSK
+ if (src->psk_identity_hint) {
+ dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint);
+ if (dest->psk_identity_hint == NULL) {
+ goto err;
+ }
+ }
+ if (src->psk_identity) {
+ dest->psk_identity = BUF_strdup(src->psk_identity);
+ if (dest->psk_identity == NULL) {
+ goto err;
+ }
+ }
+#endif
+
+ if(src->ciphers != NULL) {
+ dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
+ if (dest->ciphers == NULL)
+ goto err;
+ }
+
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
+ &dest->ex_data, &src->ex_data)) {
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (src->tlsext_hostname) {
+ dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
+ if (dest->tlsext_hostname == NULL) {
+ goto err;
+ }
+ }
+# ifndef OPENSSL_NO_EC
+ if (src->tlsext_ecpointformatlist) {
+ dest->tlsext_ecpointformatlist =
+ BUF_memdup(src->tlsext_ecpointformatlist,
+ src->tlsext_ecpointformatlist_length);
+ if (dest->tlsext_ecpointformatlist == NULL)
+ goto err;
+ }
+ if (src->tlsext_ellipticcurvelist) {
+ dest->tlsext_ellipticcurvelist =
+ BUF_memdup(src->tlsext_ellipticcurvelist,
+ src->tlsext_ellipticcurvelist_length);
+ if (dest->tlsext_ellipticcurvelist == NULL)
+ goto err;
+ }
+# endif
+#endif
+
+ if (ticket != 0) {
+ dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
+ if(dest->tlsext_tick == NULL)
+ goto err;
+ } else {
+ dest->tlsext_tick_lifetime_hint = 0;
+ dest->tlsext_ticklen = 0;
+ }
+
+#ifndef OPENSSL_NO_SRP
+ if (src->srp_username) {
+ dest->srp_username = BUF_strdup(src->srp_username);
+ if (dest->srp_username == NULL) {
+ goto err;
+ }
+ }
+#endif
+
+ return dest;
+err:
+ SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+ SSL_SESSION_free(dest);
+ return NULL;
+}
+
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
{
if(len)
diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c
index 179b467..afd5eee 100644
--- a/crypto/openssl/ssl/t1_lib.c
+++ b/crypto/openssl/ssl/t1_lib.c
@@ -1015,12 +1015,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
s->srtp_profile = NULL;
- if (data >= (d+n-2))
+ if (data >= (d + n - 2)) {
+ if (data != d + n)
+ goto err;
+ else
goto ri_check;
+ }
n2s(data,len);
if (data > (d+n-len))
- goto ri_check;
+ goto err;
while (data <= (d+n-4))
{
@@ -1028,7 +1032,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
n2s(data,size);
if (data+size > (d+n))
- goto ri_check;
+ goto err;
#if 0
fprintf(stderr,"Received extension type %d size %d\n",type,size);
#endif
@@ -1065,17 +1069,11 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
int dsize;
if (size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
n2s(data,dsize);
size -= 2;
if (dsize > size )
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
sdata = data;
while (dsize > 3)
@@ -1085,10 +1083,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
dsize -= 3;
if (len > dsize)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (s->servername_done == 0)
switch (servname_type)
{
@@ -1096,10 +1091,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
if (!s->hit)
{
if(s->session->tlsext_hostname)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (len > TLSEXT_MAXLEN_host_name)
{
*al = TLS1_AD_UNRECOGNIZED_NAME;
@@ -1135,36 +1127,24 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
dsize -= len;
}
if (dsize != 0)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
}
#ifndef OPENSSL_NO_SRP
else if (type == TLSEXT_TYPE_srp)
{
if (size <= 0 || ((len = data[0])) != (size -1))
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (s->srp_ctx.login != NULL)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL)
return -1;
memcpy(s->srp_ctx.login, &data[1], len);
s->srp_ctx.login[len]='\0';
if (strlen(s->srp_ctx.login) != len)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
+ goto err;
}
- }
#endif
#ifndef OPENSSL_NO_EC
@@ -1174,10 +1154,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
int ecpointformatlist_length = *(sdata++);
if (ecpointformatlist_length != size - 1)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (!s->hit)
{
if(s->session->tlsext_ecpointformatlist)
@@ -1212,17 +1189,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
ellipticcurvelist_length < 1 ||
/* Each NamedCurve is 2 bytes. */
ellipticcurvelist_length & 1)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (!s->hit)
{
if(s->session->tlsext_ellipticcurvelist)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
+
s->session->tlsext_ellipticcurvelist_length = 0;
if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
{
@@ -1291,33 +1263,21 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
{
int dsize;
if (sigalg_seen || size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
sigalg_seen = 1;
n2s(data,dsize);
size -= 2;
if (dsize != size || dsize & 1)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (!tls1_process_sigalgs(s, data, dsize))
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
+ goto err;
}
- }
else if (type == TLSEXT_TYPE_status_request &&
s->version != DTLS1_VERSION)
{
if (size < 5)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
s->tlsext_status_type = *data++;
size--;
@@ -1329,41 +1289,28 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
n2s(data,dsize);
size -= 2;
if (dsize > size )
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
while (dsize > 0)
{
OCSP_RESPID *id;
int idsize;
if (dsize < 4)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
n2s(data, idsize);
dsize -= 2 + idsize;
size -= 2 + idsize;
if (dsize < 0)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
sdata = data;
data += idsize;
id = d2i_OCSP_RESPID(NULL,
&sdata, idsize);
if (!id)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
if (data != sdata)
{
OCSP_RESPID_free(id);
- *al = SSL_AD_DECODE_ERROR;
- return 0;
+ goto err;
}
if (!s->tlsext_ocsp_ids
&& !(s->tlsext_ocsp_ids =
@@ -1384,17 +1331,11 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
/* Read in request_extensions */
if (size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
n2s(data,dsize);
size -= 2;
if (dsize != size)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ goto err;
sdata = data;
if (dsize > 0)
{
@@ -1409,12 +1350,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
&sdata, dsize);
if (!s->tlsext_ocsp_exts
|| (data + dsize != sdata))
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
+ goto err;
}
}
- }
/* We don't know what to do with any other type
* so ignore it.
*/
@@ -1475,6 +1413,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
data+=size;
}
+ /* Spurious data on the end */
+ if (data != d + n)
+ goto err;
+
*p = data;
ri_check:
@@ -1491,7 +1433,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
return 1;
- }
+err:
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+}
#ifndef OPENSSL_NO_NEXTPROTONEG
/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 691b57f..cba1d4e 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="10.1"
-BRANCH="RELEASE-p11"
+BRANCH="RELEASE-p12"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
OpenPOWER on IntegriCloud