Blame SOURCES/openssl-1.0.2j-deprecate-algos.patch

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