[openssl-commits] [openssl] OpenSSL source code branch OpenSSL_0_9_8-stable updated. OpenSSL_0_9_8zc-21-gec2fede

Dr. Stephen Henson steve at openssl.org
Mon Jan 5 16:47:52 UTC 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "OpenSSL source code".

The branch, OpenSSL_0_9_8-stable has been updated
       via  ec2fede9467ae1a65f452d3a39f7fbc4891d9285 (commit)
       via  63f3c9e715955f0cdc83698d8a3dfb1b80064407 (commit)
       via  c22e2dd6e52899926d1f1ee3a2b5b9570d03130f (commit)
      from  7fae32f6d69baf27ef69d92499c59c8a3277f3e3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ec2fede9467ae1a65f452d3a39f7fbc4891d9285
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sat Dec 20 15:09:50 2014 +0000

    Fix various certificate fingerprint issues.
    
    By using non-DER or invalid encodings outside the signed portion of a
    certificate the fingerprint can be changed without breaking the signature.
    Although no details of the signed portion of the certificate can be changed
    this can cause problems with some applications: e.g. those using the
    certificate fingerprint for blacklists.
    
    1. Reject signatures with non zero unused bits.
    
    If the BIT STRING containing the signature has non zero unused bits reject
    the signature. All current signature algorithms require zero unused bits.
    
    2. Check certificate algorithm consistency.
    
    Check the AlgorithmIdentifier inside TBS matches the one in the
    certificate signature. NB: this will result in signature failure
    errors for some broken certificates.
    
    3. Check DSA/ECDSA signatures use DER.
    
    Reencode DSA/ECDSA signatures and compare with the original received
    signature. Return an error if there is a mismatch.
    
    This will reject various cases including garbage after signature
    (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS
    program for discovering this case) and use of BER or invalid ASN.1 INTEGERs
    (negative or with leading zeroes).
    
    CVE-2014-8275
    Reviewed-by: Emilia Käsper <emilia at openssl.org>
    
    (cherry picked from commit 208a6012be3077d83df4475f32dd1b1446f3a02e)
    
    Conflicts:
    	crypto/dsa/dsa_vrf.c

commit 63f3c9e715955f0cdc83698d8a3dfb1b80064407
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Jan 5 15:35:55 2015 +0000

    Update ordinals.
    
    Reviewed-by: Emilia Käsper <emilia at openssl.org>

commit c22e2dd6e52899926d1f1ee3a2b5b9570d03130f
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sun Dec 14 23:14:15 2014 +0000

    Add ASN1_TYPE_cmp and X509_ALGOR_cmp.
    
    (these are needed for certificate fingerprint fixes)
    Reviewed-by: Emilia Käsper <emilia at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 CHANGES                |   37 ++++++++++++++++++++++++++++++++++++-
 crypto/asn1/a_type.c   |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 crypto/asn1/a_verify.c |   12 ++++++++++++
 crypto/asn1/asn1.h     |    1 +
 crypto/asn1/x_algor.c  |   10 ++++++++++
 crypto/dsa/dsa_asn1.c  |   16 ++++++++++++++--
 crypto/ecdsa/ecs_vrf.c |   15 ++++++++++++++-
 crypto/x509/x509.h     |    1 +
 crypto/x509/x_all.c    |    2 ++
 util/libeay.num        |    2 ++
 10 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/CHANGES b/CHANGES
index d236eea..60a4596 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,7 +4,42 @@
 
  Changes between 0.9.8zc and 0.9.8zd [xx XXX xxxx]
 
