[openssl-commits] [openssl] OpenSSL source code branch OpenSSL_1_0_0-stable updated. OpenSSL_1_0_0o-55-g208a601

Dr. Stephen Henson steve at openssl.org
Mon Jan 5 15:43:56 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_1_0_0-stable has been updated
       via  208a6012be3077d83df4475f32dd1b1446f3a02e (commit)
       via  d7f8a7cafd9458a18de16c7662b9f7d07c1efe49 (commit)
       via  0f1c30b00d3ede3e735dd9c740cf4cd5881c59cb (commit)
      from  c4b969639a4ace587f67b7cda86f8fbdcb0e79ce (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 208a6012be3077d83df4475f32dd1b1446f3a02e
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 684400ce192dac51df3d3e92b61830a6ef90be3e)
    
    Conflicts:
    	CHANGES
    	crypto/dsa/dsa_asn1.c

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

    Constify ASN1_TYPE_cmp add X509_ALGOR_cmp.
    
    Reviewed-by: Emilia Käsper <emilia at openssl.org>
    (cherry picked from commit 4c52816d35681c0533c25fdd3abb4b7c6962302d)
    
    Conflicts:
    	crypto/asn1/x_algor.c
    	crypto/x509/x509.h

commit 0f1c30b00d3ede3e735dd9c740cf4cd5881c59cb
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Dec 17 14:34:36 2014 +0000

    Reject invalid constructed encodings.
    
    According to X6.90 null, object identifier, boolean, integer and enumerated
    types can only have primitive encodings: return an error if any of
    these are received with a constructed encoding.
    Reviewed-by: Emilia Käsper <emilia at openssl.org>
    
    (cherry picked from commit f5e4b6b5b566320a8d774f9475540f7d0e6a704d)
    
    Conflicts:
    	crypto/asn1/asn1_err.c

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

Summary of changes:
 CHANGES                |   37 ++++++++++++++++++++++++++++++++++++-
 crypto/asn1/a_type.c   |    2 +-
 crypto/asn1/a_verify.c |   12 ++++++++++++
 crypto/asn1/asn1.h     |    3 ++-
 crypto/asn1/asn1_err.c |    3 ++-
 crypto/asn1/tasn_dec.c |    8 ++++++++
 crypto/asn1/x_algor.c  |   10 ++++++++++
 crypto/dsa/dsa_vrf.c   |   14 +++++++++++++-
 crypto/ecdsa/ecs_vrf.c |   15 ++++++++++++++-
 crypto/x509/x509.h     |    1 +
 crypto/x509/x_all.c    |    2 ++
 11 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/CHANGES b/CHANGES
index 7c96384..8e8646e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,7 +4,42 @@
 
  Changes between 1.0.0o and 1.0.0p [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 1.0.0n and 1.0.0o [15 Oct 2014]
 
diff --git a/crypto/asn1/a_type.c b/crypto/asn1/a_type.c
index a45d2f9..5e1bc76 100644
--- a/crypto/asn1/a_type.c
+++ b/crypto/asn1/a_type.c
@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
 IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
 
 /* Returns 0 if they are equal, != 0 otherwise. */
-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
 	{
 	int result = -1;
 
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 097ec81..a75c8c9 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -90,6 +90,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);
@@ -142,6 +148,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);
 
 	/* Convert signature OID into digest and public key OIDs */
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index f6f491f..689ef8a 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -777,7 +777,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(ASN1_TYPE *a, ASN1_TYPE *b);
+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);
@@ -1377,6 +1377,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_TIME_NOT_ASCII_FORMAT			 193
 #define ASN1_R_TOO_LONG					 155
 #define ASN1_R_TYPE_NOT_CONSTRUCTED			 156
+#define ASN1_R_TYPE_NOT_PRIMITIVE			 218
 #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
 #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
 #define ASN1_R_UNEXPECTED_EOC				 159
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index 35293f2..59a35e1 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
 /* crypto/asn1/asn1_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2014 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -293,6 +293,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
 {ERR_REASON(ASN1_R_TOO_LONG)             ,"too long"},
 {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
+{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE)   ,"type not primitive"},
 {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
 {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
 {ERR_REASON(ASN1_R_UNEXPECTED_EOC)       ,"unexpected eoc"},
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 87d7dfd..2cbfa81 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -870,6 +870,14 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
 		}
 	else if (cst)
 		{
+		if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+			|| utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+			|| utype == V_ASN1_ENUMERATED)
+			{
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+				ASN1_R_TYPE_NOT_PRIMITIVE);
+			return 0;
+			}
 		buf.length = 0;
 		buf.max = 0;
 		buf.data = NULL;
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_vrf.c b/crypto/dsa/dsa_vrf.c
index 226a75f..9a6905b 100644
--- a/crypto/dsa/dsa_vrf.c
+++ b/crypto/dsa/dsa_vrf.c
@@ -77,13 +77,25 @@ 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;
 
 	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 e6f8a40..2900777 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -763,6 +763,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 8ec88c2..3571bf0 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -72,6 +72,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));
 	}


hooks/post-receive
-- 
OpenSSL source code


More information about the openssl-commits mailing list