You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
6.3 KiB
226 lines
6.3 KiB
diff -up openssl-1.0.2j/crypto/asn1/a_verify.c.deprecate-algos openssl-1.0.2j/crypto/asn1/a_verify.c |
|
--- openssl-1.0.2j/crypto/asn1/a_verify.c.deprecate-algos 2016-09-26 11:49:07.000000000 +0200 |
|
+++ openssl-1.0.2j/crypto/asn1/a_verify.c 2017-01-09 16:47:11.666994197 +0100 |
|
@@ -56,6 +56,9 @@ |
|
* [including the GNU Public Licence.] |
|
*/ |
|
|
|
+/* for secure_getenv */ |
|
+#define _GNU_SOURCE |
|
+ |
|
#include <stdio.h> |
|
#include <time.h> |
|
|
|
@@ -133,6 +136,30 @@ int ASN1_verify(i2d_of_void *i2d, X509_A |
|
|
|
#endif |
|
|
|
+static int legacy_mds[] = { NID_md5, NID_sha, NID_md4, NID_md2, 0 }; |
|
+extern int private_ossl_allowed_legacy_mds[]; |
|
+ |
|
+static int is_md_legacy_disallowed(int mdnid) |
|
+{ |
|
+ int i; |
|
+ |
|
+ if (mdnid == NID_md5 && secure_getenv("OPENSSL_ENABLE_MD5_VERIFY") != NULL) |
|
+ return 0; |
|
+ |
|
+ for (i = 0; legacy_mds[i] != 0; ++i) { |
|
+ if (mdnid == legacy_mds[i]) { |
|
+ int j; |
|
+ |
|
+ for (j = 0; private_ossl_allowed_legacy_mds[j] != 0; ++j) { |
|
+ if (mdnid == private_ossl_allowed_legacy_mds[j]) |
|
+ return 0; |
|
+ } |
|
+ return 1; |
|
+ } |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, |
|
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) |
|
{ |
|
@@ -174,6 +201,10 @@ int ASN1_item_verify(const ASN1_ITEM *it |
|
if (ret != 2) |
|
goto err; |
|
ret = -1; |
|
+ } else if (is_md_legacy_disallowed(mdnid)) { |
|
+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, |
|
+ ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); |
|
+ goto err; |
|
} else { |
|
const EVP_MD *type; |
|
type = EVP_get_digestbynid(mdnid); |
|
diff -up openssl-1.0.2j/crypto/o_init.c.deprecate-algos openssl-1.0.2j/crypto/o_init.c |
|
--- openssl-1.0.2j/crypto/o_init.c.deprecate-algos 2017-01-05 17:49:00.000000000 +0100 |
|
+++ openssl-1.0.2j/crypto/o_init.c 2017-01-09 16:52:29.018298611 +0100 |
|
@@ -64,11 +64,21 @@ |
|
# include <unistd.h> |
|
# include <errno.h> |
|
# include <stdlib.h> |
|
+# include <stdio.h> |
|
+# include <string.h> |
|
+# include <strings.h> |
|
+# include <ctype.h> |
|
# include <openssl/fips.h> |
|
# include <openssl/rand.h> |
|
+# include <openssl/dh.h> |
|
+# include <openssl/objects.h> |
|
|
|
# define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" |
|
|
|
+# define LEGACY_SETTINGS_FILE "/etc/pki/tls/legacy-settings" |
|
+ |
|
+# define NUM_MAX_LEGACY_MDS 8 |
|
+ |
|
static void init_fips_mode(void) |
|
{ |
|
char buf[2] = "0"; |
|
@@ -98,6 +108,115 @@ static void init_fips_mode(void) |
|
} |
|
#endif |
|
|
|
+int private_ossl_allowed_legacy_mds[NUM_MAX_LEGACY_MDS + 1]; /* zero terminated */ |
|
+ |
|
+int private_ossl_minimum_dh_bits; |
|
+ |
|
+static void parse_legacy_mds(char *p) |
|
+{ |
|
+ int idx = 0; |
|
+ char *e = p; |
|
+ |
|
+ while (p[0] != '\0') { |
|
+ while (e[0] != '\0' && !isspace(e[0]) && e[0] != ',') { |
|
+ ++e; |
|
+ } |
|
+ if (e[0] != '\0') { |
|
+ e[0] = '\0'; |
|
+ ++e; |
|
+ } |
|
+ |
|
+ if (strcasecmp(p, "md5") == 0) { |
|
+ private_ossl_allowed_legacy_mds[idx++] = NID_md5; |
|
+ } else if (strcasecmp(p, "md4") == 0) { |
|
+ private_ossl_allowed_legacy_mds[idx++] = NID_md4; |
|
+ } else if (strcasecmp(p, "sha") == 0) { |
|
+ private_ossl_allowed_legacy_mds[idx++] = NID_sha; |
|
+ } else if (strcasecmp(p, "md2") == 0) { |
|
+ private_ossl_allowed_legacy_mds[idx++] = NID_md2; |
|
+ } |
|
+ |
|
+ if (idx >= |
|
+ sizeof(private_ossl_allowed_legacy_mds) / |
|
+ sizeof(private_ossl_allowed_legacy_mds[0])) { |
|
+ break; |
|
+ } |
|
+ |
|
+ while (e[0] == ',' || isspace(e[0])) { |
|
+ ++e; |
|
+ } |
|
+ |
|
+ p = e; |
|
+ } |
|
+} |
|
+ |
|
+static void parse_minimum_dh_bits(char *p) |
|
+{ |
|
+ private_ossl_minimum_dh_bits = strtol(p, NULL, 10); |
|
+ if (private_ossl_minimum_dh_bits < 512 |
|
+ || private_ossl_minimum_dh_bits > OPENSSL_DH_MAX_MODULUS_BITS) { |
|
+ /* use default */ |
|
+ private_ossl_minimum_dh_bits = 0; |
|
+ } |
|
+} |
|
+ |
|
+static void load_legacy_settings(void) |
|
+{ |
|
+ FILE *f; |
|
+ char *line = NULL; |
|
+ size_t len = 0; |
|
+ |
|
+ if ((f = fopen(LEGACY_SETTINGS_FILE, "r")) == NULL) { |
|
+ return; |
|
+ } |
|
+ |
|
+ while (getline(&line, &len, f) > 0) { |
|
+ char *p = line, *e, *val; |
|
+ |
|
+ /* skip initial whitespace */ |
|
+ while (isspace(p[0])) { |
|
+ ++p; |
|
+ } |
|
+ |
|
+ e = p; |
|
+ |
|
+ while (e[0] != '\0' && !isspace(e[0])) { |
|
+ ++e; |
|
+ } |
|
+ |
|
+ /* terminate name, skip whitespace between name and value */ |
|
+ if (e[0] != '\0') { |
|
+ e[0] = '\0'; |
|
+ ++e; |
|
+ while (isspace(e[0])) { |
|
+ ++e; |
|
+ } |
|
+ } |
|
+ |
|
+ val = e; |
|
+ |
|
+ e = e + strlen(val); |
|
+ |
|
+ /* trim terminating whitespace */ |
|
+ while (e > val) { |
|
+ --e; |
|
+ if (isspace(e[0])) { |
|
+ e[0] = '\0'; |
|
+ } else { |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (strcasecmp(p, "LegacySigningMDs") == 0) { |
|
+ parse_legacy_mds(val); |
|
+ } else if (strcasecmp(line, "MinimumDHBits") == 0) { |
|
+ parse_minimum_dh_bits(val); |
|
+ } |
|
+ /* simply skip other unrecognized lines */ |
|
+ } |
|
+ (void)fclose(f); |
|
+} |
|
+ |
|
/* |
|
* Perform any essential OpenSSL initialization operations. Currently only |
|
* sets FIPS callbacks |
|
@@ -109,6 +228,7 @@ void __attribute__ ((constructor)) OPENS |
|
if (done) |
|
return; |
|
done = 1; |
|
+ load_legacy_settings(); |
|
#ifdef OPENSSL_FIPS |
|
if (!FIPS_module_installed()) { |
|
return; |
|
diff -up openssl-1.0.2j/ssl/s3_clnt.c.deprecate-algos openssl-1.0.2j/ssl/s3_clnt.c |
|
--- openssl-1.0.2j/ssl/s3_clnt.c.deprecate-algos 2016-09-26 11:49:07.000000000 +0200 |
|
+++ openssl-1.0.2j/ssl/s3_clnt.c 2017-01-09 17:01:19.428506961 +0100 |
|
@@ -3478,6 +3478,8 @@ int ssl3_send_client_certificate(SSL *s) |
|
|
|
#define has_bits(i,m) (((i)&(m)) == (m)) |
|
|
|
+extern int private_ossl_minimum_dh_bits; |
|
+ |
|
int ssl3_check_cert_and_algorithm(SSL *s) |
|
{ |
|
int i, idx; |
|
@@ -3608,8 +3610,7 @@ int ssl3_check_cert_and_algorithm(SSL *s |
|
DH_free(dh_srvr); |
|
} |
|
|
|
- if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024) |
|
- || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { |
|
+ if (dh_size < (private_ossl_minimum_dh_bits ? private_ossl_minimum_dh_bits : 1024)) { |
|
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); |
|
goto f_err; |
|
}
|
|
|