8061842: Package jurisdiction policy files as something other than JAR
authorwetmore
Fri, 26 Aug 2016 13:44:20 -0700
changeset 40565 3ac0ba151e70
parent 40564 242110f0c920
child 40566 cf1f1b3822e7
8061842: Package jurisdiction policy files as something other than JAR Reviewed-by: xuelei, weijun, mullan
jdk/make/data/cryptopolicy/limited/default_local.policy
jdk/make/data/cryptopolicy/limited/exempt_local.policy
jdk/make/data/cryptopolicy/unlimited/default_US_export.policy
jdk/make/data/cryptopolicy/unlimited/default_local.policy
jdk/make/gendata/Gendata-java.base.gmk
jdk/make/gendata/GendataCryptoPolicy.gmk
jdk/make/gendata/GendataPolicyJars.gmk
jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java
jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java
jdk/src/java.base/share/conf/security/java.security
jdk/src/java.base/share/conf/security/policy/README.txt
jdk/src/java.base/share/conf/security/policy/limited/default_US_export.policy
jdk/src/java.base/share/conf/security/policy/limited/default_local.policy
jdk/src/java.base/share/conf/security/policy/limited/exempt_local.policy
jdk/src/java.base/share/conf/security/policy/unlimited/default_US_export.policy
jdk/src/java.base/share/conf/security/policy/unlimited/default_local.policy
jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java
jdk/test/jdk/security/JavaDotSecurity/final_java_security
jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh
jdk/test/jdk/security/JavaDotSecurity/raw_java_security
--- a/jdk/make/data/cryptopolicy/limited/default_local.policy	Thu Aug 25 20:53:40 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-// Some countries have import limits on crypto strength. This policy file
-// is worldwide importable.
-
-grant {
-    permission javax.crypto.CryptoPermission "DES", 64;
-    permission javax.crypto.CryptoPermission "DESede", *;
-    permission javax.crypto.CryptoPermission "RC2", 128, 
-                                     "javax.crypto.spec.RC2ParameterSpec", 128;
-    permission javax.crypto.CryptoPermission "RC4", 128;
-    permission javax.crypto.CryptoPermission "RC5", 128, 
-          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
-    permission javax.crypto.CryptoPermission "RSA", *;
-    permission javax.crypto.CryptoPermission *, 128;
-};
--- a/jdk/make/data/cryptopolicy/limited/exempt_local.policy	Thu Aug 25 20:53:40 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-// Some countries have import limits on crypto strength. So this file
-// will be useful.
-
-grant {
-    // There is no restriction to any algorithms if KeyRecovery is enforced.
-    permission javax.crypto.CryptoPermission *, "KeyRecovery"; 
-
-    // There is no restriction to any algorithms if KeyEscrow is enforced.
-    permission javax.crypto.CryptoPermission *, "KeyEscrow"; 
-
-    // There is no restriction to any algorithms if KeyWeakening is enforced. 
-    permission javax.crypto.CryptoPermission *, "KeyWeakening";
-};
--- a/jdk/make/data/cryptopolicy/unlimited/default_US_export.policy	Thu Aug 25 20:53:40 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// Manufacturing policy file.
-grant {
-    // There is no restriction to any algorithms.
-    permission javax.crypto.CryptoAllPermission; 
-};
--- a/jdk/make/data/cryptopolicy/unlimited/default_local.policy	Thu Aug 25 20:53:40 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// Country-specific policy file for countries with no limits on crypto strength.
-grant {
-    // There is no restriction to any algorithms.
-    permission javax.crypto.CryptoAllPermission; 
-};
--- a/jdk/make/gendata/Gendata-java.base.gmk	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/make/gendata/Gendata-java.base.gmk	Fri Aug 26 13:44:20 2016 -0700
@@ -34,7 +34,7 @@
 
 include GendataBlacklistedCerts.gmk
 
-include GendataPolicyJars.gmk
+include GendataCryptoPolicy.gmk
 
 ################################################################################
 
@@ -64,13 +64,19 @@
 GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security
 GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security
 
