diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2015-01-28 04:14:32 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2015-01-28 04:14:32 +0000 |
commit | bbd6bf84a2c283dc5e8a632ef771dc8d2fcf1586 (patch) | |
tree | e4430735bebdd058efd10a3fd4cc1f1e584a9f8f /lib | |
parent | 129ce8d7da6803fc1239aa28248901b414b1bec1 (diff) |
Fix a number of issues relating to algorithms in signatures, Mostly
from OpenSSL with a hint of boring and some things done here. Addresses
CVE-2014-8275 for OpenSSL fully
ok miod@ doug@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libcrypto/asn1/a_verify.c | 9 | ||||
-rw-r--r-- | lib/libcrypto/asn1/asn1.h | 3 | ||||
-rw-r--r-- | lib/libcrypto/asn1/x_algor.c | 16 | ||||
-rw-r--r-- | lib/libcrypto/dsa/dsa_asn1.c | 16 | ||||
-rw-r--r-- | lib/libcrypto/ecdsa/ecs_vrf.c | 16 | ||||
-rw-r--r-- | lib/libcrypto/x509/x509.h | 3 | ||||
-rw-r--r-- | lib/libcrypto/x509/x_all.c | 4 |
7 files changed, 58 insertions, 9 deletions
diff --git a/lib/libcrypto/asn1/a_verify.c b/lib/libcrypto/asn1/a_verify.c index ea937cab3ac..3fc79b78f6f 100644 --- a/lib/libcrypto/asn1/a_verify.c +++ b/lib/libcrypto/asn1/a_verify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_verify.c,v 1.20 2014/07/11 08:44:47 jsing Exp $ */ +/* $OpenBSD: a_verify.c,v 1.21 2015/01/28 04:14:31 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -85,6 +85,13 @@ ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, 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/lib/libcrypto/asn1/asn1.h b/lib/libcrypto/asn1/asn1.h index a1cc7188568..5ec89db3f00 100644 --- a/lib/libcrypto/asn1/asn1.h +++ b/lib/libcrypto/asn1/asn1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1.h,v 1.28 2014/06/12 15:49:27 deraadt Exp $ */ +/* $OpenBSD: asn1.h,v 1.29 2015/01/28 04:14:31 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1279,6 +1279,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 --git a/lib/libcrypto/asn1/x_algor.c b/lib/libcrypto/asn1/x_algor.c index c069a5225c8..71aeaaade07 100644 --- a/lib/libcrypto/asn1/x_algor.c +++ b/lib/libcrypto/asn1/x_algor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x_algor.c,v 1.12 2014/06/12 15:49:27 deraadt Exp $ */ +/* $OpenBSD: x_algor.c,v 1.13 2015/01/28 04:14:31 beck Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -136,3 +136,17 @@ X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); } + +/* Returns 0 if they are equal, != 0 otherwise. */ +int +X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) +{ + int rv = OBJ_cmp(a->algorithm, b->algorithm); + if (!rv) { + if (!a->parameter && !b->parameter) + rv = 0; + else + rv = ASN1_TYPE_cmp(a->parameter, b->parameter); + } + return(rv); +} diff --git a/lib/libcrypto/dsa/dsa_asn1.c b/lib/libcrypto/dsa/dsa_asn1.c index 7040b5a6729..16cb1fa3795 100644 --- a/lib/libcrypto/dsa/dsa_asn1.c +++ b/lib/libcrypto/dsa/dsa_asn1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsa_asn1.c,v 1.13 2014/10/18 17:20:40 jsing Exp $ */ +/* $OpenBSD: dsa_asn1.c,v 1.14 2015/01/28 04:14:31 beck Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -57,6 +57,7 @@ */ #include <stdio.h> +#include <string.h> #include <openssl/asn1.h> #include <openssl/asn1t.h> @@ -181,15 +182,26 @@ DSA_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int siglen, DSA *dsa) { DSA_SIG *s; + unsigned char *der = NULL; + const unsigned char *p = sigbuf; + int derlen = -1; int ret = -1; s = DSA_SIG_new(); if (s == NULL) return ret; - if (d2i_DSA_SIG(&s, &sigbuf, siglen) == NULL) + 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) { + explicit_bzero(der, derlen); + free(der); + } DSA_SIG_free(s); return ret; } diff --git a/lib/libcrypto/ecdsa/ecs_vrf.c b/lib/libcrypto/ecdsa/ecs_vrf.c index 40a677c46a9..b1e66af80a0 100644 --- a/lib/libcrypto/ecdsa/ecs_vrf.c +++ b/lib/libcrypto/ecdsa/ecs_vrf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecs_vrf.c,v 1.3 2014/07/10 22:45:57 jsing Exp $ */ +/* $OpenBSD: ecs_vrf.c,v 1.4 2015/01/28 04:14:31 beck Exp $ */ /* * Written by Nils Larsch for the OpenSSL project */ @@ -56,6 +56,7 @@ * */ +#include <string.h> #include <openssl/opensslconf.h> #include "ecs_locl.h" @@ -86,13 +87,24 @@ 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; + unsigned char *der = NULL; + const unsigned char *p = sigbuf; + 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) { + explicit_bzero(der, derlen); + free(der); + } ECDSA_SIG_free(s); return(ret); } diff --git a/lib/libcrypto/x509/x509.h b/lib/libcrypto/x509/x509.h index e425949675d..d67a87df0b6 100644 --- a/lib/libcrypto/x509/x509.h +++ b/lib/libcrypto/x509/x509.h @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.h,v 1.20 2014/06/12 15:49:31 deraadt Exp $ */ +/* $OpenBSD: x509.h,v 1.21 2015/01/28 04:14:31 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -758,6 +758,7 @@ 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); 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); diff --git a/lib/libcrypto/x509/x_all.c b/lib/libcrypto/x509/x_all.c index edb5f520fac..28a81c14a78 100644 --- a/lib/libcrypto/x509/x_all.c +++ b/lib/libcrypto/x509/x_all.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x_all.c,v 1.18 2014/07/11 08:44:49 jsing Exp $ */ +/* $OpenBSD: x_all.c,v 1.19 2015/01/28 04:14:31 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -76,6 +76,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)); } |