1897 lines
62 KiB
Diff
1897 lines
62 KiB
Diff
Index: crypto/openssl/apps/dhparam.c
|
|
===================================================================
|
|
--- crypto/openssl/apps/dhparam.c (revision 284286)
|
|
+++ crypto/openssl/apps/dhparam.c (working copy)
|
|
@@ -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
|
|
Index: crypto/openssl/apps/gendh.c
|
|
===================================================================
|
|
--- crypto/openssl/apps/gendh.c (revision 284286)
|
|
+++ crypto/openssl/apps/gendh.c (working copy)
|
|
@@ -78,7 +78,7 @@
|
|
#include <openssl/x509.h>
|
|
#include <openssl/pem.h>
|
|
|
|
-#define DEFBITS 512
|
|
+#define DEFBITS 2048
|
|
#undef PROG
|
|
#define PROG gendh_main
|
|
|
|
Index: crypto/openssl/apps/s_server.c
|
|
===================================================================
|
|
--- crypto/openssl/apps/s_server.c (revision 284286)
|
|
+++ crypto/openssl/apps/s_server.c (working copy)
|
|
@@ -214,7 +214,7 @@ static int generate_session_id(const SSL *ssl, uns
|
|
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;
|
|
+DH *get_dh2048()
|
|
+{
|
|
+ DH *dh;
|
|
|
|
- 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);
|
|
+ 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,9 +1681,8 @@ 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);
|
|
@@ -1670,27 +1689,25 @@ bad:
|
|
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);
|
|
@@ -1697,9 +1714,9 @@ bad:
|
|
dh = dh2;
|
|
}
|
|
}
|
|
- SSL_CTX_set_tmp_dh(ctx2,dh);
|
|
+ SSL_CTX_set_tmp_dh(ctx2, dh);
|
|
}
|
|
-#endif
|
|
+# endif
|
|
DH_free(dh);
|
|
}
|
|
#endif
|
|
Index: crypto/openssl/crypto/bio/bio_lib.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/bio/bio_lib.c (revision 284286)
|
|
+++ crypto/openssl/crypto/bio/bio_lib.c (working copy)
|
|
@@ -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);
|
|
}
|
|
|
|
Index: crypto/openssl/crypto/bn/bn_gf2m.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/bn/bn_gf2m.c (revision 284286)
|
|
+++ crypto/openssl/crypto/bn/bn_gf2m.c (working copy)
|
|
@@ -568,10 +568,11 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co
|
|
}
|
|
#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, co
|
|
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)
|
|
{
|
|
Index: crypto/openssl/crypto/bn/bn_print.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/bn/bn_print.c (revision 284286)
|
|
+++ crypto/openssl/crypto/bn/bn_print.c (working copy)
|
|
@@ -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);
|
|
Index: crypto/openssl/crypto/buffer/buffer.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/buffer/buffer.c (revision 284286)
|
|
+++ crypto/openssl/crypto/buffer/buffer.c (working copy)
|
|
@@ -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);
|
|
Index: crypto/openssl/crypto/cms/cms_smime.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/cms/cms_smime.c (revision 284286)
|
|
+++ crypto/openssl/crypto/cms/cms_smime.c (working copy)
|
|
@@ -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);
|
|
Index: crypto/openssl/crypto/ec/ec2_oct.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/ec/ec2_oct.c (revision 284286)
|
|
+++ crypto/openssl/crypto/ec/ec2_oct.c (working copy)
|
|
@@ -390,7 +390,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group
|
|
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;
|
|
Index: crypto/openssl/crypto/ec/ec_check.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/ec/ec_check.c (revision 284286)
|
|
+++ crypto/openssl/crypto/ec/ec_check.c (working copy)
|
|
@@ -88,7 +88,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_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;
|
|
Index: crypto/openssl/crypto/ec/ec_key.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/ec/ec_key.c (revision 284286)
|
|
+++ crypto/openssl/crypto/ec/ec_key.c (working copy)
|
|
@@ -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;
|
|
Index: crypto/openssl/crypto/ec/ec_lib.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/ec/ec_lib.c (revision 284286)
|
|
+++ crypto/openssl/crypto/ec/ec_lib.c (working copy)
|
|
@@ -972,7 +972,15 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group,
|
|
}
|
|
|
|
|
|
-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)
|
|
{
|
|
Index: crypto/openssl/crypto/ec/ecp_oct.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/ec/ecp_oct.c (revision 284286)
|
|
+++ crypto/openssl/crypto/ec/ecp_oct.c (working copy)
|
|
@@ -416,7 +416,8 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group,
|
|
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;
|
|
Index: crypto/openssl/crypto/ec/ectest.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/ec/ectest.c (revision 284286)
|
|
+++ crypto/openssl/crypto/ec/ectest.c (working copy)
|
|
@@ -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;
|
|
Index: crypto/openssl/crypto/evp/e_aes.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/evp/e_aes.c (revision 284286)
|
|
+++ crypto/openssl/crypto/evp/e_aes.c (working copy)
|
|
@@ -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,
|
|
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, uns
|
|
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;
|
|
}
|
|
}
|
|
Index: crypto/openssl/crypto/evp/e_rc4_hmac_md5.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/evp/e_rc4_hmac_md5.c (revision 284286)
|
|
+++ crypto/openssl/crypto/evp/e_rc4_hmac_md5.c (working copy)
|
|
@@ -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
|
|
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);
|
|
Index: crypto/openssl/crypto/evp/evp.h
|
|
===================================================================
|
|
--- crypto/openssl/crypto/evp/evp.h (revision 284286)
|
|
+++ crypto/openssl/crypto/evp/evp.h (working copy)
|
|
@@ -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
|
|
Index: crypto/openssl/crypto/hmac/hmac.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/hmac/hmac.c (revision 284286)
|
|
+++ crypto/openssl/crypto/hmac/hmac.c (working copy)
|
|
@@ -240,6 +240,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const vo
|
|
HMAC_CTX_cleanup(&c);
|
|
return md;
|
|
err:
|
|
+ HMAC_CTX_cleanup(&c);
|
|
return NULL;
|
|
}
|
|
|
|
Index: crypto/openssl/crypto/modes/gcm128.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/modes/gcm128.c (revision 284286)
|
|
+++ crypto/openssl/crypto/modes/gcm128.c (working copy)
|
|
@@ -1525,7 +1525,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const
|
|
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;
|
|
}
|
|
Index: crypto/openssl/crypto/objects/obj_dat.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/objects/obj_dat.c (revision 284286)
|
|
+++ crypto/openssl/crypto/objects/obj_dat.c (working copy)
|
|
@@ -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;
|
|
Index: crypto/openssl/crypto/pkcs12/p12_mutl.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/pkcs12/p12_mutl.c (revision 284286)
|
|
+++ crypto/openssl/crypto/pkcs12/p12_mutl.c (working copy)
|
|
@@ -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 *pas
|
|
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;
|
|
}
|
|
|
|
Index: crypto/openssl/crypto/pkcs7/pk7_doit.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 284286)
|
|
+++ crypto/openssl/crypto/pkcs7/pk7_doit.c (working copy)
|
|
@@ -504,6 +504,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
|
|
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, B
|
|
}
|
|
|
|
#if 1
|
|
- if (PKCS7_is_detached(p7) || (in_bio != NULL))
|
|
+ if (in_bio != NULL)
|
|
{
|
|
bio=in_bio;
|
|
}
|
|
Index: crypto/openssl/crypto/x509/x509_vfy.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/x509/x509_vfy.c (revision 284286)
|
|
+++ crypto/openssl/crypto/x509/x509_vfy.c (working copy)
|
|
@@ -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;
|
|
+ char buff1[24], buff2[24], *p;
|
|
+ int i, j, remaining;
|
|
|
|
- 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;
|
|
+ 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;
|
|
}
|
|
- 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 == '.')
|
|
- {
|
|
+ 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)
|
|
{
|
|
Index: crypto/openssl/crypto/x509/x509type.c
|
|
===================================================================
|
|
--- crypto/openssl/crypto/x509/x509type.c (revision 284286)
|
|
+++ crypto/openssl/crypto/x509/x509type.c (working copy)
|
|
@@ -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);
|
|
}
|
|
Index: crypto/openssl/doc/apps/dhparam.pod
|
|
===================================================================
|
|
--- crypto/openssl/doc/apps/dhparam.pod (revision 284286)
|
|
+++ crypto/openssl/doc/apps/dhparam.pod (working copy)
|
|
@@ -71,8 +71,10 @@ check if the parameters are valid primes and gener
|
|
|
|
=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>
|
|
|
|
Index: crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
|
|
===================================================================
|
|
--- crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod (revision 284286)
|
|
+++ crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod (working copy)
|
|
@@ -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,83 +74,63 @@ DH parameters can be reused, as the actual key is
|
|
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.)
|
|
|
|
+ Command-line parameter generation:
|
|
+ $ openssl dhparam -out dh_param_2048.pem 2048
|
|
+
|
|
+ Code for setting up parameters during server initialization:
|
|
+
|
|
...
|
|
- /* Set up ephemeral DH stuff */
|
|
- DH *dh_512 = NULL;
|
|
- DH *dh_1024 = NULL;
|
|
+ SSL_CTX ctx = SSL_CTX_new();
|
|
+ ...
|
|
+
|
|
+ /* Set up ephemeral DH parameters. */
|
|
+ DH *dh_2048 = NULL;
|
|
FILE *paramfile;
|
|
-
|
|
- ...
|
|
- /* "openssl dhparam -out dh_param_512.pem -2 512" */
|
|
- paramfile = fopen("dh_param_512.pem", "r");
|
|
+ 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. */
|
|
}
|
|
+ if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) {
|
|
+ /* Error. */
|
|
+ }
|
|
+ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
|
|
...
|
|
|
|
- /* "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);
|
|
- }
|
|
-
|
|
=head1 RETURN VALUES
|
|
|
|
SSL_CTX_set_tmp_dh_callback() and SSL_set_tmp_dh_callback() do not return
|
|
Index: crypto/openssl/ssl/d1_both.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/d1_both.c (revision 284286)
|
|
+++ crypto/openssl/ssl/d1_both.c (working copy)
|
|
@@ -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 st
|
|
/* 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 st
|
|
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,9 +929,6 @@ dtls1_get_message_fragment(SSL *s, int st1, int st
|
|
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;
|
|
@@ -922,7 +935,10 @@ dtls1_get_message_fragment(SSL *s, int st1, int st
|
|
|
|
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 st
|
|
}
|
|
|
|
*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'
|
|
Index: crypto/openssl/ssl/d1_lib.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/d1_lib.c (revision 284286)
|
|
+++ crypto/openssl/ssl/d1_lib.c (working copy)
|
|
@@ -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;
|
|
|
|
Index: crypto/openssl/ssl/d1_pkt.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/d1_pkt.c (revision 284286)
|
|
+++ crypto/openssl/ssl/d1_pkt.c (working copy)
|
|
@@ -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 */
|
|
Index: crypto/openssl/ssl/s3_cbc.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/s3_cbc.c (revision 284286)
|
|
+++ crypto/openssl/ssl/s3_cbc.c (working copy)
|
|
@@ -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;
|
|
Index: crypto/openssl/ssl/s3_clnt.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/s3_clnt.c (revision 284286)
|
|
+++ crypto/openssl/ssl/s3_clnt.c (working copy)
|
|
@@ -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
|
|
|
|
- if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
|
|
+ /* 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) &&
|
|
+ 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)
|
|
Index: crypto/openssl/ssl/s3_srvr.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/s3_srvr.c (revision 284286)
|
|
+++ crypto/openssl/ssl/s3_srvr.c (working copy)
|
|
@@ -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,19 +2531,22 @@ 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)
|
|
@@ -2549,7 +2553,8 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
{
|
|
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 */
|
|
Index: crypto/openssl/ssl/ssl.h
|
|
===================================================================
|
|
--- crypto/openssl/ssl/ssl.h (revision 284286)
|
|
+++ crypto/openssl/ssl/ssl.h (working copy)
|
|
@@ -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
|
|
Index: crypto/openssl/ssl/ssl_err.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/ssl_err.c (revision 284286)
|
|
+++ crypto/openssl/ssl/ssl_err.c (working copy)
|
|
@@ -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"},
|
|
Index: crypto/openssl/ssl/ssl_locl.h
|
|
===================================================================
|
|
--- crypto/openssl/ssl/ssl_locl.h (revision 284286)
|
|
+++ crypto/openssl/ssl/ssl_locl.h (working copy)
|
|
@@ -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);
|
|
Index: crypto/openssl/ssl/ssl_sess.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/ssl_sess.c (revision 284286)
|
|
+++ crypto/openssl/ssl/ssl_sess.c (working copy)
|
|
@@ -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)
|
|
Index: crypto/openssl/ssl/t1_lib.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/t1_lib.c (revision 284286)
|
|
+++ crypto/openssl/ssl/t1_lib.c (working copy)
|
|
@@ -1015,12 +1015,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned
|
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,10 +1127,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned
|
|
dsize -= len;
|
|
}
|
|
if (dsize != 0)
|
|
- {
|
|
- *al = SSL_AD_DECODE_ERROR;
|
|
- return 0;
|
|
- }
|
|
+ goto err;
|
|
|
|
}
|
|
#ifndef OPENSSL_NO_SRP
|
|
@@ -1145,15 +1134,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned
|
|
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);
|
|
@@ -1160,11 +1143,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned
|
|
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
|
|
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
|
|
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
|
|
{
|
|
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
|
|
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
|
|
|
|
/* 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
|
|
&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
|
|
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
|
|
}
|
|
|
|
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
|