+ifeq ($(UNLIMITED_CRYPTO), true)
+    CRYPTO.POLICY := unlimited
+else
+    CRYPTO.POLICY := limited
+endif
+
 # RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
 
 $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
 	$(call LogInfo, Generating java.security)
 	$(call MakeDir, $(@D))
 	$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
-	    $(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC)
+	    $(OPENJDK_TARGET_CPU_ARCH) $(CRYPTO.POLICY) $(RESTRICTED_PKGS_SRC)
 
 TARGETS += $(GENDATA_JAVA_SECURITY)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gendata/GendataCryptoPolicy.gmk	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# In pre-JDK9 releases, Oracle JDK has had a separately downloadable set
+# of policy files which has been a nightmare for deployment.
+#
+# We now create 2 complete initial sets of policy files and package into 
+# 2 different directories.  The crypto.policy Security property will select
+# the active policy.
+#
+# It will be up to the user/deployer to make an informed choice
+# as to whether they are legally entitled to use the unlimited policy
+# file in their environment.  The $(UNLIMITED_CRYPTO) make variable
+# determines the default directory/policy.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+
+################################################################################
+POLICY_DIR := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/policy
+LIMITED_POLICY_DIR := $(POLICY_DIR)/limited
+UNLIMITED_POLICY_DIR := $(POLICY_DIR)/unlimited
+
+POLICY_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/conf/security/policy
+LIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/limited
+UNLIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/unlimited
+
+$(POLICY_DIR)/README.txt: $(POLICY_SRC_DIR)/README.txt
+	$(install-file)
+
+$(LIMITED_POLICY_DIR)/%: $(LIMITED_POLICY_SRC_DIR)/%
+	$(install-file)
+
+$(UNLIMITED_POLICY_DIR)/%: $(UNLIMITED_POLICY_SRC_DIR)/%
+	$(install-file)
+
+TARGETS += \
+    $(POLICY_DIR)/README.txt \
+    $(LIMITED_POLICY_DIR)/default_US_export.policy \
+    $(LIMITED_POLICY_DIR)/default_local.policy \
+    $(LIMITED_POLICY_DIR)/exempt_local.policy \
+    $(UNLIMITED_POLICY_DIR)/default_US_export.policy \
+    $(UNLIMITED_POLICY_DIR)/default_local.policy \
+
+################################################################################
--- a/jdk/make/gendata/GendataPolicyJars.gmk	Thu Aug 25 20:53:40 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-#
-# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-default: all
-
-include $(SPEC)
-include MakeBase.gmk
-include JarArchive.gmk
-
-
-################################################################################
-
-US_EXPORT_POLICY_JAR_DST := \
-    $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/US_export_policy.jar
-
-US_EXPORT_POLICY_JAR_LIMITED := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar
-US_EXPORT_POLICY_JAR_UNLIMITED := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar
-
-#
-# TODO fix so that SetupJarArchive does not write files into SRCS
-# then we don't need this extra copying
-#
-# NOTE: We currently do not place restrictions on our limited export
-# policy. This was not a typo. This means we are shipping the same file
-# for both limited and unlimited US_export_policy.jar.  Only the local
-# policy file currently has restrictions.
-#
-US_EXPORT_POLICY_JAR_SRC_DIR := \
-    $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited
-US_EXPORT_POLICY_JAR_TMP := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp
-
-$(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/%
-	$(install-file)
-
-US_EXPORT_POLICY_JAR_DEPS := \
-    $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy
-
-$(eval $(call SetupJarArchive, BUILD_US_EXPORT_POLICY_JAR, \
-    DEPENDENCIES := $(US_EXPORT_POLICY_JAR_DEPS), \
-    SRCS := $(US_EXPORT_POLICY_JAR_TMP), \
-    SUFFIXES := .policy, \
-    JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \
-    EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
-    SKIP_METAINF := true, \
-))
-
-$(US_EXPORT_POLICY_JAR_LIMITED): \
-    $(US_EXPORT_POLICY_JAR_UNLIMITED)
-	$(call LogInfo, Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@))
-	$(install-file)
-
-TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED)
-
-ifeq ($(UNLIMITED_CRYPTO), true)
-  $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNLIMITED)
-	$(install-file)
-else
-  $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_LIMITED)
-	$(install-file)
-endif
-
-POLICY_JARS += $(US_EXPORT_POLICY_JAR_DST)
-
-################################################################################
-
-LOCAL_POLICY_JAR_DST := \
-    $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/local_policy.jar
-
-LOCAL_POLICY_JAR_LIMITED := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar
-LOCAL_POLICY_JAR_UNLIMITED := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar
-
-#
-# TODO fix so that SetupJarArchive does not write files into SRCS
-# then we don't need this extra copying
-#
-LOCAL_POLICY_JAR_LIMITED_TMP := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp
-LOCAL_POLICY_JAR_UNLIMITED_TMP := \
-    $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp
-
-$(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \
-    $(JDK_TOPDIR)/make/data/cryptopolicy/limited/%
-	$(install-file)
-
-$(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \
-    $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/%
-	$(install-file)
-
-$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_LIMITED, \
-    DEPENDENCIES := $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \
-        $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \
-    SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \
-    SUFFIXES := .policy, \
-    JAR := $(LOCAL_POLICY_JAR_LIMITED), \
-    EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \
-    SKIP_METAINF := true, \
-))
-
-$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_UNLIMITED, \
-    DEPENDENCIES := $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \
-    SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \
-    SUFFIXES := .policy, \
-    JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \
-    EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
-    SKIP_METAINF := true, \
-))
-
-TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED)
-
-ifeq ($(UNLIMITED_CRYPTO), true)
-  $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_UNLIMITED)
-	$(install-file)
-else
-  $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_LIMITED)
-	$(install-file)
-endif
-
-POLICY_JARS += $(LOCAL_POLICY_JAR_DST)
-TARGETS += $(POLICY_JARS)
-
-################################################################################
-
-$(eval $(call IncludeCustomExtension, jdk, gendata/GendataPolicyJars.gmk))
--- a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java	Fri Aug 26 13:44:20 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,8 @@
  *
  * 1. Adds additional packages to the package.access and
  *    package.definition security properties.
