diff -up openssl-1.0.1e/crypto/asn1/a_bitstr.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/a_bitstr.c
--- openssl-1.0.1e/crypto/asn1/a_bitstr.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/a_bitstr.c 2015-01-13 12:23:36.090478923 +0100
@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN
p= *pp;
i= *(p++);
+ if (i > 7)
+ {
+ i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
+ goto err;
+ }
/* We do this to preserve the settings. If we modify
* the settings, via the _set_bit function, we will recalculate
* on output */
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
+ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
if (len-- > 1) /* using one because of the bits left byte */
{
diff -up openssl-1.0.1e/crypto/asn1/asn1_err.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/asn1_err.c
--- openssl-1.0.1e/crypto/asn1/asn1_err.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/asn1_err.c 2015-01-13 12:23:36.090478923 +0100
@@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
+{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
diff -up openssl-1.0.1e/crypto/asn1/asn1.h.cert-fingerprint openssl-1.0.1e/crypto/asn1/asn1.h
--- openssl-1.0.1e/crypto/asn1/asn1.h.cert-fingerprint 2015-01-13 11:44:11.999013082 +0100
+++ openssl-1.0.1e/crypto/asn1/asn1.h 2015-01-13 12:23:36.090478923 +0100
@@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(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);
@@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_ILLEGAL_TIME_VALUE 184
#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
+#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
#define ASN1_R_INVALID_DIGIT 130
#define ASN1_R_INVALID_MIME_TYPE 205
diff -up openssl-1.0.1e/crypto/asn1/a_type.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/a_type.c
--- openssl-1.0.1e/crypto/asn1/a_type.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/a_type.c 2015-01-13 12:43:36.779633480 +0100
@@ -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 -up openssl-1.0.1e/crypto/asn1/a_verify.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/a_verify.c
--- openssl-1.0.1e/crypto/asn1/a_verify.c.cert-fingerprint 2015-01-13 11:44:12.308020070 +0100
+++ openssl-1.0.1e/crypto/asn1/a_verify.c 2015-01-13 11:44:12.413022445 +0100
@@ -93,6 +93,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_A
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);
@@ -149,6 +155,12 @@ int ASN1_item_verify(const ASN1_ITEM *it
return -1;
}
+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_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 -up openssl-1.0.1e/crypto/asn1/x_algor.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/x_algor.c
--- openssl-1.0.1e/crypto/asn1/x_algor.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/x_algor.c 2015-01-13 12:43:36.780633502 +0100
@@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg,
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}
+
+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 -up openssl-1.0.1e/crypto/dsa/dsa_asn1.c.cert-fingerprint openssl-1.0.1e/crypto/dsa/dsa_asn1.c
--- openssl-1.0.1e/crypto/dsa/dsa_asn1.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/dsa/dsa_asn1.c 2015-01-13 11:44:12.414022468 +0100
@@ -176,13 +176,25 @@ int DSA_verify(int type, const unsigned
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 -up openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c.cert-fingerprint openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c
--- openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c.cert-fingerprint 2013-02-11 16:02:48.000000000 +0100
+++ openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c 2015-01-13 11:44:12.414022468 +0100
@@ -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 unsigne
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 -up openssl-1.0.1e/crypto/x509/x_all.c.cert-fingerprint openssl-1.0.1e/crypto/x509/x_all.c
--- openssl-1.0.1e/crypto/x509/x_all.c.cert-fingerprint 2015-01-13 11:44:12.330020568 +0100
+++ openssl-1.0.1e/crypto/x509/x_all.c 2015-01-13 11:44:12.414022468 +0100
@@ -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));
}
diff -up openssl-1.0.1e/crypto/x509/x509.h.cert-fingerprint openssl-1.0.1e/crypto/x509/x509.h
--- openssl-1.0.1e/crypto/x509/x509.h.cert-fingerprint 2015-01-13 11:44:12.126015954 +0100
+++ openssl-1.0.1e/crypto/x509/x509.h 2015-01-13 12:43:36.780633502 +0100
@@ -768,6 +768,7 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor);
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+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);