-  *)
+  *) Fix various certificate fingerprint issues.
+
+     By using non-DER or invalid encodings outside the signed portion of a
+     certificate the fingerprint can be changed without breaking the signature.
+     Although no details of the signed portion of the certificate can be changed
+     this can cause problems with some applications: e.g. those using the
+     certificate fingerprint for blacklists.
+
+     1. Reject signatures with non zero unused bits.
+
+     If the BIT STRING containing the signature has non zero unused bits reject
+     the signature. All current signature algorithms require zero unused bits.
+
+     2. Check certificate algorithm consistency.
+
+     Check the AlgorithmIdentifier inside TBS matches the one in the
+     certificate signature. NB: this will result in signature failure
+     errors for some broken certificates.
+
+     Thanks to Konrad Kraszewski from Google for reporting this issue.
+
+     3. Check DSA/ECDSA signatures use DER.
+
+     Reencode DSA/ECDSA signatures and compare with the original received
+     signature. Return an error if there is a mismatch.
+
+     This will reject various cases including garbage after signature
+     (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS
+     program for discovering this case) and use of BER or invalid ASN.1 INTEGERs
+     (negative or with leading zeroes).
+
+     Further analysis was conducted and fixes were developed by Stephen Henson
+     of the OpenSSL core team.
+
+     (CVE-2014-8275)
+     [Steve Henson]
 
  Changes between 0.9.8zb and 0.9.8zc [15 Oct 2014]
 
diff --git a/crypto/asn1/a_type.c b/crypto/asn1/a_type.c
index 36becea..b7a95ad 100644
--- a/crypto/asn1/a_type.c
+++ b/crypto/asn1/a_type.c
@@ -108,3 +108,49 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
 
 IMPLEMENT_STACK_OF(ASN1_TYPE)
 IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+	{
+	int result = -1;
+
+	if (!a || !b || a->type != b->type) return -1;
+
+	switch (a->type)
+		{
+	case V_ASN1_OBJECT:
+		result = OBJ_cmp(a->value.object, b->value.object);
+		break;
+	case V_ASN1_NULL:
+		result = 0;	/* They do not have content. */
+		break;
+	case V_ASN1_INTEGER:
+	case V_ASN1_NEG_INTEGER:
+	case V_ASN1_ENUMERATED:
+	case V_ASN1_NEG_ENUMERATED:
+	case V_ASN1_BIT_STRING:
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_SEQUENCE:
+	case V_ASN1_SET:
+	case V_ASN1_NUMERICSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_VIDEOTEXSTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+	case V_ASN1_GRAPHICSTRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_OTHER:
+	default:
+		result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
+					 (ASN1_STRING *) b->value.ptr);
+		break;
+		}
+
+	return result;
+	}
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 7ded69b..3ef363d 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -89,6 +89,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
 		ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
 		goto err;
 		}
+
+	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+		goto err;
+		}
 	
 	inl=i2d(data,NULL);
 	buf_in=OPENSSL_malloc((unsigned int)inl);
@@ -144,6 +150,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
 		return -1;
 		}
 
+	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+		return -1;
+		}
+
 	EVP_MD_CTX_init(&ctx);
 	i=OBJ_obj2nid(a->algorithm);
 	type=EVP_get_digestbyname(OBJ_nid2sn(i));
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index aeb3f4c..bd7af2d 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -769,6 +769,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
 int ASN1_TYPE_get(ASN1_TYPE *a);
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int            ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
 
 ASN1_OBJECT *	ASN1_OBJECT_new(void );
 void		ASN1_OBJECT_free(ASN1_OBJECT *a);
diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c
index 99e5342..acc41ba 100644
--- a/crypto/asn1/x_algor.c
+++ b/crypto/asn1/x_algor.c
@@ -128,3 +128,13 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
 		}
 	}
 
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+	{
+	int rv;
+	rv = OBJ_cmp(a->algorithm, b->algorithm);
+	if (rv)
+		return rv;
+	if (!a->parameter && !b->parameter)
+		return 0;
+	return ASN1_TYPE_cmp(a->parameter, b->parameter);
+	}
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index bc7d7a0..08d4772 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -200,7 +200,11 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
 	     const unsigned char *sigbuf, int siglen, DSA *dsa)
 	{
 	DSA_SIG *s;
+	const unsigned char *p = sigbuf;
+	unsigned char *der = NULL;
+	int derlen = -1;
 	int ret=-1;
+
 #ifdef OPENSSL_FIPS
 	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
 		{
@@ -211,10 +215,18 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
 
 	s = DSA_SIG_new();
 	if (s == NULL) return(ret);
-	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+	if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
+	/* Ensure signature uses DER and doesn't have trailing garbage */
+	derlen = i2d_DSA_SIG(s, &der);
+	if (derlen != siglen || memcmp(sigbuf, der, derlen))
+		goto err;
 	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
 err:
+	if (derlen > 0)
+		{
+		OPENSSL_cleanse(der, derlen);
+		OPENSSL_free(der);
+		}
 	DSA_SIG_free(s);
 	return(ret);
 	}
-
diff --git a/crypto/ecdsa/ecs_vrf.c b/crypto/ecdsa/ecs_vrf.c
index ef9acf7..2836efe 100644
--- a/crypto/ecdsa/ecs_vrf.c
+++ b/crypto/ecdsa/ecs_vrf.c
@@ -57,6 +57,7 @@
  */
 
 #include "ecs_locl.h"
+#include "cryptlib.h"
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
 		const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
  	{
 	ECDSA_SIG *s;
+	const unsigned char *p = sigbuf;
+	unsigned char *der = NULL;
+	int derlen = -1;
 	int ret=-1;
 
 	s = ECDSA_SIG_new();
 	if (s == NULL) return(ret);
-	if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
+	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
+	/* Ensure signature uses DER and doesn't have trailing garbage */
+	derlen = i2d_ECDSA_SIG(s, &der);
+	if (derlen != sig_len || memcmp(sigbuf, der, derlen))
+		goto err;
 	ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
 err:
+	if (derlen > 0)
+		{
+		OPENSSL_cleanse(der, derlen);
+		OPENSSL_free(der);
+		}
 	ECDSA_SIG_free(s);
 	return(ret);
 	}
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index c34689a..e77ee69 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -870,6 +870,7 @@ X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
 int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
 void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
 						X509_ALGOR *algor);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
 
 X509_NAME *X509_NAME_dup(X509_NAME *xn);
 X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index c7b07f7..f4c68fc 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -73,6 +73,8 @@
 
 int X509_verify(X509 *a, EVP_PKEY *r)
 	{
+	if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+		return 0;
 	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
 		a->signature,a->cert_info,r));
 	}
diff --git a/util/libeay.num b/util/libeay.num
index f3b7776..b2f9e45 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1807,6 +1807,7 @@ ASN1_UTCTIME_get                        2350	NOEXIST::FUNCTION:
 X509_REQ_digest                         2362	EXIST::FUNCTION:EVP
 X509_CRL_digest                         2391	EXIST::FUNCTION:EVP
 d2i_ASN1_SET_OF_PKCS7                   2397	NOEXIST::FUNCTION:
+X509_ALGOR_cmp                          2398	EXIST::FUNCTION:
 EVP_CIPHER_CTX_set_key_length           2399	EXIST::FUNCTION:
 EVP_CIPHER_CTX_ctrl                     2400	EXIST::FUNCTION:
 BN_mod_exp_mont_word                    2401	EXIST::FUNCTION:
@@ -3730,3 +3731,4 @@ JPAKE_STEP2_init                        4113	EXIST::FUNCTION:JPAKE
 pqueue_size                             4114	EXIST::FUNCTION:
 OPENSSL_uni2asc                         4115	EXIST:NETWARE:FUNCTION:
 OPENSSL_asc2uni                         4116	EXIST:NETWARE:FUNCTION:
+ASN1_TYPE_cmp                           4428	EXIST::FUNCTION:


hooks/post-receive
-- 
OpenSSL source code


More information about the openssl-commits mailing list