- * 2. Filter out platform-unrelated parts
+ * 2. Filter out platform-unrelated parts.
+ * 3. Set the JCE jurisdiction policy directory.
  *
  * In order to easily maintain platform-related entries, every item
  * (including the last line) in package.access and package.definition
@@ -50,12 +51,13 @@
 
     public static void main(String[] args) throws Exception {
 
-        if (args.length < 4) {
+        if (args.length < 5) {
             System.err.println("Usage: java MakeJavaSecurity " +
                                "[input java.security file name] " +
                                "[output java.security file name] " +
                                "[openjdk target os] " +
                                "[openjdk target cpu architecture]" +
+                               "[JCE jurisdiction policy directory]" +
                                "[more restricted packages file name?]");
 
                     System.exit(1);
@@ -63,8 +65,8 @@
 
         // more restricted packages
         List<String> extraLines;
-        if (args.length == 5) {
-            extraLines = Files.readAllLines(Paths.get(args[4]));
+        if (args.length == 6) {
+            extraLines = Files.readAllLines(Paths.get(args[5]));
         } else {
             extraLines = Collections.emptyList();
         }
@@ -135,6 +137,16 @@
             }
         }
 
+        // Set the JCE policy value
+        for (int i = 0; i < lines.size(); i++) {
+            String line = lines.get(i);
+            int index = line.indexOf("crypto.policydir-tbd");
+            if (index >= 0) {
+                String prefix = line.substring(0, index);
+                lines.set(i, prefix + args[4]);
+            }
+        }
+
         // Clean up the last line of PKG_ACC and PKG_DEF blocks.
         // Not really necessary since a blank line follows.
         boolean inBlock = false;
--- a/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java	Fri Aug 26 13:44:20 2016 -0700
@@ -29,6 +29,7 @@
 import java.util.jar.*;
 import java.io.*;
 import java.net.URL;
+import java.nio.file.*;
 import java.security.*;
 
 import java.security.Provider.Service;
@@ -206,7 +207,7 @@
 
     static {
         try {
-            NULL_URL = new URL("http://null.sun.com/");
+            NULL_URL = new URL("http://null.oracle.com/");
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -243,83 +244,94 @@
         }
     }
 
+    // This is called from within an doPrivileged block.
     private static void setupJurisdictionPolicies() throws Exception {
-        String javaHomeDir = System.getProperty("java.home");
-        String sep = File.separator;
-        String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
-            "security" + sep;
+
+        // Sanity check the crypto.policy Security property.  Single
+        // directory entry, no pseudo-directories (".", "..", leading/trailing
+        // path separators). normalize()/getParent() will help later.
+        String cryptoPolicyProperty = Security.getProperty("crypto.policy");
+        Path cpPath = Paths.get(cryptoPolicyProperty);
+
+        if ((cryptoPolicyProperty == null) ||
+                (cpPath.getNameCount() != 1) ||
+                (cpPath.compareTo(cpPath.getFileName()) != 0)) {
+            throw new SecurityException(
+                "Invalid policy directory name format: " +
+                cryptoPolicyProperty);
+        }
 
-        File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
-        File importJar = new File(pathToPolicyJar, "local_policy.jar");
+        // Prepend java.home to get the full path.  normalize() in
+        // case an extra "." or ".." snuck in somehow.
+        String javaHomeProperty = System.getProperty("java.home");
+        Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
+                "security", "policy").normalize();
+        Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",
+                "policy", cryptoPolicyProperty).normalize();
 
-        if (!exportJar.exists() || !importJar.exists()) {
-            throw new SecurityException
-                                ("Cannot locate policy or framework files!");
+        if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) {
+            throw new SecurityException(
+                "Invalid cryptographic jurisdiction policy directory path: " +
+                cryptoPolicyProperty);
+        }
+
+        if (!Files.isDirectory(cryptoPolicyPath)
+                || !Files.isReadable(cryptoPolicyPath)) {
+            throw new SecurityException(
+                "Can't read cryptographic policy directory: " +
+                cryptoPolicyProperty);
         }
 
-        // Read jurisdiction policies.
-        CryptoPermissions defaultExport = new CryptoPermissions();
-        CryptoPermissions exemptExport = new CryptoPermissions();
-        loadPolicies(exportJar, defaultExport, exemptExport);
-
-        CryptoPermissions defaultImport = new CryptoPermissions();
-        CryptoPermissions exemptImport = new CryptoPermissions();
-        loadPolicies(importJar, defaultImport, exemptImport);
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(
+                cryptoPolicyPath, "{default,exempt}_*.policy")) {
+            for (Path entry : stream) {
+                try (InputStream is = new BufferedInputStream(
+                        Files.newInputStream(entry))) {
+                    String filename = entry.getFileName().toString();
 
-        // Merge the export and import policies for default applications.
-        if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
-            throw new SecurityException("Missing mandatory jurisdiction " +
-                                        "policy files");
-        }
-        defaultPolicy = defaultExport.getMinimum(defaultImport);
-
-        // Merge the export and import policies for exempt applications.
-        if (exemptExport.isEmpty())  {
-            exemptPolicy = exemptImport.isEmpty() ? null : exemptImport;
-        } else {
-            exemptPolicy = exemptExport.getMinimum(exemptImport);
-        }
-    }
+                    CryptoPermissions tmpPerms = new CryptoPermissions();
+                    tmpPerms.load(is);
 
-    /**
-     * Load the policies from the specified file. Also checks that the
-     * policies are correctly signed.
-     */
-    private static void loadPolicies(File jarPathName,
-                                     CryptoPermissions defaultPolicy,
-                                     CryptoPermissions exemptPolicy)
-        throws Exception {
-
-        JarFile jf = new JarFile(jarPathName);
-
-        Enumeration<JarEntry> entries = jf.entries();
-        while (entries.hasMoreElements()) {
-            JarEntry je = entries.nextElement();
-            InputStream is = null;
-            try {
-                if (je.getName().startsWith("default_")) {
-                    is = jf.getInputStream(je);
-                    defaultPolicy.load(is);
-                } else if (je.getName().startsWith("exempt_")) {
-                    is = jf.getInputStream(je);
-                    exemptPolicy.load(is);
-                } else {
-                    continue;
-                }
-            } finally {
-                if (is != null) {
-                    is.close();
+                    if (filename.startsWith("default_")) {
+                        // Did we find a default perms?
+                        defaultPolicy = ((defaultPolicy == null) ? tmpPerms :
+                                defaultPolicy.getMinimum(tmpPerms));
+                    } else if (filename.startsWith("exempt_")) {
+                        // Did we find a exempt perms?
+                        exemptPolicy = ((exemptPolicy == null) ? tmpPerms :
+                                exemptPolicy.getMinimum(tmpPerms));
+                    } else {
+                        // This should never happen.  newDirectoryStream
+                        // should only throw return "{default,exempt}_*.policy"
+                        throw new SecurityException(
+                            "Unexpected jurisdiction policy files in : " +
+                            cryptoPolicyProperty);
+                    }
+                } catch (Exception e) {
+                    throw new SecurityException(
+                        "Couldn't parse jurisdiction policy files in: " +
+                        cryptoPolicyProperty);
                 }
             }
+        } catch (DirectoryIteratorException ex) {
+            // I/O error encountered during the iteration,
+            // the cause is an IOException
+            throw new SecurityException(
+                "Couldn't iterate through the jurisdiction policy files: " +
+                cryptoPolicyProperty);
+        }
 
-            // Enforce the signer restraint, i.e. signer of JCE framework
-            // jar should also be the signer of the two jurisdiction policy
-            // jar files.
-            ProviderVerifier.verifyPolicySigned(je.getCertificates());
+        // Must have a default policy
+        if ((defaultPolicy == null) || defaultPolicy.isEmpty()) {
+            throw new SecurityException(
+                "Missing mandatory jurisdiction policy files: " +
+                cryptoPolicyProperty);
         }
-        // Close and nullify the JarFile reference to help GC.
-        jf.close();
-        jf = null;
+
+        // If there was an empty exempt policy file, ignore it.
+        if ((exemptPolicy != null) && exemptPolicy.isEmpty()) {
+            exemptPolicy = null;
+        }
     }
 
     static CryptoPermissions getDefaultPolicy() {
--- a/jdk/src/java.base/share/conf/security/java.security	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/src/java.base/share/conf/security/java.security	Fri Aug 26 13:44:20 2016 -0700
@@ -804,6 +804,56 @@
 #       EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
 #       FFFFFFFF FFFFFFFF, 2}
 
+# Cryptographic Jurisdiction Policy defaults
+# 
+# Due to the import control restrictions of some countries, the default
+# JCE policy files allow for strong but "limited" cryptographic key
+# lengths to be used.  If your country's cryptographic regulations allow,
+# the "unlimited" strength policy files can be used instead, which contain
+# no restrictions on cryptographic strengths.
+# 
+# If your country has restrictions that don't fit either "limited" or
+# "unlimited", an appropriate set of policy files should be created and
+# configured before using this distribution.  The jurisdiction policy file
+# configuration must reflect the cryptographic restrictions appropriate
+# for your country.
+# 
+# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY
+# TO DETERMINE THE EXACT REQUIREMENTS.
+# 
+# The policy files are flat text files organized into subdirectories of
+# <java-home>/conf/security/policy.  Each directory contains a complete
+# set of policy files.
+#
+# The "crypto.policy" Security property controls the directory selection,
+# and thus the effective cryptographic policy.
+# 
+# The default set of directories is:  
+# 
+#     limited | unlimited 
+# 
+# however other directories can be created and configured.
+# 
+# Within a directory, the effective policy is the combined minimum
+# permissions of the grant statements in the file(s) with the filename
+# pattern "default_*.policy".  At least one grant is required.  For
+# example:
+#
+#     limited   =  Export (all) + Import (limited)  =  Limited
+#     unlimited =  Export (all) + Import (all)      =  Unlimited
+#
+# The effective exemption policy is the combined minimum permissions
+# of the grant statements in the file(s) with the filename pattern
+# "exempt_*.policy".  Exemption grants are optional.
+#
+#     limited   =  grants exemption permissions, by which the
+#                  effective policy can be circumvented. 
+#                  e.g.  KeyRecovery/Escrow/Weakening.
+# 
+# Please see the JCA documentation for additional information on these
+# files and formats.
+crypto.policy=crypto.policydir-tbd
+
 #
 # The policy for the XML Signature secure validation mode. The mode is
 # enabled by setting the property "org.jcp.xml.dsig.secureValidation" to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/README.txt	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,35 @@
+
+            Java(TM) Cryptography Extension Policy Files
+    for the Java(TM) Platform, Standard Edition Runtime Environment
+
+                               README
+------------------------------------------------------------------------
+
+
+The JCE architecture allows flexible cryptographic strength to be
+configured via the jurisdiction policy files contained within these
+directories.
+
+Due to import control restrictions of some countries, the default
+JCE policy files bundled in this Java Runtime Environment allow
+for strong but "limited" cryptographic strengths.  For convenience,
+this build also contains the "unlimited strength" policy files which
+contain no restrictions on cryptographic strengths, but they must be
+specifically activated by updating the "crypto.policy" Security property
+(e.g. <java-home>/conf/security/java.security) to point to the appropriate
+directory.
+
+Each subdirectory contains a complete policy configuration, and additional
+subdirectories can be added/removed to reflect local regulations.
+
+JCE for Java SE has been through the U.S. export review process.  The JCE
+framework, along with the various JCE providers that come standard with it
+(SunJCE, SunEC, SunPKCS11, SunMSCAPI, etc), is exportable from the
+United States.
+
+You are advised to consult your export/import control counsel or attorney
+to determine the exact requirements of your location, and what policy
+settings should be used.
+
+Please see The Java(TM) Cryptography Architecture (JCA) Reference
+Guide and the java.security file for more information.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/limited/default_US_export.policy	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,6 @@
+// Default US Export policy file.
+
+grant {
+    // There is no restriction to any algorithms.
+    permission javax.crypto.CryptoAllPermission; 
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/limited/default_local.policy	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,14 @@
+// Some countries have import limits on crypto strength. This policy file
+// is worldwide importable.
+
+grant {
+    permission javax.crypto.CryptoPermission "DES", 64;
+    permission javax.crypto.CryptoPermission "DESede", *;
+    permission javax.crypto.CryptoPermission "RC2", 128, 
+                                     "javax.crypto.spec.RC2ParameterSpec", 128;
+    permission javax.crypto.CryptoPermission "RC4", 128;
+    permission javax.crypto.CryptoPermission "RC5", 128, 
+          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
+    permission javax.crypto.CryptoPermission "RSA", *;
+    permission javax.crypto.CryptoPermission *, 128;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/limited/exempt_local.policy	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,13 @@
+// Some countries have import limits on crypto strength, but may allow for
+// these exemptions if the exemption mechanism is used.
+
+grant {
+    // There is no restriction to any algorithms if KeyRecovery is enforced.
+    permission javax.crypto.CryptoPermission *, "KeyRecovery"; 
+
+    // There is no restriction to any algorithms if KeyEscrow is enforced.
+    permission javax.crypto.CryptoPermission *, "KeyEscrow"; 
+
+    // There is no restriction to any algorithms if KeyWeakening is enforced. 
+    permission javax.crypto.CryptoPermission *, "KeyWeakening";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/unlimited/default_US_export.policy	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,6 @@
+// Default US Export policy file.
+
+grant {
+    // There is no restriction to any algorithms.
+    permission javax.crypto.CryptoAllPermission; 
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/unlimited/default_local.policy	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,6 @@
+// Country-specific policy file for countries with no limits on crypto strength.
+
+grant {
+    // There is no restriction to any algorithms.
+    permission javax.crypto.CryptoAllPermission; 
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java	Fri Aug 26 13:44:20 2016 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8061842
+ * @summary Package jurisdiction policy files as something other than JAR
+ * @run main/othervm TestUnlimited "" exception
+ * @run main/othervm TestUnlimited limited fail
+ * @run main/othervm TestUnlimited unlimited pass
+ * @run main/othervm TestUnlimited unlimited/ pass
+ * @run main/othervm TestUnlimited NosuchDir exception
+ * @run main/othervm TestUnlimited . exception
+ * @run main/othervm TestUnlimited /tmp/unlimited exception
+ * @run main/othervm TestUnlimited ../policy/unlimited exception
+ * @run main/othervm TestUnlimited ./unlimited exception
+ * @run main/othervm TestUnlimited /unlimited exception
+ */
+import javax.crypto.*;
+import java.security.Security;
+
+public class TestUnlimited {
+
+    public static void main(String[] args) throws Exception {
+        /*
+         * Override the Security property to allow for unlimited policy.
+         * Would need appropriate permissions if Security Manager were
+         * active.
+         */
+        if (args.length != 2) {
+            throw new Exception("Two args required");
+        }
+
+        boolean expected = args[1].equals("pass");
+        boolean exception = args[1].equals("exception");
+        boolean result = false;
+
+        System.out.println("Testing: " + args[0]);
+
+        if (args[0].equals("\"\"")) {
+            Security.setProperty("crypto.policy", "");
+        } else {
+            Security.setProperty("crypto.policy", args[0]);
+        }
+
+        /*
+         * Use the AES as the test Cipher
+         * If there is an error initializing, we will never get past here.
+         */
+        try {
+            int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
+            System.out.println("max AES key len:" + maxKeyLen);
+            if (maxKeyLen > 128) {
+                System.out.println("Unlimited policy is active");
+                result = true;
+            } else {
+                System.out.println("Unlimited policy is NOT active");
+                result = false;
+            }
+        } catch (Throwable e) {
+            if (!exception) {
+                throw new Exception();
+            }
+        }
+
+        System.out.println(
+                "Expected:\t" + expected + "\nResult:\t\t" + result);
+        if (expected != result) {
+            throw new Exception();
+        }
+
+        System.out.println("DONE!");
+    }
+}
--- a/jdk/test/jdk/security/JavaDotSecurity/final_java_security	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/test/jdk/security/JavaDotSecurity/final_java_security	Fri Aug 26 13:44:20 2016 -0700
@@ -10,6 +10,7 @@
 foo.6=9a
 foo.7=10
 foo.8=12
+crypto.policy=somepolicy
 
 package.access=sun.,\
                solaris.,\
--- a/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh	Fri Aug 26 13:44:20 2016 -0700
@@ -46,7 +46,13 @@
 fi
 
 $JAVAC -d . $TOOLSRC
-$JAVA $TOOLNAME $TESTSRC/raw_java_security outfile solaris sparc $TESTSRC/more_restricted
+$JAVA $TOOLNAME \
+    $TESTSRC/raw_java_security \
+    outfile \
+    solaris \
+    sparc \
+    somepolicy \
+    $TESTSRC/more_restricted
 
 # On Windows, line end could be different. -b is a cross-platform option.
-diff -b outfile $TESTSRC/final_java_security
\ No newline at end of file
+diff -b outfile $TESTSRC/final_java_security
--- a/jdk/test/jdk/security/JavaDotSecurity/raw_java_security	Thu Aug 25 20:53:40 2016 +0300
+++ b/jdk/test/jdk/security/JavaDotSecurity/raw_java_security	Fri Aug 26 13:44:20 2016 -0700
@@ -44,6 +44,7 @@
 #ifndef macosx-x64
 foo.tbd=12
 #endif
+crypto.policy=crypto.policydir-tbd
 
 package.access=sun.,\
 #ifdef solaris