8170157: Enable unlimited cryptographic policy by default in OracleJDK
8169335: Add a crypto policy fallback in case Security Property 'crypto.policy' does not exist Reviewed-by: erikj, ihse, weijun, xuelei, coffeys
This commit is contained in:
parent
615fbfe49c
commit
fdb9c95f6b
jdk
make/gensrc
src/java.base/share
test/javax/crypto/CryptoPermissions
@ -108,3 +108,19 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Create the javax/crypto/JceSecurity.class, using the build default.
|
||||
#
|
||||
ifeq ($(UNLIMITED_CRYPTO), true)
|
||||
JCE_DEFAULT_POLICY = unlimited
|
||||
else
|
||||
JCE_DEFAULT_POLICY = limited
|
||||
endif
|
||||
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JCESECURITY_JAVA, \
|
||||
SOURCE_FILES := $(JDK_TOPDIR)/src/java.base/share/classes/javax/crypto/JceSecurity.java.template, \
|
||||
OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/javax/crypto/JceSecurity.java, \
|
||||
REPLACEMENTS := \
|
||||
@@JCE_DEFAULT_POLICY@@ => $(JCE_DEFAULT_POLICY), \
|
||||
))
|
||||
|
||||
GENSRC_JAVA_BASE += $(BUILD_JCESECURITY_JAVA)
|
||||
|
@ -23,10 +23,33 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* README README README README README README README README README
|
||||
*
|
||||
* This file is the template for generating the JceSecurity.java source
|
||||
* file.
|
||||
*
|
||||
* In the current jdk builds, this file is first preprocessed to replace
|
||||
* @@JCE_DEFAULT_POLICY@ [sic] with "limited" or "unlimited" which is
|
||||
* determined by the $(UNLIMTED_CRYPTO) make variable. This variable is
|
||||
* set by top-level configure script, using either
|
||||
* --disable-unlimited-crypto or --enable-unlimited-crypto [default].
|
||||
*
|
||||
* Since this file is a generated source, incremental changes to
|
||||
* this file require regenerating the source. Compilation options:
|
||||
*
|
||||
* (fewer dependencies/"faster" ones first)
|
||||
*
|
||||
* 1. make JDK_FILTER=javax/crypto java.base-gensrc-only java.base-java-only
|
||||
* 2. make java.base-gensrc-only java.base-java-only
|
||||
* 3. make java.base-gensrc-only java.base-only
|
||||
* 4. make java.base-only
|
||||
* 5. make
|
||||
*/
|
||||
|
||||
package javax.crypto;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.jar.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.file.*;
|
||||
@ -36,6 +59,7 @@ import java.security.Provider.Service;
|
||||
|
||||
import sun.security.jca.*;
|
||||
import sun.security.jca.GetInstance.Instance;
|
||||
import sun.security.util.Debug;
|
||||
|
||||
/**
|
||||
* This class instantiates implementations of JCE engine classes from
|
||||
@ -47,6 +71,9 @@ import sun.security.jca.GetInstance.Instance;
|
||||
*/
|
||||
|
||||
final class JceSecurity {
|
||||
|
||||
|
||||
private static final Debug debug = Debug.getInstance("jca");
|
||||
|
||||
static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
@ -251,10 +278,27 @@ final class JceSecurity {
|
||||
// directory entry, no pseudo-directories (".", "..", leading/trailing
|
||||
// path separators). normalize()/getParent() will help later.
|
||||
String cryptoPolicyProperty = Security.getProperty("crypto.policy");
|
||||
|
||||
/*
|
||||
* In case no property is present, rather than fail catastrophically,
|
||||
* we at least try for a "sane" value, which is what we were
|
||||
* built with. We first preprocess this file to plug in that
|
||||
* value, then compile the result gensrc.
|
||||
*
|
||||
* Log the warning first.
|
||||
*/
|
||||
if (cryptoPolicyProperty == null) {
|
||||
cryptoPolicyProperty = "@@JCE_DEFAULT_POLICY@@";
|
||||
if (debug != null) {
|
||||
debug.println(
|
||||
"Security Property 'crypto.policy' not found: "
|
||||
+ "using '" + cryptoPolicyProperty + "' as fallback");
|
||||
}
|
||||
}
|
||||
|
||||
Path cpPath = Paths.get(cryptoPolicyProperty);
|
||||
|
||||
if ((cryptoPolicyProperty == null) ||
|
||||
(cpPath.getNameCount() != 1) ||
|
||||
if ((cpPath.getNameCount() != 1) ||
|
||||
(cpPath.compareTo(cpPath.getFileName()) != 0)) {
|
||||
throw new SecurityException(
|
||||
"Invalid policy directory name format: " +
|
@ -849,35 +849,35 @@ jdk.tls.legacyAlgorithms= \
|
||||
# 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
|
||||
#
|
||||
#
|
||||
# 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
|
||||
@ -891,11 +891,15 @@ jdk.tls.legacyAlgorithms= \
|
||||
# "exempt_*.policy". Exemption grants are optional.
|
||||
#
|
||||
# limited = grants exemption permissions, by which the
|
||||
# effective policy can be circumvented.
|
||||
# effective policy can be circumvented.
|
||||
# e.g. KeyRecovery/Escrow/Weakening.
|
||||
#
|
||||
#
|
||||
# Please see the JCA documentation for additional information on these
|
||||
# files and formats.
|
||||
#
|
||||
# Note: This property is currently used by the JDK Reference implementation.
|
||||
# It is not guaranteed to be examined and used by other implementations.
|
||||
#
|
||||
crypto.policy=crypto.policydir-tbd
|
||||
|
||||
#
|
||||
@ -951,7 +955,8 @@ jdk.xml.dsig.secureValidationPolicy=\
|
||||
#
|
||||
# If a pattern includes a "=", it sets a limit.
|
||||
# If a limit appears more than once the last value is used.
|
||||
# Limits are checked before classes regardless of the order in the sequence of patterns.
|
||||
# Limits are checked before classes regardless of the order in the
|
||||
# sequence of patterns.
|
||||
# If any of the limits are exceeded, the filter status is REJECTED.
|
||||
#
|
||||
# maxdepth=value - the maximum depth of a graph
|
||||
@ -961,20 +966,24 @@ jdk.xml.dsig.secureValidationPolicy=\
|
||||
#
|
||||
# Other patterns, from left to right, match the class or package name as
|
||||
# returned from Class.getName.
|
||||
# If the class is an array type, the class or package to be matched is the element type.
|
||||
# If the class is an array type, the class or package to be matched is the
|
||||
# element type.
|
||||
# Arrays of any number of dimensions are treated the same as the element type.
|
||||
# For example, a pattern of "!example.Foo", rejects creation of any instance or
|
||||
# array of example.Foo.
|
||||
#
|
||||
# If the pattern starts with "!", the status is REJECTED if the remaining pattern
|
||||
# is matched; otherwise the status is ALLOWED if the pattern matches.
|
||||
# If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
|
||||
# If the pattern starts with "!", the status is REJECTED if the remaining
|
||||
# pattern is matched; otherwise the status is ALLOWED if the pattern matches.
|
||||
# If the pattern contains "/", the non-empty prefix up to the "/" is the
|
||||
# module name;
|
||||
# if the module name matches the module name of the class then
|
||||
# the remaining pattern is matched with the class name.
|
||||
# If there is no "/", the module name is not compared.
|
||||
# If the pattern ends with ".**" it matches any class in the package and all subpackages.
|
||||
# If the pattern ends with ".**" it matches any class in the package and all
|
||||
# subpackages.
|
||||
# If the pattern ends with ".*" it matches any class in the package.
|
||||
# If the pattern ends with "*", it matches any class with the pattern as a prefix.
|
||||
# If the pattern ends with "*", it matches any class with the pattern as a
|
||||
# prefix.
|
||||
# If the pattern is equal to the class name, it matches.
|
||||
# Otherwise, the status is UNDECIDED.
|
||||
#
|
||||
|
@ -10,11 +10,10 @@ 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
|
||||
The default JCE policy files bundled in this Java Runtime Environment
|
||||
allow for "unlimited" cryptographic strengths. For convenience,
|
||||
this build also contains the historic "limited" strength policy files
|
||||
which contain 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.
|
||||
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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 8169335
|
||||
* @summary Add a crypto policy fallback in case Security Property
|
||||
* 'crypto.policy' does not exist.
|
||||
* @run main/othervm CryptoPolicyFallback
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.stream.*;
|
||||
import javax.crypto.*;
|
||||
|
||||
/*
|
||||
* Take the current java.security file, strip out the 'crypto.policy' entry,
|
||||
* write to a new file in the current directory, then use that file as the
|
||||
* replacement java.security file. This test will fail if the crypto.policy
|
||||
* entry doesn't match the compiled in value.
|
||||
*/
|
||||
public class CryptoPolicyFallback {
|
||||
|
||||
private static final String FILENAME = "java.security";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String javaHome = System.getProperty("java.home");
|
||||
|
||||
Path path = Paths.get(javaHome, "conf", "security", FILENAME);
|
||||
|
||||
/*
|
||||
* Get the default value.
|
||||
*/
|
||||
String defaultPolicy;
|
||||
try (Stream<String> lines = Files.lines(path)) {
|
||||
/*
|
||||
* If the input java.security file is malformed
|
||||
* (missing crypto.policy, attribute/no value, etc), throw
|
||||
* exception. split() might throw AIOOB which
|
||||
* is ok behavior.
|
||||
*/
|
||||
defaultPolicy = lines.filter(x -> x.startsWith("crypto.policy="))
|
||||
.findFirst().orElseThrow(
|
||||
() -> new Exception("Missing crypto.policy"))
|
||||
.split("=")[1].trim();
|
||||
}
|
||||
|
||||
/*
|
||||
* We know there is at least one crypto.policy entry, strip
|
||||
* all of them out of the java.security file.
|
||||
*/
|
||||
try (PrintWriter out = new PrintWriter(FILENAME);
|
||||
Stream<String> lines = Files.lines(path)) {
|
||||
lines.filter(x -> !x.trim().startsWith("crypto.policy="))
|
||||
.forEach(out::println);
|
||||
}
|
||||
|
||||
/*
|
||||
* "-Djava.security.properties==file" does a complete replacement
|
||||
* of the system java.security file. i.e. value must be "=file"
|
||||
*/
|
||||
System.setProperty("java.security.properties", "=" + FILENAME);
|
||||
|
||||
/*
|
||||
* Find out expected value.
|
||||
*/
|
||||
int expected;
|
||||
switch (defaultPolicy) {
|
||||
case "limited":
|
||||
expected = 128;
|
||||
break;
|
||||
case "unlimited":
|
||||
expected = Integer.MAX_VALUE;
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
"Unexpected Default Policy Value: " + defaultPolicy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the actual check. If the JCE Framework can't initialize
|
||||
* an Exception is normally thrown here.
|
||||
*/
|
||||
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
|
||||
|
||||
System.out.println("Default Policy: " + defaultPolicy
|
||||
+ "\nExpected max AES key length: " + expected
|
||||
+ ", received : " + maxKeyLen);
|
||||
|
||||
if (expected != maxKeyLen) {
|
||||
throw new Exception("Wrong Key Length size!");
|
||||
}
|
||||
|
||||
System.out.println("PASSED!");
|
||||
}
|
||||
}
|
@ -27,10 +27,11 @@
|
||||
* @test
|
||||
* @bug 8061842
|
||||
* @summary Package jurisdiction policy files as something other than JAR
|
||||
* @run main/othervm TestUnlimited use_default default
|
||||
* @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 limited limited
|
||||
* @run main/othervm TestUnlimited unlimited unlimited
|
||||
* @run main/othervm TestUnlimited unlimited/ unlimited
|
||||
* @run main/othervm TestUnlimited NosuchDir exception
|
||||
* @run main/othervm TestUnlimited . exception
|
||||
* @run main/othervm TestUnlimited /tmp/unlimited exception
|
||||
@ -40,9 +41,38 @@
|
||||
*/
|
||||
import javax.crypto.*;
|
||||
import java.security.Security;
|
||||
import java.nio.file.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class TestUnlimited {
|
||||
|
||||
private enum Result {
|
||||
UNLIMITED,
|
||||
LIMITED,
|
||||
EXCEPTION,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
/*
|
||||
* Grab the default policy entry from java.security.
|
||||
*
|
||||
* If the input java.security file is malformed
|
||||
* (missing crypto.policy, attribute/no value, etc), throw
|
||||
* exception. split() might throw AIOOB which
|
||||
* is ok behavior.
|
||||
*/
|
||||
private static String getDefaultPolicy() throws Exception {
|
||||
String javaHome = System.getProperty("java.home");
|
||||
Path path = Paths.get(javaHome, "conf", "security", "java.security");
|
||||
|
||||
try (Stream<String> lines = Files.lines(path)) {
|
||||
return lines.filter(x -> x.startsWith("crypto.policy="))
|
||||
.findFirst().orElseThrow(
|
||||
() -> new Exception("Missing crypto.policy"))
|
||||
.split("=")[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
* Override the Security property to allow for unlimited policy.
|
||||
@ -53,16 +83,37 @@ public class TestUnlimited {
|
||||
throw new Exception("Two args required");
|
||||
}
|
||||
|
||||
boolean expected = args[1].equals("pass");
|
||||
boolean exception = args[1].equals("exception");
|
||||
boolean result = false;
|
||||
String testStr = args[0];
|
||||
String expectedStr = args[1];
|
||||
if (testStr.equals("use_default")) {
|
||||
expectedStr = getDefaultPolicy();
|
||||
}
|
||||
|
||||
System.out.println("Testing: " + args[0]);
|
||||
Result expected = Result.UNKNOWN; // avoid NPE warnings
|
||||
Result result;
|
||||
|
||||
if (args[0].equals("\"\"")) {
|
||||
switch (expectedStr) {
|
||||
case "unlimited":
|
||||
expected = Result.UNLIMITED;
|
||||
break;
|
||||
case "limited":
|
||||
expected = Result.LIMITED;
|
||||
break;
|
||||
case "exception":
|
||||
expected = Result.EXCEPTION;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unexpected argument");
|
||||
}
|
||||
|
||||
System.out.println("Testing: " + testStr);
|
||||
if (testStr.equals("\"\"")) {
|
||||
Security.setProperty("crypto.policy", "");
|
||||
} else {
|
||||
Security.setProperty("crypto.policy", args[0]);
|
||||
// skip default case.
|
||||
if (!testStr.equals("use_default")) {
|
||||
Security.setProperty("crypto.policy", testStr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -74,21 +125,20 @@ public class TestUnlimited {
|
||||
System.out.println("max AES key len:" + maxKeyLen);
|
||||
if (maxKeyLen > 128) {
|
||||
System.out.println("Unlimited policy is active");
|
||||
result = true;
|
||||
result = Result.UNLIMITED;
|
||||
} else {
|
||||
System.out.println("Unlimited policy is NOT active");
|
||||
result = false;
|
||||
result = Result.LIMITED;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (!exception) {
|
||||
throw new Exception();
|
||||
}
|
||||
//ExceptionInInitializerError's
|
||||
result = Result.EXCEPTION;
|
||||
}
|
||||
|
||||
System.out.println(
|
||||
"Expected:\t" + expected + "\nResult:\t\t" + result);
|
||||
if (expected != result) {
|
||||
throw new Exception();
|
||||
if (!expected.equals(result)) {
|
||||
throw new Exception("Didn't match");
|
||||
}
|
||||
|
||||
System.out.println("DONE!");
|
||||
|
Loading…
x
Reference in New Issue
Block a user