File openssl-CVE-2016-0705.patch of Package openssl.openSUSE_13.2_Update
commit 6c88c71b4e4825c7bc0489306d062d017634eb88
Author: Dr. Stephen Henson <steve@openssl.org>
Date: Thu Feb 18 12:47:23 2016 +0000
Fix double free in DSA private key parsing.
Fix double free bug when parsing malformed DSA private keys.
Thanks to Adam Langley (Google/BoringSSL) for discovering this bug using
libFuzzer.
CVE-2016-0705
Reviewed-by: Emilia Käsper <emilia@openssl.org>
Index: openssl-1.0.1k/crypto/dsa/dsa_ameth.c
===================================================================
--- openssl-1.0.1k.orig/crypto/dsa/dsa_ameth.c 2016-03-01 11:22:12.722859225 +0100
+++ openssl-1.0.1k/crypto/dsa/dsa_ameth.c 2016-03-01 11:22:14.110881247 +0100
@@ -201,6 +201,8 @@ static int dsa_priv_decode(EVP_PKEY *pke
STACK_OF(ASN1_TYPE) *ndsa = NULL;
DSA *dsa = NULL;
+ int ret = 0;
+
if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);
@@ -281,23 +283,21 @@ static int dsa_priv_decode(EVP_PKEY *pke
}
EVP_PKEY_assign_DSA(pkey, dsa);
- BN_CTX_free (ctx);
- if(ndsa)
- sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
- else
- ASN1_INTEGER_free(privkey);
- return 1;
+ ret = 1;
+ goto done;
decerr:
- DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
+ DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR);
dsaerr:
- BN_CTX_free (ctx);
- if (privkey)
- ASN1_INTEGER_free(privkey);
- sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
DSA_free(dsa);
- return 0;
+ done:
+ BN_CTX_free(ctx);
+ if (ndsa)
+ sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+ else
+ ASN1_STRING_clear_free(privkey);
+ return ret;
}
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
Index: openssl-1.0.1k/crypto/asn1/asn1_lib.c
===================================================================
--- openssl-1.0.1k.orig/crypto/asn1/asn1_lib.c 2016-03-01 11:22:12.966863096 +0100
+++ openssl-1.0.1k/crypto/asn1/asn1_lib.c 2016-03-01 11:22:14.110881247 +0100
@@ -446,6 +446,13 @@ void ASN1_STRING_free(ASN1_STRING *a)
OPENSSL_free(a);
}
+void ASN1_STRING_clear_free(ASN1_STRING *a)
+{
+ if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+ OPENSSL_cleanse(a->data, a->length);
+ ASN1_STRING_free(a);
+}
+
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int i;