doc/share/security/patches/SA-15:10/openssl-8.4.patch
2015-06-12 07:33:55 +00:00

692 lines
24 KiB
Diff

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,6 +71,12 @@ char *BN_bn2hex(const BIGNUM *a)
char *buf;
char *p;
+ 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);
+ }
buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
if (buf == NULL)
{
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_smpl.c
===================================================================
--- crypto/openssl/crypto/ec/ec2_smpl.c (revision 284286)
+++ crypto/openssl/crypto/ec/ec2_smpl.c (working copy)
@@ -657,7 +657,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)
@@ -316,7 +316,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)
@@ -1040,7 +1040,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_smpl.c
===================================================================
--- crypto/openssl/crypto/ec/ecp_smpl.c (revision 284286)
+++ crypto/openssl/crypto/ec/ecp_smpl.c (working copy)
@@ -983,7 +983,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)
@@ -267,7 +267,7 @@ void prime_field_tests()
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");
@@ -363,7 +363,7 @@ void prime_field_tests()
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;
@@ -407,7 +407,7 @@ void prime_field_tests()
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;
@@ -453,7 +453,7 @@ void prime_field_tests()
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;
@@ -499,7 +499,7 @@ void prime_field_tests()
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;
@@ -550,7 +550,7 @@ void prime_field_tests()
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;
@@ -606,7 +606,7 @@ void prime_field_tests()
"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;
@@ -651,7 +651,7 @@ void prime_field_tests()
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;
@@ -764,7 +764,7 @@ void prime_field_tests()
#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; \
@@ -782,7 +782,7 @@ void prime_field_tests()
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; \
@@ -895,7 +895,7 @@ void char2_field_tests()
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
@@ -1134,7 +1134,7 @@ void char2_field_tests()
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/objects/obj_dat.c
===================================================================
--- crypto/openssl/crypto/objects/obj_dat.c (revision 284286)
+++ crypto/openssl/crypto/objects/obj_dat.c (working copy)
@@ -377,6 +377,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/pkcs7/pk7_doit.c
===================================================================
--- crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 284286)
+++ crypto/openssl/crypto/pkcs7/pk7_doit.c (working copy)
@@ -410,6 +410,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)
{
@@ -587,12 +593,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
}
#if 1
- if (PKCS7_is_detached(p7) || (in_bio != NULL))
- {
- bio=in_bio;
- }
- else
- {
+ if (in_bio != NULL) {
+ bio = in_bio;
+ } else {
#if 0
bio=BIO_new(BIO_s_mem());
/* We need to set this so that when we have read all
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)
@@ -1040,82 +1040,120 @@ int X509_cmp_current_time(ASN1_TIME *ctm)
}
int X509_cmp_time(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.length=sizeof(buff2);
- atm.data=(unsigned char *)buff2;
+ atm.type = ctm->type;
+ 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/ssl/d1_lib.c
===================================================================
--- crypto/openssl/ssl/d1_lib.c (revision 284286)
+++ crypto/openssl/ssl/d1_lib.c (working copy)
@@ -507,6 +507,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/s3_clnt.c
===================================================================
--- crypto/openssl/ssl/s3_clnt.c (revision 284286)
+++ crypto/openssl/ssl/s3_clnt.c (working copy)
@@ -1805,6 +1805,38 @@ int ssl3_get_new_session_ticket(SSL *s)
}
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 */
Index: crypto/openssl/ssl/s3_srvr.c
===================================================================
--- crypto/openssl/ssl/s3_srvr.c (revision 284286)
+++ crypto/openssl/ssl/s3_srvr.c (working copy)
@@ -2012,6 +2012,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);
@@ -2124,19 +2125,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)
@@ -2143,7 +2147,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))))
{
@@ -2159,7 +2164,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;
}
}
@@ -2185,8 +2191,12 @@ int ssl3_get_client_key_exchange(SSL *s)
** kssl_ctx = kssl_ctx_free(kssl_ctx);
** if (s->kssl_ctx) s->kssl_ctx = NULL;
*/
- }
- else
+
+ kclean:
+ OPENSSL_cleanse(pms, sizeof(pms));
+ if (kerr)
+ goto err;
+ } else
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_ECDH
Index: crypto/openssl/ssl/ssl.h
===================================================================
--- crypto/openssl/ssl/ssl.h (revision 284286)
+++ crypto/openssl/ssl/ssl.h (working copy)
@@ -1851,6 +1851,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_SESS_CERT_NEW 225
Index: crypto/openssl/ssl/ssl_err.c
===================================================================
--- crypto/openssl/ssl/ssl_err.c (revision 284286)
+++ crypto/openssl/ssl/ssl_err.c (working copy)
@@ -233,6 +233,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_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"},
Index: crypto/openssl/ssl/ssl_locl.h
===================================================================
--- crypto/openssl/ssl/ssl_locl.h (revision 284286)
+++ crypto/openssl/ssl/ssl_locl.h (working copy)
@@ -731,6 +731,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);
int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
const SSL_CIPHER * const *bp);
Index: crypto/openssl/ssl/ssl_sess.c
===================================================================
--- crypto/openssl/ssl/ssl_sess.c (revision 284286)
+++ crypto/openssl/ssl/ssl_sess.c (working copy)
@@ -132,6 +132,79 @@ 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
+ */
+ dest->ciphers = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ dest->tlsext_hostname = NULL;
+#endif
+ dest->tlsext_tick = NULL;
+ 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);
+
+ 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;
+ }
+ }
+#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;
+ }
+
+ 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)