[Pkg-openssl-devel] Some openssl patches
Bolesław Tokarski
btokarski at opera.com
Fri Feb 26 14:46:49 UTC 2016
Hello,
I know the next openssl release which is supposed to fix a number of security
issues is advertised to happen on Mar 1st, but since (at least some of) their
patches seem to have landed on their git repository, I took the challenge to
port them to Wheezy and Jessie.
I guess you will be doing that soon as well, you may find them useful. There
was some work required since between the 1.0.1s version that's to be released
and the 1.0.1e and 1.0.1k versions in Wheezy/Jessie there were some whitespace
changes done.
I have not done any verification if the current packages are vulnerable at all.
The head of the patches contain the commit descriptions used. The commit IDs
are different than those in the upstream git, as they came from my private git
repository after being backported. Don't feel obliged to put my name on it.
Please let me know if you find them ported incorrectly, though.
Best regards,
Bolesław Tokarski
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CVE-2016-0705.patch
Type: text/x-patch
Size: 1518 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-openssl-devel/attachments/20160226/b3ab57cf/attachment-0005.bin>
-------------- next part --------------
commit a88b90440bec3e56408d4179545290405f651141
Author: Emilia Kasper <emilia at openssl.org>
Date: Wed Feb 24 12:59:59 2016 +0100
CVE-2016-0798: avoid memory leak in SRP
The SRP user database lookup method SRP_VBASE_get_by_user had confusing
memory management semantics; the returned pointer was sometimes newly
allocated, and sometimes owned by the callee. The calling code has no
way of distinguishing these two cases.
Specifically, SRP servers that configure a secret seed to hide valid
login information are vulnerable to a memory leak: an attacker
connecting with an invalid username can cause a memory leak of around
300 bytes per connection.
Servers that do not configure SRP, or configure SRP but do not configure
a seed are not vulnerable.
In Apache, the seed directive is known as SSLSRPUnknownUserSeed.
To mitigate the memory leak, the seed handling in SRP_VBASE_get_by_user
is now disabled even if the user has configured a seed.
Applications are advised to migrate to SRP_VBASE_get1_by_user. However,
note that OpenSSL makes no strong guarantees about the
indistinguishability of valid and invalid logins. In particular,
computations are currently not carried out in constant time.
Reviewed-by: Rich Salz <rsalz at openssl.org>
Merged-by: Bolesław Tokarski
Conflicts:
CHANGES
apps/s_server.c
crypto/srp/srp.h
crypto/srp/srp_vfy.c
util/libeay.num
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -395,6 +395,8 @@
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
srpsrvparm *p = (srpsrvparm *)arg;
+ int ret = SSL3_AL_FATAL;
+
if (p->login == NULL && p->user == NULL )
{
p->login = SSL_get_srp_username(s);
@@ -405,19 +407,23 @@
if (p->user == NULL)
{
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
- return SSL3_AL_FATAL;
+ goto err;
}
+
if (SSL_set_srp_server_param(s, p->user->N, p->user->g, p->user->s, p->user->v,
p->user->info) < 0)
{
*ad = SSL_AD_INTERNAL_ERROR;
- return SSL3_AL_FATAL;
+ goto err;
}
BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
- /* need to check whether there are memory leaks */
+ ret = SSL_ERROR_NONE;
+
+err:
+ SRP_user_pwd_free(p->user);
p->user = NULL;
p->login = NULL;
- return SSL_ERROR_NONE;
+ return ret;
}
#endif
@@ -2284,7 +2290,8 @@
while (SSL_get_error(con,k) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP renego during write\n");
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
@@ -2343,7 +2350,8 @@
while (SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP renego during read\n");
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
@@ -2432,7 +2440,8 @@
while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
@@ -2674,7 +2683,8 @@
while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
--- a/crypto/srp/srp.h
+++ b/crypto/srp/srp.h
@@ -83,16 +83,21 @@
typedef struct SRP_user_pwd_st
{
+ /* Owned by us. */
char *id;
BIGNUM *s;
BIGNUM *v;
+ /* Not owned by us. */
const BIGNUM *g;
const BIGNUM *N;
+ /* Owned by us. */
char *info;
} SRP_user_pwd;
DECLARE_STACK_OF(SRP_user_pwd)
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd);
+
typedef struct SRP_VBASE_st
{
STACK_OF(SRP_user_pwd) *users_pwd;
@@ -117,7 +122,12 @@
SRP_VBASE *SRP_VBASE_new(char *seed_key);
int SRP_VBASE_free(SRP_VBASE *vb);
int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file);
+
+/* This method ignores the configured seed and fails for an unknown user. */
SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
+/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username);
+
char *SRP_create_verifier(const char *user, const char *pass, char **salt,
char **verifier, const char *N, const char *g);
int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
--- a/crypto/srp/srp_vfy.c
+++ b/crypto/srp/srp_vfy.c
@@ -182,7 +182,7 @@
return olddst;
}
-static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
{
if (user_pwd == NULL)
return;
@@ -244,6 +244,24 @@
return (vinfo->s != NULL && vinfo->v != NULL) ;
}
+static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src)
+{
+ SRP_user_pwd *ret;
+
+ if (src == NULL)
+ return NULL;
+ if ((ret = SRP_user_pwd_new()) == NULL)
+ return NULL;
+
+ SRP_user_pwd_set_gN(ret, src->g, src->N);
+ if (!SRP_user_pwd_set_ids(ret, src->id, src->info)
+ || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) {
+ SRP_user_pwd_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
SRP_VBASE *SRP_VBASE_new(char *seed_key)
{
SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE));
@@ -475,26 +493,54 @@
}
-SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username)
{
int i;
SRP_user_pwd *user;
- unsigned char digv[SHA_DIGEST_LENGTH];
- unsigned char digs[SHA_DIGEST_LENGTH];
- EVP_MD_CTX ctxt;
if (vb == NULL)
return NULL;
+
for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
{
user = sk_SRP_user_pwd_value(vb->users_pwd, i);
if (strcmp(user->id,username)==0)
return user;
}
- if ((vb->seed_key == NULL) ||
- (vb->default_g == NULL) ||
- (vb->default_N == NULL))
- return NULL;
+
+ return NULL;
+}
+
+/*
+ * This method ignores the configured seed and fails for an unknown user.
+ * Ownership of the returned pointer is not released to the caller.
+ * In other words, caller must not free the result.
+ */
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+{
+ return find_user(vb, username);
+}
+
+/*
+ * Ownership of the returned pointer is released to the caller.
+ * In other words, caller must free the result once done.
+ */
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
+{
+ SRP_user_pwd *user;
+ unsigned char digv[SHA_DIGEST_LENGTH];
+ unsigned char digs[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX ctxt;
+
+ if (vb == NULL)
+ return NULL;
+
+ if ((user = find_user(vb, username)) != NULL)
+ return srp_user_pwd_dup(user);
+
+ if ((vb->seed_key == NULL) ||
+ (vb->default_g == NULL) || (vb->default_N == NULL))
+ return NULL;
/* if the user is unknown we set parameters as well if we have a seed_key */
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1806,6 +1806,8 @@
ASN1_UTCTIME_get 2350 NOEXIST::FUNCTION:
X509_REQ_digest 2362 EXIST::FUNCTION:EVP
X509_CRL_digest 2391 EXIST::FUNCTION:EVP
+SRP_VBASE_get1_by_user 2393 EXIST::FUNCTION:SRP
+SRP_user_pwd_free 2394 EXIST::FUNCTION:SRP
d2i_ASN1_SET_OF_PKCS7 2397 NOEXIST::FUNCTION:
X509_ALGOR_cmp 2398 EXIST::FUNCTION:
EVP_CIPHER_CTX_set_key_length 2399 EXIST::FUNCTION:
-------------- next part --------------
commit a88b90440bec3e56408d4179545290405f651141
Author: Emilia Kasper <emilia at openssl.org>
Date: Wed Feb 24 12:59:59 2016 +0100
CVE-2016-0798: avoid memory leak in SRP
The SRP user database lookup method SRP_VBASE_get_by_user had confusing
memory management semantics; the returned pointer was sometimes newly
allocated, and sometimes owned by the callee. The calling code has no
way of distinguishing these two cases.
Specifically, SRP servers that configure a secret seed to hide valid
login information are vulnerable to a memory leak: an attacker
connecting with an invalid username can cause a memory leak of around
300 bytes per connection.
Servers that do not configure SRP, or configure SRP but do not configure
a seed are not vulnerable.
In Apache, the seed directive is known as SSLSRPUnknownUserSeed.
To mitigate the memory leak, the seed handling in SRP_VBASE_get_by_user
is now disabled even if the user has configured a seed.
Applications are advised to migrate to SRP_VBASE_get1_by_user. However,
note that OpenSSL makes no strong guarantees about the
indistinguishability of valid and invalid logins. In particular,
computations are currently not carried out in constant time.
Reviewed-by: Rich Salz <rsalz at openssl.org>
Merged-by: Bolesław Tokarski
Conflicts:
CHANGES
apps/s_server.c
crypto/srp/srp.h
crypto/srp/srp_vfy.c
util/libeay.num
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -395,6 +395,8 @@
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
srpsrvparm *p = (srpsrvparm *)arg;
+ int ret = SSL3_AL_FATAL;
+
if (p->login == NULL && p->user == NULL )
{
p->login = SSL_get_srp_username(s);
@@ -405,19 +407,23 @@
if (p->user == NULL)
{
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
- return SSL3_AL_FATAL;
+ goto err;
}
+
if (SSL_set_srp_server_param(s, p->user->N, p->user->g, p->user->s, p->user->v,
p->user->info) < 0)
{
*ad = SSL_AD_INTERNAL_ERROR;
- return SSL3_AL_FATAL;
+ goto err;
}
BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
- /* need to check whether there are memory leaks */
+ ret = SSL_ERROR_NONE;
+
+err:
+ SRP_user_pwd_free(p->user);
p->user = NULL;
p->login = NULL;
- return SSL_ERROR_NONE;
+ return ret;
}
#endif
@@ -2254,7 +2260,8 @@
while (SSL_get_error(con,k) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP renego during write\n");
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
@@ -2313,7 +2320,8 @@
while (SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP renego during read\n");
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
@@ -2402,7 +2410,8 @@
while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
@@ -2644,7 +2653,8 @@
while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
{
BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
- srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user = SRP_VBASE_get1_by_user(srp_callback_parm.vb, srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
else
--- a/crypto/srp/srp.h
+++ b/crypto/srp/srp.h
@@ -83,16 +83,21 @@
typedef struct SRP_user_pwd_st
{
+ /* Owned by us. */
char *id;
BIGNUM *s;
BIGNUM *v;
+ /* Not owned by us. */
const BIGNUM *g;
const BIGNUM *N;
+ /* Owned by us. */
char *info;
} SRP_user_pwd;
DECLARE_STACK_OF(SRP_user_pwd)
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd);
+
typedef struct SRP_VBASE_st
{
STACK_OF(SRP_user_pwd) *users_pwd;
@@ -117,7 +122,12 @@
SRP_VBASE *SRP_VBASE_new(char *seed_key);
int SRP_VBASE_free(SRP_VBASE *vb);
int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file);
+
+/* This method ignores the configured seed and fails for an unknown user. */
SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
+/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username);
+
char *SRP_create_verifier(const char *user, const char *pass, char **salt,
char **verifier, const char *N, const char *g);
int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
--- a/crypto/srp/srp_vfy.c
+++ b/crypto/srp/srp_vfy.c
@@ -179,7 +179,7 @@
return olddst;
}
-static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
{
if (user_pwd == NULL)
return;
@@ -241,6 +241,24 @@
return (vinfo->s != NULL && vinfo->v != NULL) ;
}
+static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src)
+{
+ SRP_user_pwd *ret;
+
+ if (src == NULL)
+ return NULL;
+ if ((ret = SRP_user_pwd_new()) == NULL)
+ return NULL;
+
+ SRP_user_pwd_set_gN(ret, src->g, src->N);
+ if (!SRP_user_pwd_set_ids(ret, src->id, src->info)
+ || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) {
+ SRP_user_pwd_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
SRP_VBASE *SRP_VBASE_new(char *seed_key)
{
SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE));
@@ -472,26 +490,54 @@
}
-SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username)
{
int i;
SRP_user_pwd *user;
- unsigned char digv[SHA_DIGEST_LENGTH];
- unsigned char digs[SHA_DIGEST_LENGTH];
- EVP_MD_CTX ctxt;
if (vb == NULL)
return NULL;
+
for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
{
user = sk_SRP_user_pwd_value(vb->users_pwd, i);
if (strcmp(user->id,username)==0)
return user;
}
- if ((vb->seed_key == NULL) ||
- (vb->default_g == NULL) ||
- (vb->default_N == NULL))
- return NULL;
+
+ return NULL;
+}
+
+/*
+ * This method ignores the configured seed and fails for an unknown user.
+ * Ownership of the returned pointer is not released to the caller.
+ * In other words, caller must not free the result.
+ */
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+{
+ return find_user(vb, username);
+}
+
+/*
+ * Ownership of the returned pointer is released to the caller.
+ * In other words, caller must free the result once done.
+ */
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
+{
+ SRP_user_pwd *user;
+ unsigned char digv[SHA_DIGEST_LENGTH];
+ unsigned char digs[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX ctxt;
+
+ if (vb == NULL)
+ return NULL;
+
+ if ((user = find_user(vb, username)) != NULL)
+ return srp_user_pwd_dup(user);
+
+ if ((vb->seed_key == NULL) ||
+ (vb->default_g == NULL) || (vb->default_N == NULL))
+ return NULL;
/* if the user is unknown we set parameters as well if we have a seed_key */
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1806,6 +1806,8 @@
ASN1_UTCTIME_get 2350 NOEXIST::FUNCTION:
X509_REQ_digest 2362 EXIST::FUNCTION:EVP
X509_CRL_digest 2391 EXIST::FUNCTION:EVP
+SRP_VBASE_get1_by_user 2393 EXIST::FUNCTION:SRP
+SRP_user_pwd_free 2394 EXIST::FUNCTION:SRP
d2i_ASN1_SET_OF_PKCS7 2397 NOEXIST::FUNCTION:
EVP_CIPHER_CTX_set_key_length 2399 EXIST::FUNCTION:
EVP_CIPHER_CTX_ctrl 2400 EXIST::FUNCTION:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rt-4218.patch
Type: text/x-patch
Size: 2380 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-openssl-devel/attachments/20160226/b3ab57cf/attachment-0006.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CVE-2016-0799.patch
Type: text/x-patch
Size: 12410 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-openssl-devel/attachments/20160226/b3ab57cf/attachment-0007.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gh714.patch
Type: text/x-patch
Size: 179 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-openssl-devel/attachments/20160226/b3ab57cf/attachment-0008.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: symbols.patch
Type: text/x-patch
Size: 274 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-openssl-devel/attachments/20160226/b3ab57cf/attachment-0009.bin>
More information about the Pkg-openssl-devel
mailing list