Compare commits

...

9 Commits
master ... f22

Author SHA1 Message Date
Tomas Mraz bfc1772d6e Multiple security issues fixed.
- fix CVE-2016-2105 - possible overflow in base64 encoding
- fix CVE-2016-2106 - possible overflow in EVP_EncryptUpdate()
- fix CVE-2016-2107 - padding oracle in stitched AES-NI CBC-MAC
- fix CVE-2016-2108 - memory corruption in ASN.1 encoder
- fix CVE-2016-2109 - possible DoS when reading ASN.1 data from BIO
2016-05-03 18:29:16 +02:00
Tomas Mraz 94b1a89708 Add missing file. 2016-03-02 11:05:10 +01:00
Tomas Mraz 0fa091c0ff Fix multiple security issues.
- fix CVE-2016-0702 - side channel attack on modular exponentiation
- fix CVE-2016-0705 - double-free in DSA private key parsing
- fix CVE-2016-0797 - heap corruption in BN_hex2bn and BN_dec2bn
- fix CVE-2015-3197 - SSLv2 ciphersuite enforcement
- fix CVE-2015-7575 - disallow use of MD5 in TLS1.2
- fix CVE-2016-0799 - memory issues in BIO_*printf functions
2016-03-02 11:00:13 +01:00
Tomas Mraz 85a2d8a93c Multiple security issues fixed
- fix CVE-2015-3194 - certificate verify crash with missing PSS parameter
- fix CVE-2015-3195 - X509_ATTRIBUTE memory leak
- fix CVE-2015-3196 - race condition when handling PSK identity hint
- filter out unwanted link options from the .pc files (#1257836)
2015-12-04 16:38:05 +01:00
Tom Callaway 1c2ab61fa1 enable secp256k1 2015-08-13 08:09:25 -04:00
Tomas Mraz 929846e5d1 fix CVE-2015-1793 - certificate verification forgery 2015-07-09 15:36:41 +02:00
Tomas Mraz 546bf977b5 Fix multiple security issues.
- fix CVE-2015-1789 - out-of-bounds read in X509_cmp_time
- fix CVE-2015-1790 - PKCS7 crash with missing EncryptedContent
- fix CVE-2015-1791 - race condition handling NewSessionTicket
- fix CVE-2015-1792 - CMS verify infinite loop with unknown hash function
- add missing parts of CVE-2015-0209 fix for corectness although unexploitable
2015-06-15 17:09:29 +02:00
Tomas Mraz a3963e794f fix CVE-2015-4000 - prevent the logjam attack on client
- restrict the DH key size to at least 768 bits (limit will be increased
  in future)
2015-05-29 16:07:30 +02:00
Tomas Mraz fc6854bd38 try to find alternative cert chains (#1166614) 2015-04-30 15:08:45 +02:00
23 changed files with 3357 additions and 1 deletions

View File

@ -0,0 +1,103 @@
diff -up openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read openssl-1.0.1e/crypto/x509/x509_vfy.c
--- openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read 2015-05-25 12:03:41.000000000 +0200
+++ openssl-1.0.1e/crypto/x509/x509_vfy.c 2015-06-09 15:01:51.688640453 +0200
@@ -1702,49 +1702,92 @@ int X509_cmp_time(const ASN1_TIME *ctm,
ASN1_TIME atm;
long offset;
char buff1[24],buff2[24],*p;
- int i,j;
+ int i, j, remaining;
p=buff1;
- i=ctm->length;
+ remaining=ctm->length;
str=(char *)ctm->data;
+ /*
+ * Note that the following (historical) code allows much more slack in the
+ * time format than RFC5280. In RFC5280, the representation is fixed:
+ * UTCTime: YYMMDDHHMMSSZ
+ * GeneralizedTime: YYYYMMDDHHMMSSZ
+ */
if (ctm->type == V_ASN1_UTCTIME)
{
- if ((i < 11) || (i > 17)) return 0;
+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+ int min_length = sizeof("YYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
memcpy(p,str,10);
p+=10;
str+=10;
+ remaining -= 10;
}
else
{
- if (i < 13) return 0;
+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
memcpy(p,str,12);
p+=12;
str+=12;
+ remaining -= 12;
}
if ((*str == 'Z') || (*str == '-') || (*str == '+'))
{ *(p++)='0'; *(p++)='0'; }
else
{
+ /* SS (seconds) */
+ if (remaining < 2)
+ return 0;
*(p++)= *(str++);
*(p++)= *(str++);
- /* Skip any fractional seconds... */
- if (*str == '.')
+ remaining -= 2;
+ /*
+ * Skip any (up to three) fractional seconds...
+ * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+ * Can we just kill them altogether?
+ */
+ if (remaining && *str == '.')
{
str++;
- while ((*str >= '0') && (*str <= '9')) str++;
+ remaining--;
+ for (i = 0; i < 3 && remaining; i++, str++, remaining--)
+ {
+ if (*str < '0' || *str > '9')
+ break;
+ }
}
}
*(p++)='Z';
*(p++)='\0';
+ /* We now need either a terminating 'Z' or an offset. */
+ if (!remaining)
+ return 0;
if (*str == 'Z')
+ {
+ if (remaining != 1)
+ return 0;
offset=0;
+ }
else
{
+ /* (+-)HHMM */
if ((*str != '+') && (*str != '-'))
return 0;
+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+ if (remaining != 5)
+ return 0;
+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+ return 0;
offset=((str[1]-'0')*10+(str[2]-'0'))*60;
offset+=(str[3]-'0')*10+(str[4]-'0');
if (*str == '-')

View File

@ -0,0 +1,55 @@
diff -up openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.missing-content openssl-1.0.1e/crypto/pkcs7/pk7_doit.c
--- openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.missing-content 2015-05-25 12:03:41.000000000 +0200
+++ openssl-1.0.1e/crypto/pkcs7/pk7_doit.c 2015-06-09 15:21:21.377951520 +0200
@@ -472,6 +472,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
switch (i)
{
case NID_pkcs7_signed:
+ /*
+ * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
+ * field and optional content.
+ * data_body is NULL if that structure has no (=detached) content
+ * or if the contentType is wrong (i.e., not "data").
+ */
data_body=PKCS7_get_octet_string(p7->d.sign->contents);
if (!PKCS7_is_detached(p7) && data_body == NULL)
{
@@ -484,6 +490,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
case NID_pkcs7_signedAndEnveloped:
rsk=p7->d.signed_and_enveloped->recipientinfo;
md_sk=p7->d.signed_and_enveloped->md_algs;
+ /* data_body is NULL if the optional EncryptedContent is missing. */
data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
@@ -496,6 +503,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
case NID_pkcs7_enveloped:
rsk=p7->d.enveloped->recipientinfo;
enc_alg=p7->d.enveloped->enc_data->algorithm;
+ /* data_body is NULL if the optional EncryptedContent is missing. */
data_body=p7->d.enveloped->enc_data->enc_data;
evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
if (evp_cipher == NULL)
@@ -509,6 +517,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
goto err;
}
+ /* Detached content must be supplied via in_bio instead. */
+ if (data_body == NULL && in_bio == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ goto err;
+ }
+
/* We will be checking the signature */
if (md_sk != NULL)
{
@@ -665,7 +680,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
}
#if 1
- if (PKCS7_is_detached(p7) || (in_bio != NULL))
+ if (in_bio != NULL)
{
bio=in_bio;
}

View File

@ -0,0 +1,12 @@
diff -up openssl-1.0.1e/crypto/cms/cms_smime.c.unknown-hash openssl-1.0.1e/crypto/cms/cms_smime.c
--- openssl-1.0.1e/crypto/cms/cms_smime.c.unknown-hash 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/cms/cms_smime.c 2015-06-09 16:07:16.001516190 +0200
@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *up
BIO_free(f);
f = tbio;
}
- while (f != upto);
+ while (f && f != upto);
}
else
BIO_free_all(f);

View File

@ -0,0 +1,12 @@
diff -up openssl-1.0.1e/crypto/rsa/rsa_ameth.c.pss-check openssl-1.0.1e/crypto/rsa/rsa_ameth.c
--- openssl-1.0.1e/crypto/rsa/rsa_ameth.c.pss-check 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/rsa/rsa_ameth.c 2015-12-04 09:03:18.300660817 +0100
@@ -287,7 +287,7 @@ static RSA_PSS_PARAMS *rsa_pss_decode(co
{
ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1
- && param->type == V_ASN1_SEQUENCE)
+ && param && param->type == V_ASN1_SEQUENCE)
{
p = param->value.sequence->data;
plen = param->value.sequence->length;

View File

@ -0,0 +1,31 @@
diff -up openssl-1.0.1e/crypto/asn1/tasn_dec.c.combine-leak openssl-1.0.1e/crypto/asn1/tasn_dec.c
--- openssl-1.0.1e/crypto/asn1/tasn_dec.c.combine-leak 2015-12-04 09:01:53.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/tasn_dec.c 2015-12-04 09:09:30.629793475 +0100
@@ -169,6 +169,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
int otag;
int ret = 0;
ASN1_VALUE **pchptr, *ptmpval;
+ int combine = aclass & ASN1_TFLG_COMBINE;
+ aclass &= ~ASN1_TFLG_COMBINE;
if (!pval)
return 0;
if (aux && aux->asn1_cb)
@@ -539,7 +541,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval,
auxerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
err:
- ASN1_item_ex_free(pval, it);
+ if (combine == 0)
+ ASN1_item_ex_free(pval, it);
if (errtt)
ERR_add_error_data(4, "Field=", errtt->field_name,
", Type=", it->sname);
@@ -767,7 +770,7 @@ static int asn1_template_noexp_d2i(ASN1_
{
/* Nothing special */
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
- -1, 0, opt, ctx);
+ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
if (!ret)
{
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,

View File

@ -0,0 +1,42 @@
diff -up openssl-1.0.1e/ssl/s2_srvr.c.ssl2-ciphers openssl-1.0.1e/ssl/s2_srvr.c
--- openssl-1.0.1e/ssl/s2_srvr.c.ssl2-ciphers 2016-01-14 17:38:50.000000000 +0100
+++ openssl-1.0.1e/ssl/s2_srvr.c 2016-02-16 16:18:59.790225008 +0100
@@ -392,7 +392,7 @@ static int get_client_master_key(SSL *s)
}
cp=ssl2_get_cipher_by_char(p);
- if (cp == NULL)
+ if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0)
{
ssl2_return_error(s,SSL2_PE_NO_CIPHER);
SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
@@ -692,9 +692,13 @@ static int get_client_hello(SSL *s)
prio = cs;
allow = cl;
}
+
+ /* Generate list of SSLv2 ciphers shared between client and server */
for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
{
- if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
+ const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z);
+ if ((cp->algorithm_ssl & SSL_SSLV2) == 0 ||
+ sk_SSL_CIPHER_find(allow,cp) < 0)
{
(void)sk_SSL_CIPHER_delete(prio,z);
z--;
@@ -705,6 +709,14 @@ static int get_client_hello(SSL *s)
sk_SSL_CIPHER_free(s->session->ciphers);
s->session->ciphers = prio;
}
+
+ /* Make sure we have at least one cipher in common */
+ if (sk_SSL_CIPHER_num(s->session->ciphers) == 0)
+ {
+ ssl2_return_error(s, SSL2_PE_NO_CIPHER);
+ SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH);
+ return -1;
+ }
/* s->session->ciphers should now have a list of
* ciphers that are on both the client and server.
* This list is ordered by the order the client sent

View File

@ -0,0 +1,45 @@
diff -up openssl-1.0.1e/crypto/dsa/dsa_ameth.c.dsa-doublefree openssl-1.0.1e/crypto/dsa/dsa_ameth.c
--- openssl-1.0.1e/crypto/dsa/dsa_ameth.c.dsa-doublefree 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/dsa/dsa_ameth.c 2016-02-24 14:38:46.075165304 +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:
- 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_INTEGER_free(privkey);
+ return ret;
}
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)

View File

@ -0,0 +1,74 @@
diff -up openssl-1.0.1e/crypto/bn/bn.h.bn-hex openssl-1.0.1e/crypto/bn/bn.h
--- openssl-1.0.1e/crypto/bn/bn.h.bn-hex 2016-02-24 14:23:33.020233047 +0100
+++ openssl-1.0.1e/crypto/bn/bn.h 2016-02-24 14:23:06.078615397 +0100
@@ -129,6 +129,7 @@
#ifndef OPENSSL_NO_FP_API
#include <stdio.h> /* FILE */
#endif
+#include <limits.h>
#include <openssl/ossl_typ.h>
#include <openssl/crypto.h>
@@ -640,7 +641,8 @@ const BIGNUM *BN_get0_nist_prime_521(voi
/* library internal functions */
-#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+#define bn_expand(a,bits) (bits > (INT_MAX - BN_BITS2 + 1)?\
+ NULL:(((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
BIGNUM *bn_expand2(BIGNUM *a, int words);
diff -up openssl-1.0.1e/crypto/bn/bn_print.c.bn-hex openssl-1.0.1e/crypto/bn/bn_print.c
--- openssl-1.0.1e/crypto/bn/bn_print.c.bn-hex 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/bn/bn_print.c 2016-02-24 14:15:21.215948376 +0100
@@ -58,6 +58,7 @@
#include <stdio.h>
#include <ctype.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include "bn_lcl.h"
@@ -180,8 +181,10 @@ int BN_hex2bn(BIGNUM **bn, const char *a
if (*a == '-') { neg=1; a++; }
- for (i=0; isxdigit((unsigned char) a[i]); i++)
+ for (i=0; i <= (INT_MAX/4) && isxdigit((unsigned char) a[i]); i++)
;
+ if (i > INT_MAX/4)
+ goto err;
num=i+neg;
if (bn == NULL) return(num);
@@ -197,7 +200,7 @@ int BN_hex2bn(BIGNUM **bn, const char *a
BN_zero(ret);
}
- /* i is the number of hex digests; */
+ /* i is the number of hex digits */
if (bn_expand(ret,i*4) == NULL) goto err;
j=i; /* least significant 'hex' */
@@ -246,8 +249,10 @@ int BN_dec2bn(BIGNUM **bn, const char *a
if ((a == NULL) || (*a == '\0')) return(0);
if (*a == '-') { neg=1; a++; }
- for (i=0; isdigit((unsigned char) a[i]); i++)
+ for (i=0; i <= (INT_MAX/4) && isdigit((unsigned char) a[i]); i++)
;
+ if (i > INT_MAX/4)
+ goto err;
num=i+neg;
if (bn == NULL) return(num);
@@ -264,7 +269,7 @@ int BN_dec2bn(BIGNUM **bn, const char *a
BN_zero(ret);
}
- /* i is the number of digests, a bit of an over expand; */
+ /* i is the number of digits, a bit of an over expand */
if (bn_expand(ret,i*4) == NULL) goto err;
j=BN_DEC_NUM-(i%BN_DEC_NUM);

View File

@ -0,0 +1,40 @@
diff -up openssl-1.0.1e/crypto/evp/encode.c.b64-overflow openssl-1.0.1e/crypto/evp/encode.c
--- openssl-1.0.1e/crypto/evp/encode.c.b64-overflow 2016-04-07 15:45:20.000000000 +0200
+++ openssl-1.0.1e/crypto/evp/encode.c 2016-04-29 12:46:34.232656522 +0200
@@ -132,12 +132,12 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ct
const unsigned char *in, int inl)
{
int i,j;
- unsigned int total=0;
+ size_t total=0;
*outl=0;
if (inl == 0) return;
OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
- if ((ctx->num+inl) < ctx->length)
+ if (ctx->length - ctx->num > inl)
{
memcpy(&(ctx->enc_data[ctx->num]),in,inl);
ctx->num+=inl;
@@ -156,7 +156,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ct
*out='\0';
total=j+1;
}
- while (inl >= ctx->length)
+ while (inl >= ctx->length && total <= INT_MAX)
{
j=EVP_EncodeBlock(out,in,ctx->length);
in+=ctx->length;
@@ -166,6 +166,12 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ct
*out='\0';
total+=j+1;
}
+ if (total > INT_MAX)
+ {
+ /* Too much output data! */
+ *outl = 0;
+ return;
+ }
if (inl != 0)
memcpy(&(ctx->enc_data[0]),in,inl);
ctx->num=inl;

View File

@ -0,0 +1,12 @@
diff -up openssl-1.0.1e/crypto/evp/evp_enc.c.enc-overflow openssl-1.0.1e/crypto/evp/evp_enc.c
--- openssl-1.0.1e/crypto/evp/evp_enc.c.enc-overflow 2016-04-29 12:42:43.000000000 +0200
+++ openssl-1.0.1e/crypto/evp/evp_enc.c 2016-04-29 12:56:50.253736555 +0200
@@ -408,7 +408,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ct
OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
if (i != 0)
{
- if (i+inl < bl)
+ if (bl - i > inl)
{
memcpy(&(ctx->buf[i]),in,inl);
ctx->buf_len+=inl;

View File

@ -0,0 +1,20 @@
diff -up openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c.padding-check openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c
--- openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c.padding-check 2016-04-29 12:42:43.000000000 +0200
+++ openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c 2016-04-29 13:10:13.441125487 +0200
@@ -59,6 +59,7 @@
#include <openssl/aes.h>
#include <openssl/sha.h>
#include "evp_locl.h"
+#include "constant_time_locl.h"
#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
@@ -278,6 +279,8 @@ static int aesni_cbc_hmac_sha1_cipher(EV
maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
maxpad &= 255;
+ ret &= constant_time_ge(maxpad, pad);
+
inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
inp_len &= mask;

View File

@ -0,0 +1,69 @@
diff -up openssl-1.0.1e/crypto/asn1/a_int.c.asn1-negative openssl-1.0.1e/crypto/asn1/a_int.c
--- openssl-1.0.1e/crypto/asn1/a_int.c.asn1-negative 2016-04-29 13:23:05.221797998 +0200
+++ openssl-1.0.1e/crypto/asn1/a_int.c 2016-04-29 13:26:51.030957218 +0200
@@ -124,6 +124,8 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, un
{
ret=a->length;
i=a->data[0];
+ if (ret == 1 && i == 0)
+ neg = 0;
if (!neg && (i > 127)) {
pad=1;
pb=0;
@@ -157,7 +159,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, un
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
- while(!*n) {
+ while(!*n && i > 1) {
*(p--) = 0;
n--;
i--;
@@ -415,7 +417,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const B
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
goto err;
}
- if (BN_is_negative(bn))
+ if (BN_is_negative(bn) && !BN_is_zero(bn))
ret->type = V_ASN1_NEG_INTEGER;
else ret->type=V_ASN1_INTEGER;
j=BN_num_bits(bn);
diff -up openssl-1.0.1e/crypto/asn1/a_type.c.asn1-negative openssl-1.0.1e/crypto/asn1/a_type.c
--- openssl-1.0.1e/crypto/asn1/a_type.c.asn1-negative 2016-04-29 12:42:43.000000000 +0200
+++ openssl-1.0.1e/crypto/asn1/a_type.c 2016-04-29 13:28:40.202443787 +0200
@@ -131,9 +131,7 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, co
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:
diff -up openssl-1.0.1e/crypto/asn1/tasn_dec.c.asn1-negative openssl-1.0.1e/crypto/asn1/tasn_dec.c
--- openssl-1.0.1e/crypto/asn1/tasn_dec.c.asn1-negative 2016-04-29 12:42:43.000000000 +0200
+++ openssl-1.0.1e/crypto/asn1/tasn_dec.c 2016-04-29 13:30:08.560456293 +0200
@@ -1011,9 +1011,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const
break;
case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
tint = (ASN1_INTEGER **)pval;
if (!c2i_ASN1_INTEGER(tint, &cont, len))
goto err;
diff -up openssl-1.0.1e/crypto/asn1/tasn_enc.c.asn1-negative openssl-1.0.1e/crypto/asn1/tasn_enc.c
--- openssl-1.0.1e/crypto/asn1/tasn_enc.c.asn1-negative 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/tasn_enc.c 2016-04-29 13:30:34.688051394 +0200
@@ -638,9 +638,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsig
break;
case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
/* These are all have the same content format
* as ASN1_INTEGER
*/

View File

@ -0,0 +1,72 @@
diff -up openssl-1.0.1e/crypto/asn1/a_d2i_fp.c.asn1-bio-dos openssl-1.0.1e/crypto/asn1/a_d2i_fp.c
--- openssl-1.0.1e/crypto/asn1/a_d2i_fp.c.asn1-bio-dos 2013-02-11 16:02:47.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/a_d2i_fp.c 2016-04-29 13:44:52.205538739 +0200
@@ -139,6 +139,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *
#endif
#define HEADER_SIZE 8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
@@ -230,6 +231,8 @@ static int asn1_d2i_read_bio(BIO *in, BU
want=c.slen;
if (want > (len-off))
{
+ size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+
want-=(len-off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
@@ -237,24 +240,38 @@ static int asn1_d2i_read_bio(BIO *in, BU
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
- if (!BUF_MEM_grow_clean(b,len+want))
- {
- ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
- goto err;
- }
while (want > 0)
{
- i=BIO_read(in,&(b->data[len]),want);
- if (i <= 0)
+ /*
+ * Read content in chunks of increasing size
+ * so we can return an error for EOF without
+ * having to allocate the entire content length
+ * in one go.
+ */
+ size_t chunk = want > chunk_max ? chunk_max : want;
+
+ if (!BUF_MEM_grow_clean(b, len + chunk))
{
- ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
- ASN1_R_NOT_ENOUGH_DATA);
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
goto err;
}
- /* This can't overflow because
- * |len+want| didn't overflow. */
- len+=i;
- want-=i;
+ want -= chunk;
+ while (chunk > 0)
+ {
+ i = BIO_read(in, &(b->data[len]), chunk);
+ if (i <= 0)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+ ASN1_R_NOT_ENOUGH_DATA);
+ goto err;
+ }
+ /* This can't overflow because
+ * |len+want| didn't overflow. */
+ len += i;
+ chunk -= i;
+ }
+ if (chunk_max < INT_MAX/2)
+ chunk_max *= 2;
}
}
if (off + c.slen < off)

View File

@ -11,3 +11,73 @@ diff -up openssl-1.0.1h/ssl/ssl_lib.c.v2v3 openssl-1.0.1h/ssl/ssl_lib.c
return(ret);
err:
SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
diff -up openssl-1.0.1e/doc/apps/ciphers.pod.disable-sslv2 openssl-1.0.1e/doc/apps/ciphers.pod
--- openssl-1.0.1e/doc/apps/ciphers.pod.disable-sslv2 2016-01-14 17:38:50.000000000 +0100
+++ openssl-1.0.1e/doc/apps/ciphers.pod 2016-02-24 11:17:36.297955053 +0100
@@ -572,11 +572,11 @@ Note: these ciphers can also be used in
=head2 Deprecated SSL v2.0 cipher suites.
SSL_CK_RC4_128_WITH_MD5 RC4-MD5
- SSL_CK_RC4_128_EXPORT40_WITH_MD5 EXP-RC4-MD5
- SSL_CK_RC2_128_CBC_WITH_MD5 RC2-MD5
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 EXP-RC2-MD5
+ SSL_CK_RC4_128_EXPORT40_WITH_MD5 Not implemented.
+ SSL_CK_RC2_128_CBC_WITH_MD5 RC2-CBC-MD5
+ SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 Not implemented.
SSL_CK_IDEA_128_CBC_WITH_MD5 IDEA-CBC-MD5
- SSL_CK_DES_64_CBC_WITH_MD5 DES-CBC-MD5
+ SSL_CK_DES_64_CBC_WITH_MD5 Not implemented.
SSL_CK_DES_192_EDE3_CBC_WITH_MD5 DES-CBC3-MD5
=head1 NOTES
diff -up openssl-1.0.1e/ssl/s2_lib.c.disable-sslv2 openssl-1.0.1e/ssl/s2_lib.c
--- openssl-1.0.1e/ssl/s2_lib.c.disable-sslv2 2016-02-24 11:23:24.012237164 +0100
+++ openssl-1.0.1e/ssl/s2_lib.c 2016-02-24 11:19:34.623773423 +0100
@@ -156,6 +156,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
128,
},
+#if 0
/* RC4_128_EXPORT40_WITH_MD5 */
{
1,
@@ -171,6 +172,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
40,
128,
},
+#endif
/* RC2_128_CBC_WITH_MD5 */
{
@@ -188,6 +190,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
128,
},
+#if 0
/* RC2_128_CBC_EXPORT40_WITH_MD5 */
{
1,
@@ -203,6 +206,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
40,
128,
},
+#endif
#ifndef OPENSSL_NO_IDEA
/* IDEA_128_CBC_WITH_MD5 */
@@ -222,6 +226,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
},
#endif
+#if 0
/* DES_64_CBC_WITH_MD5 */
{
1,
@@ -237,6 +242,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip
56,
56,
},
+#endif
/* DES_192_EDE3_CBC_WITH_MD5 */
{

View File

@ -0,0 +1,407 @@
diff -up openssl-1.0.1k/apps/apps.c.alt-chains openssl-1.0.1k/apps/apps.c
--- openssl-1.0.1k/apps/apps.c.alt-chains 2015-07-09 14:58:55.949753674 +0200
+++ openssl-1.0.1k/apps/apps.c 2015-07-09 14:58:55.970754174 +0200
@@ -2365,6 +2365,8 @@ int args_verify(char ***pargs, int *parg
flags |= X509_V_FLAG_NOTIFY_POLICY;
else if (!strcmp(arg, "-check_ss_sig"))
flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
+ else if (!strcmp(arg, "-no_alt_chains"))
+ flags |= X509_V_FLAG_NO_ALT_CHAINS;
else if (!strcmp(arg, "-trusted_first"))
flags |= X509_V_FLAG_TRUSTED_FIRST;
else
diff -up openssl-1.0.1k/apps/cms.c.alt-chains openssl-1.0.1k/apps/cms.c
--- openssl-1.0.1k/apps/cms.c.alt-chains 2015-07-09 14:58:55.949753674 +0200
+++ openssl-1.0.1k/apps/cms.c 2015-07-09 14:58:55.970754174 +0200
@@ -642,6 +642,7 @@ int MAIN(int argc, char **argv)
BIO_printf (bio_err, "-text include or delete text MIME headers\n");
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
+ BIO_printf (bio_err, "-no_alt_chains only ever use the first certificate chain found\n");
BIO_printf (bio_err, "-trusted_first use trusted certificates first when building the trust chain\n");
BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n");
BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
diff -up openssl-1.0.1k/apps/ocsp.c.alt-chains openssl-1.0.1k/apps/ocsp.c
--- openssl-1.0.1k/apps/ocsp.c.alt-chains 2015-07-09 14:58:55.949753674 +0200
+++ openssl-1.0.1k/apps/ocsp.c 2015-07-09 14:58:55.971754198 +0200
@@ -605,6 +605,7 @@ int MAIN(int argc, char **argv)
BIO_printf (bio_err, "-path path to use in OCSP request\n");
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
+ BIO_printf (bio_err, "-no_alt_chains only ever use the first certificate chain found\n");
BIO_printf (bio_err, "-trusted_first use trusted certificates first when building the trust chain\n");
BIO_printf (bio_err, "-VAfile file validator certificates file\n");
BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
diff -up openssl-1.0.1k/apps/s_client.c.alt-chains openssl-1.0.1k/apps/s_client.c
--- openssl-1.0.1k/apps/s_client.c.alt-chains 2015-07-09 14:58:55.956753841 +0200
+++ openssl-1.0.1k/apps/s_client.c 2015-07-09 14:58:55.971754198 +0200
@@ -299,6 +299,7 @@ static void sc_usage(void)
BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
+ BIO_printf(bio_err," -no_alt_chains - only ever use the first certificate chain found\n");
BIO_printf(bio_err," -trusted_first - Use trusted CA's first when building the trust chain\n");
BIO_printf(bio_err," -reconnect - Drop and re-make the connection with the same Session-ID\n");
BIO_printf(bio_err," -pause - sleep(1) after each read(2) and write(2) system call\n");
diff -up openssl-1.0.1k/apps/smime.c.alt-chains openssl-1.0.1k/apps/smime.c
--- openssl-1.0.1k/apps/smime.c.alt-chains 2015-07-09 14:58:55.950753698 +0200
+++ openssl-1.0.1k/apps/smime.c 2015-07-09 14:58:55.971754198 +0200
@@ -479,6 +479,7 @@ int MAIN(int argc, char **argv)
BIO_printf (bio_err, "-text include or delete text MIME headers\n");
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
+ BIO_printf (bio_err, "-no_alt_chains only ever use the first certificate chain found\n");
BIO_printf (bio_err, "-trusted_first use trusted certificates first when building the trust chain\n");
BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n");
BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
diff -up openssl-1.0.1k/apps/s_server.c.alt-chains openssl-1.0.1k/apps/s_server.c
--- openssl-1.0.1k/apps/s_server.c.alt-chains 2015-07-09 14:58:55.950753698 +0200
+++ openssl-1.0.1k/apps/s_server.c 2015-07-09 14:58:55.971754198 +0200
@@ -502,6 +502,7 @@ static void sv_usage(void)
BIO_printf(bio_err," -state - Print the SSL states\n");
BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
+ BIO_printf(bio_err," -no_alt_chains - only ever use the first certificate chain found\n");
BIO_printf(bio_err," -trusted_first - Use trusted CA's first when building the trust chain\n");
BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n");
BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n");
diff -up openssl-1.0.1k/apps/verify.c.alt-chains openssl-1.0.1k/apps/verify.c
--- openssl-1.0.1k/apps/verify.c.alt-chains 2015-07-09 14:58:55.951753722 +0200
+++ openssl-1.0.1k/apps/verify.c 2015-07-09 14:58:55.972754221 +0200
@@ -238,7 +238,7 @@ int MAIN(int argc, char **argv)
end:
if (ret == 1) {
BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-trusted_first] [-purpose purpose] [-crl_check]");
- BIO_printf(bio_err," [-attime timestamp]");
+ BIO_printf(bio_err," [-no_alt_chains] [-attime timestamp]");
#ifndef OPENSSL_NO_ENGINE
BIO_printf(bio_err," [-engine e]");
#endif
diff -up openssl-1.0.1k/crypto/x509/x509_vfy.c.alt-chains openssl-1.0.1k/crypto/x509/x509_vfy.c
--- openssl-1.0.1k/crypto/x509/x509_vfy.c.alt-chains 2015-07-09 14:58:55.951753722 +0200
+++ openssl-1.0.1k/crypto/x509/x509_vfy.c 2015-07-09 15:28:03.630442145 +0200
@@ -154,11 +154,11 @@ static int x509_subject_cmp(X509 **a, X5
int X509_verify_cert(X509_STORE_CTX *ctx)
{
- X509 *x,*xtmp,*chain_ss=NULL;
+ X509 *x,*xtmp,*xtmp2,*chain_ss=NULL;
int bad_chain = 0;
X509_VERIFY_PARAM *param = ctx->param;
int depth,i,ok=0;
- int num;
+ int num, j, retry;
int (*cb)(int xok,X509_STORE_CTX *xctx);
STACK_OF(X509) *sktmp=NULL;
if (ctx->cert == NULL)
@@ -167,21 +167,27 @@ int X509_verify_cert(X509_STORE_CTX *ctx
return -1;
}
+ if (ctx->chain != NULL) {
+ /*
+ * This X509_STORE_CTX has already been used to verify a cert. We
+ * cannot do another one.
+ */
+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
cb=ctx->verify_cb;
/* first we make sure the chain we are going to build is
* present and that the first entry is in place */
- if (ctx->chain == NULL)
+ if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
+ (!sk_X509_push(ctx->chain,ctx->cert)))
{
- if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
- (!sk_X509_push(ctx->chain,ctx->cert)))
- {
- X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
- goto end;
- }
- CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
- ctx->last_untrusted=1;
+ X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
+ goto end;
}
+ CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
+ ctx->last_untrusted=1;
/* We use a temporary STACK so we can chop and hack at it */
if (ctx->untrusted != NULL
@@ -247,10 +253,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx
break;
}
+ /* Remember how many untrusted certs we have */
+ j = num;
+
/* at this point, chain should contain a list of untrusted
* certificates. We now need to add at least one trusted one,
* if possible, otherwise we complain. */
+ do {
/* Examine last certificate in chain and see if it
* is self signed.
*/
@@ -294,6 +304,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx
chain_ss=sk_X509_pop(ctx->chain);
ctx->last_untrusted--;
num--;
+ j--;
x=sk_X509_value(ctx->chain,num-1);
}
}
@@ -322,7 +333,42 @@ int X509_verify_cert(X509_STORE_CTX *ctx
num++;
}
- /* we now have our chain, lets check it... */
+ /*
+ * If we haven't got a least one certificate from our store then check
+ * if there is an alternative chain that could be used. We only do this
+ * if the user hasn't switched off alternate chain checking
+ */
+ retry = 0;
+ if (num == ctx->last_untrusted &&
+ !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
+ while (j-- > 1) {
+ xtmp2 = sk_X509_value(ctx->chain, j - 1);
+ ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+ if (ok < 0)
+ goto end;
+ /* Check if we found an alternate chain */
+ if (ok > 0) {
+ /*
+ * Free up the found cert we'll add it again later
+ */
+ X509_free(xtmp);
+
+ /*
+ * Dump all the certs above this point - we've found an
+ * alternate chain
+ */
+ while (num > j) {
+ xtmp = sk_X509_pop(ctx->chain);
+ X509_free(xtmp);
+ num--;
+ }
+ ctx->last_untrusted = j;
+ retry = 1;
+ break;
+ }
+ }
+ }
+ } while (retry);
/* Is last certificate looked up self signed? */
if (!ctx->check_issued(ctx,x,x))
diff -up openssl-1.0.1k/crypto/x509/x509_vfy.h.alt-chains openssl-1.0.1k/crypto/x509/x509_vfy.h
--- openssl-1.0.1k/crypto/x509/x509_vfy.h.alt-chains 2015-07-09 14:58:55.951753722 +0200
+++ openssl-1.0.1k/crypto/x509/x509_vfy.h 2015-07-09 14:58:55.972754221 +0200
@@ -391,7 +391,12 @@ void X509_STORE_CTX_set_depth(X509_STORE
#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
/* Use trusted store first */
#define X509_V_FLAG_TRUSTED_FIRST 0x8000
-
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.1n/1.0.2b. Setting
+ * this flag will force the behaviour to match that of previous versions.
+ */
+#define X509_V_FLAG_NO_ALT_CHAINS 0x100000
#define X509_VP_FLAG_DEFAULT 0x1
#define X509_VP_FLAG_OVERWRITE 0x2
diff -up openssl-1.0.1k/doc/apps/cms.pod.alt-chains openssl-1.0.1k/doc/apps/cms.pod
--- openssl-1.0.1k/doc/apps/cms.pod.alt-chains 2015-07-09 14:58:55.951753722 +0200
+++ openssl-1.0.1k/doc/apps/cms.pod 2015-07-09 14:58:55.972754221 +0200
@@ -35,6 +35,7 @@ B<openssl> B<cms>
[B<-print>]
[B<-CAfile file>]
[B<-CApath dir>]
+[B<-no_alt_chains>]
[B<-trusted_first>]
[B<-md digest>]
[B<-[cipher]>]
@@ -413,7 +414,7 @@ portion of a message so they may be incl
then many S/MIME mail clients check the signers certificate's email
address matches that specified in the From: address.
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
Set various certificate chain valiadition option. See the
L<B<verify>|verify(1)> manual page for details.
diff -up openssl-1.0.1k/doc/apps/ocsp.pod.alt-chains openssl-1.0.1k/doc/apps/ocsp.pod
--- openssl-1.0.1k/doc/apps/ocsp.pod.alt-chains 2015-07-09 14:58:55.951753722 +0200
+++ openssl-1.0.1k/doc/apps/ocsp.pod 2015-07-09 14:58:55.973754245 +0200
@@ -29,6 +29,7 @@ B<openssl> B<ocsp>
[B<-path>]
[B<-CApath dir>]
[B<-CAfile file>]
+[B<-no_alt_chains>]]
[B<-trusted_first>]
[B<-VAfile file>]
[B<-validity_period n>]
@@ -143,6 +144,10 @@ connection timeout to the OCSP responder
file or pathname containing trusted CA certificates. These are used to verify
the signature on the OCSP response.
+=item B<-no_alt_chains>
+
+See L<B<verify>|verify(1)> manual page for details.
+
=item B<-trusted_first>
Use certificates in CA file or CA directory over certificates provided
diff -up openssl-1.0.1k/doc/apps/s_client.pod.alt-chains openssl-1.0.1k/doc/apps/s_client.pod
--- openssl-1.0.1k/doc/apps/s_client.pod.alt-chains 2015-07-09 14:58:55.952753746 +0200
+++ openssl-1.0.1k/doc/apps/s_client.pod 2015-07-09 14:58:55.973754245 +0200
@@ -19,6 +19,7 @@ B<openssl> B<s_client>
[B<-pass arg>]
[B<-CApath directory>]
[B<-CAfile filename>]
+[B<-no_alt_chains>]
[B<-trusted_first>]
[B<-reconnect>]
[B<-pause>]
@@ -122,7 +123,7 @@ also used when building the client certi
A file containing trusted certificates to use during server authentication
and to use when attempting to build the client certificate chain.
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig, -trusted_first>
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
Set various certificate chain valiadition option. See the
L<B<verify>|verify(1)> manual page for details.
diff -up openssl-1.0.1k/doc/apps/smime.pod.alt-chains openssl-1.0.1k/doc/apps/smime.pod
--- openssl-1.0.1k/doc/apps/smime.pod.alt-chains 2015-07-09 14:58:55.952753746 +0200
+++ openssl-1.0.1k/doc/apps/smime.pod 2015-07-09 14:58:55.973754245 +0200
@@ -17,6 +17,7 @@ B<openssl> B<smime>
[B<-in file>]
[B<-CAfile file>]
[B<-CApath dir>]
+[B<-no_alt_chains>]
[B<-trusted_first>]
[B<-certfile file>]
[B<-signer file>]
@@ -268,7 +269,7 @@ portion of a message so they may be incl
then many S/MIME mail clients check the signers certificate's email
address matches that specified in the From: address.
-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig>
+=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
Set various options of certificate chain verification. See
L<B<verify>|verify(1)> manual page for details.
diff -up openssl-1.0.1k/doc/apps/s_server.pod.alt-chains openssl-1.0.1k/doc/apps/s_server.pod
--- openssl-1.0.1k/doc/apps/s_server.pod.alt-chains 2015-07-09 14:58:55.952753746 +0200
+++ openssl-1.0.1k/doc/apps/s_server.pod 2015-07-09 14:58:55.973754245 +0200
@@ -33,6 +33,7 @@ B<openssl> B<s_server>
[B<-state>]
[B<-CApath directory>]
[B<-CAfile filename>]
+[B<-no_alt_chains>]
[B<-trusted_first>]
[B<-nocert>]
[B<-cipher cipherlist>]
@@ -179,6 +180,10 @@ and to use when attempting to build the
is also used in the list of acceptable client CAs passed to the client when
a certificate is requested.
+=item B<-no_alt_chains>
+
+See the L<B<verify>|verify(1)> manual page for details.
+
=item B<-trusted_first>
Use certificates in CA file or CA directory before other certificates
diff -up openssl-1.0.1k/doc/apps/verify.pod.alt-chains openssl-1.0.1k/doc/apps/verify.pod
--- openssl-1.0.1k/doc/apps/verify.pod.alt-chains 2015-07-09 14:58:55.952753746 +0200
+++ openssl-1.0.1k/doc/apps/verify.pod 2015-07-09 14:58:55.973754245 +0200
@@ -23,6 +23,7 @@ B<openssl> B<verify>
[B<-extended_crl>]
[B<-use_deltas>]
[B<-policy_print>]
+[B<-no_alt_chains>]
[B<-untrusted file>]
[B<-help>]
[B<-issuer_checks>]
@@ -115,6 +116,14 @@ Set policy variable inhibit-any-policy (
Set policy variable inhibit-policy-mapping (see RFC5280).
+=item B<-no_alt_chains>
+
+When building a certificate chain, if the first certificate chain found is not
+trusted, then OpenSSL will continue to check to see if an alternative chain can
+be found that is trusted. With this option that behaviour is suppressed so that
+only the first chain found is ever used. Using this option will force the
+behaviour to match that of previous OpenSSL versions.
+
=item B<-policy_print>
Print out diagnostics related to policy processing.
diff -up openssl-1.0.1k/doc/crypto/X509_STORE_CTX_new.pod.alt-chains openssl-1.0.1k/doc/crypto/X509_STORE_CTX_new.pod
--- openssl-1.0.1k/doc/crypto/X509_STORE_CTX_new.pod.alt-chains 2014-10-15 15:49:15.000000000 +0200
+++ openssl-1.0.1k/doc/crypto/X509_STORE_CTX_new.pod 2015-07-09 15:29:16.461174414 +0200
@@ -39,10 +39,15 @@ X509_STORE_CTX_free() completely frees u
is no longer valid.
X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation.
-The trusted certificate store is set to B<store>, the end entity certificate
-to be verified is set to B<x509> and a set of additional certificates (which
-will be untrusted but may be used to build the chain) in B<chain>. Any or
-all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>.
+It must be called before each call to X509_verify_cert(), i.e. a B<ctx> is only
+good for one call to X509_verify_cert(); if you want to verify a second
+certificate with the same B<ctx> then you must call X509_XTORE_CTX_cleanup()
+and then X509_STORE_CTX_init() again before the second call to
+X509_verify_cert(). The trusted certificate store is set to B<store>, the end
+entity certificate to be verified is set to B<x509> and a set of additional
+certificates (which will be untrusted but may be used to build the chain) in
+B<chain>. Any or all of the B<store>, B<x509> and B<chain> parameters can be
+B<NULL>.
X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx>
to B<sk>. This is an alternative way of specifying trusted certificates
diff -up openssl-1.0.1k/doc/crypto/X509_verify_cert.pod.alt-chains openssl-1.0.1k/doc/crypto/X509_verify_cert.pod
--- openssl-1.0.1k/doc/crypto/X509_verify_cert.pod.alt-chains 2014-10-15 15:49:15.000000000 +0200
+++ openssl-1.0.1k/doc/crypto/X509_verify_cert.pod 2015-07-09 15:29:16.461174414 +0200
@@ -32,7 +32,8 @@ OpenSSL internally for certificate valid
SSL/TLS code.
The negative return value from X509_verify_cert() can only occur if no
-certificate is set in B<ctx> (due to a programming error) or if a retry
+certificate is set in B<ctx> (due to a programming error); if X509_verify_cert()
+twice without reinitialising B<ctx> in between; or if a retry
operation is requested during internal lookups (which never happens with
standard lookup methods). It is however recommended that application check
for <= 0 return value on error.
diff -up openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod.alt-chains openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod
--- openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod.alt-chains 2015-01-08 15:00:36.000000000 +0100
+++ openssl-1.0.1k/doc/crypto/X509_VERIFY_PARAM_set_flags.pod 2015-07-09 14:58:55.973754245 +0200
@@ -133,6 +133,12 @@ verification. If this flag is set then a
to the verification callback and it B<must> be prepared to handle such cases
without assuming they are hard errors.
+The B<X509_V_FLAG_NO_ALT_CHAINS> flag suppresses checking for alternative
+chains. By default, when building a certificate chain, if the first certificate
+chain found is not trusted, then OpenSSL will continue to check to see if an
+alternative chain can be found that is trusted. With this flag set the behaviour
+will match that of OpenSSL versions prior to 1.0.1n and 1.0.2b.
+
=head1 NOTES
The above functions should be used to manipulate verification parameters
@@ -166,6 +172,6 @@ L<X509_verify_cert(3)|X509_verify_cert(3
=head1 HISTORY
-TBA
+The B<X509_V_FLAG_NO_ALT_CHAINS> flag was added in upstream OpenSSL 1.0.1n and 1.0.2b
=cut

View File

@ -1,3 +1,34 @@
diff -up openssl-1.0.1e/crypto/asn1/x_x509.c.use-after-free openssl-1.0.1e/crypto/asn1/x_x509.c
--- openssl-1.0.1e/crypto/asn1/x_x509.c.use-after-free 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/x_x509.c 2015-06-11 11:14:52.581856349 +0200
@@ -170,8 +170,14 @@ X509 *d2i_X509_AUX(X509 **a, const unsig
{
const unsigned char *q;
X509 *ret;
+ int freeret = 0;
+
/* Save start position */
q = *pp;
+
+ if(!a || *a == NULL) {
+ freeret = 1;
+ }
ret = d2i_X509(a, pp, length);
/* If certificate unreadable then forget it */
if(!ret) return NULL;
@@ -181,7 +187,11 @@ X509 *d2i_X509_AUX(X509 **a, const unsig
if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
return ret;
err:
- X509_free(ret);
+ if(freeret) {
+ X509_free(ret);
+ if (a)
+ *a = NULL;
+ }
return NULL;
}
diff -up openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free openssl-1.0.1k/crypto/ec/ec_asn1.c
--- openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free 2014-10-15 15:49:54.000000000 +0200
+++ openssl-1.0.1k/crypto/ec/ec_asn1.c 2015-03-19 17:28:03.349627040 +0100
@ -25,3 +56,27 @@ diff -up openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free openssl-1.0.1k/crypto
EC_KEY_free(ret);
ret = NULL;
}
@@ -1377,8 +1377,6 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, con
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
return NULL;
}
- if (a)
- *a = ret;
}
else
ret = *a;
@@ -1386,9 +1384,14 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, con
if (!d2i_ECPKParameters(&ret->group, in, len))
{
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+ if (a == NULL || *a != ret)
+ EC_KEY_free(ret);
return NULL;
}
+ if (a)
+ *a = ret;
+
return ret;
}

View File

@ -0,0 +1,231 @@
diff -up openssl-1.0.1k/ssl/ssl_err.c.ticket-race openssl-1.0.1k/ssl/ssl_err.c
--- openssl-1.0.1k/ssl/ssl_err.c.ticket-race 2015-06-15 17:06:22.699702477 +0200
+++ openssl-1.0.1k/ssl/ssl_err.c 2015-06-15 17:06:22.704702592 +0200
@@ -245,6 +245,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"},
{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
+{ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
{ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
diff -up openssl-1.0.1k/ssl/ssl.h.ticket-race openssl-1.0.1k/ssl/ssl.h
--- openssl-1.0.1k/ssl/ssl.h.ticket-race 2015-06-15 17:06:22.700702500 +0200
+++ openssl-1.0.1k/ssl/ssl.h 2015-06-15 17:06:22.704702592 +0200
@@ -2203,6 +2203,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_READ 223
#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187
#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188
+#define SSL_F_SSL_SESSION_DUP 348
#define SSL_F_SSL_SESSION_NEW 189
#define SSL_F_SSL_SESSION_PRINT_FP 190
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
diff -up openssl-1.0.1k/ssl/ssl_locl.h.ticket-race openssl-1.0.1k/ssl/ssl_locl.h
--- openssl-1.0.1k/ssl/ssl_locl.h.ticket-race 2015-06-15 17:06:22.543698865 +0200
+++ openssl-1.0.1k/ssl/ssl_locl.h 2015-06-15 17:06:22.705702616 +0200
@@ -831,6 +831,7 @@ void ssl_sess_cert_free(SESS_CERT *sc);
int ssl_set_peer_cert_type(SESS_CERT *c, int type);
int ssl_get_new_session(SSL *s, int session);
int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
ssl_cipher_id);
diff -up openssl-1.0.1k/ssl/ssl_sess.c.ticket-race openssl-1.0.1k/ssl/ssl_sess.c
--- openssl-1.0.1k/ssl/ssl_sess.c.ticket-race 2015-01-08 15:00:56.000000000 +0100
+++ openssl-1.0.1k/ssl/ssl_sess.c 2015-06-15 17:06:22.705702616 +0200
@@ -224,6 +224,146 @@ SSL_SESSION *SSL_SESSION_new(void)
return(ss);
}
+/*
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+ SSL_SESSION *dest;
+
+ dest = OPENSSL_malloc(sizeof(*src));
+ if (dest == NULL)
+ {
+ goto err;
+ }
+ memcpy(dest, src, sizeof(*dest));
+
+ /*
+ * Set the various pointers to NULL so that we can call SSL_SESSION_free in
+ * the case of an error whilst halfway through constructing dest
+ */
+#ifndef OPENSSL_NO_PSK
+ dest->psk_identity_hint = NULL;
+ dest->psk_identity = NULL;
+#endif
+ dest->ciphers = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ dest->tlsext_hostname = NULL;
+# ifndef OPENSSL_NO_EC
+ dest->tlsext_ecpointformatlist = NULL;
+ dest->tlsext_ellipticcurvelist = NULL;
+# endif
+#endif
+ dest->tlsext_tick = NULL;
+#ifndef OPENSSL_NO_SRP
+ dest->srp_username = NULL;
+#endif
+ memset(&dest->ex_data, 0, sizeof(dest->ex_data));
+
+ /* We deliberately don't copy the prev and next pointers */
+ dest->prev = NULL;
+ dest->next = NULL;
+
+ dest->references = 1;
+
+ if (src->sess_cert != NULL)
+ CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
+
+ if (src->peer != NULL)
+ CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
+
+#ifndef OPENSSL_NO_PSK
+ if (src->psk_identity_hint)
+ {
+ dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint);
+ if (dest->psk_identity_hint == NULL)
+ {
+ goto err;
+ }
+ }
+ if (src->psk_identity)
+ {
+ dest->psk_identity = BUF_strdup(src->psk_identity);
+ if (dest->psk_identity == NULL)
+ {
+ goto err;
+ }
+ }
+#endif
+
+ if(src->ciphers != NULL)
+ {
+ dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
+ if (dest->ciphers == NULL)
+ goto err;
+ }
+
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
+ &dest->ex_data, &src->ex_data))
+ {
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (src->tlsext_hostname)
+ {
+ dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
+ if (dest->tlsext_hostname == NULL)
+ {
+ goto err;
+ }
+ }
+# ifndef OPENSSL_NO_EC
+ if (src->tlsext_ecpointformatlist)
+ {
+ dest->tlsext_ecpointformatlist =
+ BUF_memdup(src->tlsext_ecpointformatlist,
+ src->tlsext_ecpointformatlist_length);
+ if (dest->tlsext_ecpointformatlist == NULL)
+ goto err;
+ }
+ if (src->tlsext_ellipticcurvelist)
+ {
+ dest->tlsext_ellipticcurvelist =
+ BUF_memdup(src->tlsext_ellipticcurvelist,
+ src->tlsext_ellipticcurvelist_length);
+ if (dest->tlsext_ellipticcurvelist == NULL)
+ goto err;
+ }
+# endif
+#endif
+
+ if (ticket != 0)
+ {
+ dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
+ if(dest->tlsext_tick == NULL)
+ goto err;
+ }
+ else
+ {
+ dest->tlsext_tick_lifetime_hint = 0;
+ dest->tlsext_ticklen = 0;
+ }
+
+#ifndef OPENSSL_NO_SRP
+ if (src->srp_username)
+ {
+ dest->srp_username = BUF_strdup(src->srp_username);
+ if (dest->srp_username == NULL)
+ {
+ goto err;
+ }
+ }
+#endif
+
+ return dest;
+err:
+ SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+ SSL_SESSION_free(dest);
+ return NULL;
+}
+
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
{
if(len)
diff -up openssl-1.0.1k/ssl/s3_clnt.c.ticket-race openssl-1.0.1k/ssl/s3_clnt.c
--- openssl-1.0.1k/ssl/s3_clnt.c.ticket-race 2015-06-15 17:06:22.700702500 +0200
+++ openssl-1.0.1k/ssl/s3_clnt.c 2015-06-15 17:06:37.434043557 +0200
@@ -2191,6 +2191,44 @@ int ssl3_get_new_session_ticket(SSL *s)
}
p=d=(unsigned char *)s->init_msg;
+
+ if (s->session->session_id_length > 0)
+ {
+ int i = s->session_ctx->session_cache_mode;
+ SSL_SESSION *new_sess;
+ /*
+ * We reused an existing session, so we need to replace it with a new
+ * one
+ */
+ if (i & SSL_SESS_CACHE_CLIENT)
+ {
+ /*
+ * Remove the old session from the cache
+ */
+ if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
+ {
+ if (s->session_ctx->remove_session_cb != NULL)
+ s->session_ctx->remove_session_cb(s->session_ctx,
+ s->session);
+ }
+ else
+ {
+ /* We carry on if this fails */
+ SSL_CTX_remove_session(s->session_ctx, s->session);
+ }
+ }
+
+ if ((new_sess = ssl_session_dup(s->session, 0)) == 0)
+ {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+
+ SSL_SESSION_free(s->session);
+ s->session = new_sess;
+ }
+
n2l(p, s->session->tlsext_tick_lifetime_hint);
n2s(p, ticklen);
/* ticket_lifetime_hint + ticket_length + ticket */

View File

@ -0,0 +1,52 @@
diff -up openssl-1.0.1k/ssl/s3_clnt.c.psk-identity openssl-1.0.1k/ssl/s3_clnt.c
--- openssl-1.0.1k/ssl/s3_clnt.c.psk-identity 2015-12-04 16:25:45.606213013 +0100
+++ openssl-1.0.1k/ssl/s3_clnt.c 2015-12-04 16:29:58.083945750 +0100
@@ -1360,8 +1360,6 @@ int ssl3_get_key_exchange(SSL *s)
#ifndef OPENSSL_NO_PSK
if (alg_k & SSL_kPSK)
{
- char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
-
param_len = 2;
if (param_len > n)
{
@@ -1390,16 +1388,8 @@ int ssl3_get_key_exchange(SSL *s)
}
param_len += i;
- /* If received PSK identity hint contains NULL
- * characters, the hint is truncated from the first
- * NULL. p may not be ending with NULL, so create a
- * NULL-terminated string. */
- memcpy(tmp_id_hint, p, i);
- memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
- if (s->ctx->psk_identity_hint != NULL)
- OPENSSL_free(s->ctx->psk_identity_hint);
- s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
- if (s->ctx->psk_identity_hint == NULL)
+ s->session->psk_identity_hint = BUF_strndup((char *)p, i);
+ if (s->session->psk_identity_hint == NULL)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
@@ -3008,7 +2998,7 @@ int ssl3_send_client_key_exchange(SSL *s
}
memset(identity, 0, sizeof(identity));
- psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
+ psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
identity, sizeof(identity) - 1,
psk_or_pre_ms, sizeof(psk_or_pre_ms));
if (psk_len > PSK_MAX_PSK_LEN)
diff -up openssl-1.0.1k/ssl/s3_srvr.c.psk-identity openssl-1.0.1k/ssl/s3_srvr.c
--- openssl-1.0.1k/ssl/s3_srvr.c.psk-identity 2015-01-08 15:02:09.000000000 +0100
+++ openssl-1.0.1k/ssl/s3_srvr.c 2015-12-04 16:25:45.606213013 +0100
@@ -2816,7 +2816,7 @@ int ssl3_get_client_key_exchange(SSL *s)
if (s->session->psk_identity != NULL)
OPENSSL_free(s->session->psk_identity);
- s->session->psk_identity = BUF_strdup((char *)p);
+ s->session->psk_identity = BUF_strndup((char *)p, i);
if (s->session->psk_identity == NULL)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,

View File

@ -0,0 +1,208 @@
diff -up openssl-1.0.1k/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod.logjam openssl-1.0.1k/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
--- openssl-1.0.1k/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod.logjam 2015-05-29 16:02:33.335187143 +0200
+++ openssl-1.0.1k/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod 2015-05-29 16:05:16.611940775 +0200
@@ -61,12 +61,12 @@ negotiation is being saved.
If "strong" primes were used to generate the DH parameters, it is not strictly
necessary to generate a new key for each handshake but it does improve forward
-secrecy. If it is not assured, that "strong" primes were used (see especially
-the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used
-in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE
-has an impact on the computer time needed during negotiation, but it is not
-very large, so application authors/users should consider to always enable
-this option.
+secrecy. If it is not assured that "strong" primes were used,
+SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup
+attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the
+computer time needed during negotiation, but it is not very large, so
+application authors/users should consider always enabling this option.
+The option is required to implement perfect forward secrecy (PFS).
As generating DH parameters is extremely time consuming, an application
should not generate the parameters on the fly but supply the parameters.
@@ -74,82 +74,62 @@ DH parameters can be reused, as the actu
the negotiation. The risk in reusing DH parameters is that an attacker
may specialize on a very often used DH group. Applications should therefore
generate their own DH parameters during the installation process using the
-openssl L<dhparam(1)|dhparam(1)> application. In order to reduce the computer
-time needed for this generation, it is possible to use DSA parameters
-instead (see L<dhparam(1)|dhparam(1)>), but in this case SSL_OP_SINGLE_DH_USE
-is mandatory.
+openssl L<dhparam(1)|dhparam(1)> application. This application
+guarantees that "strong" primes are used.
-Application authors may compile in DH parameters. Files dh512.pem,
-dh1024.pem, dh2048.pem, and dh4096.pem in the 'apps' directory of current
+Files dh2048.pem, and dh4096.pem in the 'apps' directory of the current
version of the OpenSSL distribution contain the 'SKIP' DH parameters,
which use safe primes and were generated verifiably pseudo-randomly.
These files can be converted into C code using the B<-C> option of the
-L<dhparam(1)|dhparam(1)> application.
-Authors may also generate their own set of parameters using
-L<dhparam(1)|dhparam(1)>, but a user may not be sure how the parameters were
-generated. The generation of DH parameters during installation is therefore
-recommended.
+L<dhparam(1)|dhparam(1)> application. Generation of custom DH
+parameters during installation should still be preferred to stop an
+attacker from specializing on a commonly used group. Files dh1024.pem
+and dh512.pem contain old parameters that must not be used by
+applications.
An application may either directly specify the DH parameters or
-can supply the DH parameters via a callback function. The callback approach
-has the advantage, that the callback may supply DH parameters for different
-key lengths.
-
-The B<tmp_dh_callback> is called with the B<keylength> needed and
-the B<is_export> information. The B<is_export> flag is set, when the
-ephemeral DH key exchange is performed with an export cipher.
+can supply the DH parameters via a callback function.
+
+Previous versions of the callback used B<is_export> and B<keylength>
+parameters to control parameter generation for export and non-export
+cipher suites. Modern servers that do not support export ciphersuites
+are advised to either use SSL_CTX_set_tmp_dh() in combination with
+SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore
+B<keylength> and B<is_export> and simply supply at least 2048-bit
+parameters in the callback.
=head1 EXAMPLES
-Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling
+Setup DH parameters with a key length of 2048 bits. (Error handling
partly left out.)
- ...
- /* Set up ephemeral DH stuff */
- DH *dh_512 = NULL;
- DH *dh_1024 = NULL;
- FILE *paramfile;
+ Command-line parameter generation:
+ $ openssl dhparam -out dh_param_2048.pem 2048
+
+ Code for setting up parameters during server initialization:
...
- /* "openssl dhparam -out dh_param_512.pem -2 512" */
- paramfile = fopen("dh_param_512.pem", "r");
+ SSL_CTX ctx = SSL_CTX_new();
+ ...
+
+ /* Set up ephemeral DH parameters. */
+ DH *dh_2048 = NULL;
+ FILE *paramfile;
+ paramfile = fopen("dh_param_2048.pem", "r");
if (paramfile) {
- dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
+ dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
fclose(paramfile);
+ } else {
+ /* Error. */
}
- /* "openssl dhparam -out dh_param_1024.pem -2 1024" */
- paramfile = fopen("dh_param_1024.pem", "r");
- if (paramfile) {
- dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
- fclose(paramfile);
+ if (dh_2048 == NULL) {
+ /* Error. */
}
- ...
-
- /* "openssl dhparam -C -2 512" etc... */
- DH *get_dh512() { ... }
- DH *get_dh1024() { ... }
-
- DH *tmp_dh_callback(SSL *s, int is_export, int keylength)
- {
- DH *dh_tmp=NULL;
-
- switch (keylength) {
- case 512:
- if (!dh_512)
- dh_512 = get_dh512();
- dh_tmp = dh_512;
- break;
- case 1024:
- if (!dh_1024)
- dh_1024 = get_dh1024();
- dh_tmp = dh_1024;
- break;
- default:
- /* Generating a key on the fly is very costly, so use what is there */
- setup_dh_parameters_like_above();
+ if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) {
+ /* Error. */
}
- return(dh_tmp);
- }
+ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
+ ...
=head1 RETURN VALUES
diff -up openssl-1.0.1k/ssl/ssl_err.c.logjam openssl-1.0.1k/ssl/ssl_err.c
--- openssl-1.0.1k/ssl/ssl_err.c.logjam 2015-01-08 15:00:36.000000000 +0100
+++ openssl-1.0.1k/ssl/ssl_err.c 2015-05-29 16:02:33.336187166 +0200
@@ -362,6 +362,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"},
+{ERR_REASON(SSL_R_DH_KEY_TOO_SMALL) ,"dh key too small"},
{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"},
{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"},
{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"},
diff -up openssl-1.0.1k/ssl/ssl.h.logjam openssl-1.0.1k/ssl/ssl.h
--- openssl-1.0.1k/ssl/ssl.h.logjam 2015-05-29 16:02:19.210862433 +0200
+++ openssl-1.0.1k/ssl/ssl.h 2015-05-29 16:02:33.337187189 +0200
@@ -2317,6 +2317,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_DATA_LENGTH_TOO_LONG 146
#define SSL_R_DECRYPTION_FAILED 147
#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281
+#define SSL_R_DH_KEY_TOO_SMALL 372
#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148
#define SSL_R_DIGEST_CHECK_FAILED 149
#define SSL_R_DTLS_MESSAGE_TOO_BIG 334
diff -up openssl-1.0.1k/ssl/s3_clnt.c.logjam openssl-1.0.1k/ssl/s3_clnt.c
--- openssl-1.0.1k/ssl/s3_clnt.c.logjam 2015-01-08 15:00:56.000000000 +0100
+++ openssl-1.0.1k/ssl/s3_clnt.c 2015-05-29 16:02:33.338187212 +0200
@@ -3393,24 +3393,34 @@ int ssl3_check_cert_and_algorithm(SSL *s
}
#endif
#ifndef OPENSSL_NO_DH
- if ((alg_k & SSL_kEDH) &&
- !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
+ if ((alg_k & SSL_kEDH) && dh == NULL)
{
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
goto f_err;
}
- else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
+ if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
{
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
goto f_err;
}
#ifndef OPENSSL_NO_DSA
- else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
+ if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
{
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
goto f_err;
}
#endif
+ /* Check DHE only: static DH not implemented. */
+ if (alg_k & SSL_kEDH)
+ {
+ int dh_size = BN_num_bits(dh->p);
+ if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768)
+ || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512))
+ {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL);
+ goto f_err;
+ }
+ }
#endif
if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,437 @@
diff -up openssl-1.0.1k/crypto/bio/b_print.c.bio-printf openssl-1.0.1k/crypto/bio/b_print.c
--- openssl-1.0.1k/crypto/bio/b_print.c.bio-printf 2015-01-08 15:00:36.000000000 +0100
+++ openssl-1.0.1k/crypto/bio/b_print.c 2016-03-02 10:56:35.376167813 +0100
@@ -125,14 +125,14 @@
#define LLONG long
#endif
-static void fmtstr (char **, char **, size_t *, size_t *,
+static int fmtstr(char **, char **, size_t *, size_t *,
const char *, int, int, int);
-static void fmtint (char **, char **, size_t *, size_t *,
+static int fmtint(char **, char **, size_t *, size_t *,
LLONG, int, int, int, int);
-static void fmtfp (char **, char **, size_t *, size_t *,
+static int fmtfp(char **, char **, size_t *, size_t *,
LDOUBLE, int, int, int);
-static void doapr_outch (char **, char **, size_t *, size_t *, int);
-static void _dopr(char **sbuffer, char **buffer,
+static int doapr_outch(char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
size_t *maxlen, size_t *retlen, int *truncated,
const char *format, va_list args);
@@ -165,7 +165,7 @@ static void _dopr(char **sbuffer, char *
#define char_to_int(p) (p - '0')
#define OSSL_MAX(p,q) ((p >= q) ? p : q)
-static void
+static int
_dopr(
char **sbuffer,
char **buffer,
@@ -200,7 +200,8 @@ _dopr(
if (ch == '%')
state = DP_S_FLAGS;
else
- doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
+ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
ch = *format++;
break;
case DP_S_FLAGS:
@@ -306,8 +307,9 @@ _dopr(
value = va_arg(args, int);
break;
}
- fmtint(sbuffer, buffer, &currlen, maxlen,
- value, 10, min, max, flags);
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+ max, flags))
+ return 0;
break;
case 'X':
flags |= DP_F_UP;
@@ -332,17 +334,19 @@ _dopr(
unsigned int);
break;
}
- fmtint(sbuffer, buffer, &currlen, maxlen, value,
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
- min, max, flags);
+ min, max, flags))
+ return 0;
break;
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
else
fvalue = va_arg(args, double);
- fmtfp(sbuffer, buffer, &currlen, maxlen,
- fvalue, min, max, flags);
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+ flags))
+ return 0;
break;
case 'E':
flags |= DP_F_UP;
@@ -361,8 +365,9 @@ _dopr(
fvalue = va_arg(args, double);
break;
case 'c':
- doapr_outch(sbuffer, buffer, &currlen, maxlen,
- va_arg(args, int));
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+ va_arg(args, int)))
+ return 0;
break;
case 's':
strvalue = va_arg(args, char *);
@@ -372,13 +377,15 @@ _dopr(
else
max = *maxlen;
}
- fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
- flags, min, max);
+ if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+ flags, min, max))
+ return 0;
break;
case 'p':
value = (long)va_arg(args, void *);
- fmtint(sbuffer, buffer, &currlen, maxlen,
- value, 16, min, max, flags|DP_F_NUM);
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+ value, 16, min, max, flags | DP_F_NUM))
+ return 0;
break;
case 'n': /* XXX */
if (cflags == DP_C_SHORT) {
@@ -400,7 +407,8 @@ _dopr(
}
break;
case '%':
- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
break;
case 'w':
/* not supported yet, treat as next char */
@@ -424,12 +432,13 @@ _dopr(
*truncated = (currlen > *maxlen - 1);
if (*truncated)
currlen = *maxlen - 1;
- doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+ return 0;
*retlen = currlen - 1;
- return;
+ return 1;
}
-static void
+static int
fmtstr(
char **sbuffer,
char **buffer,
@@ -440,36 +449,44 @@ fmtstr(
int min,
int max)
{
- int padlen, strln;
+ int padlen;
+ size_t strln;
int cnt = 0;
if (value == 0)
value = "<NULL>";
- for (strln = 0; value[strln]; ++strln)
- ;
+
+ strln = strlen(value);
+ if (strln > INT_MAX)
+ strln = INT_MAX;
+
padlen = min - strln;
- if (padlen < 0)
+ if (min < 0 || padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen;
while ((padlen > 0) && (cnt < max)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
--padlen;
++cnt;
}
while (*value && (cnt < max)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+ return 0;
++cnt;
}
while ((padlen < 0) && (cnt < max)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
++padlen;
++cnt;
}
+ return 1;
}
-static void
+static int
fmtint(
char **sbuffer,
char **buffer,
@@ -533,37 +550,44 @@ fmtint(
/* spaces */
while (spadlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
--spadlen;
}
/* sign */
if (signvalue)
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
/* prefix */
while (*prefix) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+ return 0;
prefix++;
}
/* zeros */
if (zpadlen > 0) {
while (zpadlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
--zpadlen;
}
}
/* digits */
- while (place > 0)
- doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
+ while (place > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+ return 0;
+ }
/* left justified spaces */
while (spadlen < 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
++spadlen;
}
- return;
+ return 1;
}
static LDOUBLE
@@ -597,7 +621,7 @@ roundv(LDOUBLE value)
return intpart;
}
-static void
+static int
fmtfp(
char **sbuffer,
char **buffer,
@@ -616,7 +640,6 @@ fmtfp(
int fplace = 0;
int padlen = 0;
int zpadlen = 0;
- int caps = 0;
long intpart;
long fracpart;
long max10;
@@ -650,9 +673,7 @@ fmtfp(
/* convert integer part */
do {
- iconvert[iplace++] =
- (caps ? "0123456789ABCDEF"
- : "0123456789abcdef")[intpart % 10];
+ iconvert[iplace++] = "0123456789"[intpart % 10];
intpart = (intpart / 10);
} while (intpart && (iplace < (int)sizeof(iconvert)));
if (iplace == sizeof iconvert)
@@ -661,9 +682,7 @@ fmtfp(
/* convert fractional part */
do {
- fconvert[fplace++] =
- (caps ? "0123456789ABCDEF"
- : "0123456789abcdef")[fracpart % 10];
+ fconvert[fplace++] = "0123456789"[fracpart % 10];
fracpart = (fracpart / 10);
} while (fplace < max);
if (fplace == sizeof fconvert)
@@ -682,47 +701,61 @@ fmtfp(
if ((flags & DP_F_ZERO) && (padlen > 0)) {
if (signvalue) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
--padlen;
signvalue = 0;
}
while (padlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
--padlen;
}
}
while (padlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
--padlen;
}
- if (signvalue)
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
+ if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
- while (iplace > 0)
- doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
+ while (iplace > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+ return 0;
+ }
/*
* Decimal point. This should probably use locale to find the correct
* char to print out.
*/
if (max > 0 || (flags & DP_F_NUM)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+ return 0;
- while (fplace > 0)
- doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
+ while (fplace > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
+ fconvert[--fplace]))
+ return 0;
+ }
}
while (zpadlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
--zpadlen;
}
while (padlen < 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
++padlen;
}
+ return 1;
}
-static void
+#define BUFFER_INC 1024
+
+static int
doapr_outch(
char **sbuffer,
char **buffer,
@@ -733,24 +766,30 @@ doapr_outch(
/* If we haven't at least one buffer, someone has doe a big booboo */
assert(*sbuffer != NULL || buffer != NULL);
- if (buffer) {
- while (*currlen >= *maxlen) {
- if (*buffer == NULL) {
- if (*maxlen == 0)
- *maxlen = 1024;
+ /* |currlen| must always be <= |*maxlen| */
+ assert(*currlen <= *maxlen);
+
+ if (buffer && *currlen == *maxlen) {
+ if (*maxlen > INT_MAX - BUFFER_INC)
+ return 0;
+
+ *maxlen += BUFFER_INC;
+ if (*buffer == NULL) {
*buffer = OPENSSL_malloc(*maxlen);
+ if (*buffer == NULL)
+ return 0;
if (*currlen > 0) {
assert(*sbuffer != NULL);
memcpy(*buffer, *sbuffer, *currlen);
}
*sbuffer = NULL;
- } else {
- *maxlen += 1024;
- *buffer = OPENSSL_realloc(*buffer, *maxlen);
- }
+ } else {
+ char *tmpbuf;
+ tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+ if (tmpbuf == NULL)
+ return 0;
+ *buffer = tmpbuf;
}
- /* What to do if *buffer is NULL? */
- assert(*sbuffer != NULL || *buffer != NULL);
}
if (*currlen < *maxlen) {
@@ -760,7 +799,7 @@ doapr_outch(
(*buffer)[(*currlen)++] = (char)c;
}
- return;
+ return 1;
}
/***************************************************************************/
@@ -792,11 +831,15 @@ int BIO_vprintf (BIO *bio, const char *f
dynbuf = NULL;
CRYPTO_push_info("doapr()");
- _dopr(&hugebufp, &dynbuf, &hugebufsize,
- &retlen, &ignored, format, args);
+ if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
+ args))
+ {
+ OPENSSL_free(dynbuf);
+ return -1;
+ }
if (dynbuf)
{
- ret=BIO_write(bio, dynbuf, (int)retlen);
+ ret = BIO_write(bio, dynbuf, (int)retlen);
OPENSSL_free(dynbuf);
}
else
@@ -829,7 +872,8 @@ int BIO_vsnprintf(char *buf, size_t n, c
size_t retlen;
int truncated;
- _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
+ if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+ return -1;
if (truncated)
/* In case of truncation, return -1 like traditional snprintf.

View File

@ -0,0 +1,59 @@
diff -up openssl-1.0.1k/crypto/ec/ec_curve.c.secp256k1 openssl-1.0.1k/crypto/ec/ec_curve.c
--- openssl-1.0.1k/crypto/ec/ec_curve.c.secp256k1 2015-08-13 07:47:37.890966462 -0400
+++ openssl-1.0.1k/crypto/ec/ec_curve.c 2015-08-13 08:01:31.697866786 -0400
@@ -82,6 +82,36 @@ typedef struct {
unsigned int cofactor; /* promoted to BN_ULONG */
} EC_CURVE_DATA;
+static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
+ _EC_SECG_PRIME_256K1 = {
+ { NID_X9_62_prime_field,0,32,1 },
+ { /* no seed */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
+ 0xFC,0x2F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x07,
+ 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0, /* x */
+ 0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
+ 0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
+ 0x17,0x98,
+ 0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4, /* y */
+ 0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
+ 0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
+ 0xd4,0xb8,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
+ 0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
+ 0x41,0x41 }
+ };
+
static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
_EC_NIST_PRIME_384 = {
{ NID_X9_62_prime_field,20,48,1 },
@@ -212,6 +242,7 @@ typedef struct _ec_list_element_st {
static const ec_list_element curve_list[] = {
/* prime field curves */
/* secg curves */
+ { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" },
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
{ NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" },
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
diff -up openssl-1.0.1k/ssl/t1_lib.c.secp256k1 openssl-1.0.1k/ssl/t1_lib.c
--- openssl-1.0.1k/ssl/t1_lib.c.secp256k1 2015-08-13 08:03:17.401589785 -0400
+++ openssl-1.0.1k/ssl/t1_lib.c 2015-08-13 08:05:44.283292971 -0400
@@ -218,6 +218,7 @@ static int pref_list[] =
NID_sect283k1, /* sect283k1 (9) */
NID_sect283r1, /* sect283r1 (10) */
#endif
+ NID_secp256k1, /* secp256k1 (22) */
NID_X9_62_prime256v1, /* secp256r1 (23) */
#ifndef OPENSSL_NO_EC2M
NID_sect239k1, /* sect239k1 (8) */

View File

@ -23,7 +23,7 @@
Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl
Version: 1.0.1k
Release: 7%{?dist}
Release: 15%{?dist}
Epoch: 1
# We have to remove certain patented algorithms from the openssl source
# tarball with the hobble-openssl script which is included below.
@ -83,6 +83,7 @@ Patch77: openssl-1.0.1e-weak-ciphers.patch
Patch90: openssl-1.0.1e-enc-fail.patch
Patch92: openssl-1.0.1h-system-cipherlist.patch
Patch93: openssl-1.0.1h-disable-sslv2v3.patch
Patch94: openssl-1.0.1k-secp256k1.patch
# Backported fixes including security fixes
Patch80: openssl-1.0.1j-evp-wrap.patch
Patch81: openssl-1.0.1k-padlock64.patch
@ -96,6 +97,25 @@ Patch103: openssl-1.0.1e-cve-2015-0287.patch
Patch104: openssl-1.0.1e-cve-2015-0288.patch
Patch105: openssl-1.0.1k-cve-2015-0289.patch
Patch106: openssl-1.0.1e-cve-2015-0293.patch
Patch107: openssl-1.0.1k-alt-chains.patch
Patch108: openssl-1.0.1k-cve-2015-4000.patch
Patch109: openssl-1.0.1e-cve-2015-1789.patch
Patch110: openssl-1.0.1e-cve-2015-1790.patch
Patch111: openssl-1.0.1k-cve-2015-1791.patch
Patch112: openssl-1.0.1e-cve-2015-1792.patch
Patch113: openssl-1.0.1e-cve-2015-3194.patch
Patch114: openssl-1.0.1e-cve-2015-3195.patch
Patch115: openssl-1.0.1k-cve-2015-3196.patch
Patch116: openssl-1.0.1e-cve-2015-3197.patch
Patch117: openssl-1.0.1k-cve-2016-0702.patch
Patch118: openssl-1.0.1e-cve-2016-0705.patch
Patch119: openssl-1.0.1e-cve-2016-0797.patch
Patch120: openssl-1.0.1k-cve-2016-0799.patch
Patch121: openssl-1.0.1e-cve-2016-2105.patch
Patch122: openssl-1.0.1e-cve-2016-2106.patch
Patch123: openssl-1.0.1e-cve-2016-2107.patch
Patch124: openssl-1.0.1e-cve-2016-2108.patch
Patch125: openssl-1.0.1e-cve-2016-2109.patch
License: OpenSSL
Group: System Environment/Libraries
@ -212,6 +232,7 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/
%patch90 -p1 -b .enc-fail
%patch92 -p1 -b .system
%patch93 -p1 -b .v2v3
%patch94 -p1 -b .secp256k1
%patch80 -p1 -b .wrap
%patch81 -p1 -b .padlock64
@ -225,6 +246,25 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/
%patch104 -p1 -b .req-null-deref
%patch105 -p1 -b .pkcs7-null-deref
%patch106 -p1 -b .ssl2-assert
%patch107 -p1 -b .alt-chains
%patch108 -p1 -b .logjam
%patch109 -p1 -b .oob-read
%patch110 -p1 -b .missing-content
%patch111 -p1 -b .ticket-race
%patch112 -p1 -b .unknown-hash
%patch113 -p1 -b .pss-check
%patch114 -p1 -b .combine-leak
%patch115 -p1 -b .psk-identity
%patch116 -p1 -b .ssl2-ciphers
%patch117 -p1 -b .rsa-const
%patch118 -p1 -b .dsa-doublefree
%patch119 -p1 -b .bn-hex
%patch120 -p1 -b .bio-printf
%patch121 -p1 -b .b64-overflow
%patch122 -p1 -b .enc-overflow
%patch123 -p1 -b .padding-check
%patch124 -p1 -b .asn1-negative
%patch125 -p1 -b .asn1-bio-dos
sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h
@ -301,6 +341,11 @@ make rehash
# Overwrite FIPS README
cp -f %{SOURCE11} .
# Clean up the .pc files
for i in libcrypto.pc libssl.pc openssl.pc ; do
sed -i '/^Libs.private:/{s/-L[^ ]* //;s/-Wl[^ ]* //}' $i
done
%check
# Verify that what was compiled actually works.
@ -492,6 +537,47 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.*
%postun libs -p /sbin/ldconfig
%changelog
* Tue May 3 2016 Tomáš Mráz <tmraz@redhat.com> 1.0.1e-15
- fix CVE-2016-2105 - possible overflow in base64 encoding
- fix CVE-2016-2106 - possible overflow in EVP_EncryptUpdate()
- fix CVE-2016-2107 - padding oracle in stitched AES-NI CBC-MAC
- fix CVE-2016-2108 - memory corruption in ASN.1 encoder
- fix CVE-2016-2109 - possible DoS when reading ASN.1 data from BIO
* Wed Mar 2 2016 Tomáš Mráz <tmraz@redhat.com> 1.0.1e-14
- fix CVE-2016-0702 - side channel attack on modular exponentiation
- fix CVE-2016-0705 - double-free in DSA private key parsing
- fix CVE-2016-0797 - heap corruption in BN_hex2bn and BN_dec2bn
- fix CVE-2015-3197 - SSLv2 ciphersuite enforcement
- fix CVE-2015-7575 - disallow use of MD5 in TLS1.2
- fix CVE-2016-0799 - memory issues in BIO_*printf functions
* Fri Dec 4 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-13
- fix CVE-2015-3194 - certificate verify crash with missing PSS parameter
- fix CVE-2015-3195 - X509_ATTRIBUTE memory leak
- fix CVE-2015-3196 - race condition when handling PSK identity hint
- filter out unwanted link options from the .pc files (#1257836)
* Thu Aug 13 2015 Tom Callaway <spot@fedoraproject.org> 1.0.1k-12
- enable secp256k1 (bz1021898)
* Thu Jul 9 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-11
- fix CVE-2015-1793 - certificate verification forgery
* Mon Jun 15 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-10
- fix CVE-2015-1789 - out-of-bounds read in X509_cmp_time
- fix CVE-2015-1790 - PKCS7 crash with missing EncryptedContent
- fix CVE-2015-1791 - race condition handling NewSessionTicket
- fix CVE-2015-1792 - CMS verify infinite loop with unknown hash function
- add missing parts of CVE-2015-0209 fix for corectness although unexploitable
* Fri May 29 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-9
- fix CVE-2015-4000 - prevent the logjam attack on client - restrict
the DH key size to at least 768 bits (limit will be increased in future)
* Thu Apr 30 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-8
- try to find alternative cert chains (#1166614)
* Thu Apr 9 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-7
- drop the AES-GCM restriction of 2^32 operations because the IV is
always 96 bits (32 bit fixed field + 64 bit invocation field)