Merge
This commit is contained in:
commit
7884ab9ccf
2
.hgtags
2
.hgtags
@ -452,3 +452,5 @@ e5357aa85dadacc6562175ff74714fecfb4470cf jdk-10+22
|
||||
8eb5e3ccee560c28ac9b1df2670adac2b3d36fad jdk-10+25
|
||||
1129253d3bc728a2963ba411ab9dd1adf358fb6b jdk-10+26
|
||||
b87d7b5d5dedc1185e5929470f945b7378cdb3ad jdk-10+27
|
||||
92f08900cb3c0d694e5c529a676c1c9e5909193f jdk-10+28
|
||||
a6e591e12f122768f675428e1e5a838fd0e9c7ec jdk-10+29
|
||||
|
@ -205,6 +205,8 @@ ifneq ($(filter product-bundles, $(MAKECMDGOALS)), )
|
||||
) \
|
||||
$(call CacheFind, $(SYMBOLS_IMAGE_DIR))
|
||||
|
||||
TEST_DEMOS_BUNDLE_FILES := $(filter $(JDK_IMAGE_HOMEDIR)/demo/%, $(ALL_JDK_FILES))
|
||||
|
||||
ALL_JRE_FILES := $(call CacheFind, $(JRE_IMAGE_DIR))
|
||||
|
||||
# Create special filter rules when dealing with unzipped .dSYM directories on
|
||||
@ -264,6 +266,17 @@ ifneq ($(filter product-bundles, $(MAKECMDGOALS)), )
|
||||
|
||||
PRODUCT_TARGETS += $(BUILD_JRE_SYMBOLS_BUNDLE)
|
||||
|
||||
# The demo bundle is only created to support client tests. Ideally it should
|
||||
# be built with the main test bundle, but since the prerequisites match
|
||||
# better with the product build, it makes more sense to keep it there for now.
|
||||
$(eval $(call SetupBundleFile, BUILD_TEST_DEMOS_BUNDLE, \
|
||||
BUNDLE_NAME := $(TEST_DEMOS_BUNDLE_NAME), \
|
||||
FILES := $(TEST_DEMOS_BUNDLE_FILES), \
|
||||
BASE_DIRS := $(JDK_IMAGE_DIR), \
|
||||
SUBDIR := $(JDK_BUNDLE_SUBDIR), \
|
||||
))
|
||||
|
||||
PRODUCT_TARGETS += $(BUILD_TEST_DEMOS_BUNDLE)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
104
make/Docs.gmk
104
make/Docs.gmk
@ -64,7 +64,7 @@ MODULES_SOURCE_PATH := $(call PathList, $(call GetModuleSrcPath) \
|
||||
JAVADOC_BASE_URL := http://www.oracle.com/pls/topic/lookup?ctx=javase9&id=homepage
|
||||
BUG_SUBMIT_URL := http://bugreport.java.com/bugreport/
|
||||
COPYRIGHT_URL := {@docroot}/../legal/copyright.html
|
||||
LICENSE_URL := http://www.oracle.com/technetwork/java/javase/terms/license/java9speclicense.html
|
||||
LICENSE_URL := http://www.oracle.com/technetwork/java/javase/terms/license/java10speclicense.html
|
||||
REDISTRIBUTION_URL := http://www.oracle.com/technetwork/java/redist-137594.html
|
||||
|
||||
# In order to get a specific ordering it's necessary to specify the total
|
||||
@ -97,13 +97,25 @@ JAVADOC_TAGS := \
|
||||
$(CUSTOM_JAVADOC_TAGS) \
|
||||
#
|
||||
|
||||
# The reference tags must stay stable to allow for comparisons across the
|
||||
# development cycle. If JAVADOC_TAGS needs to change, make sure that
|
||||
# REFERENCE_TAGS remains unchanged, by copying and hardcoding, if necessary.
|
||||
REFERENCE_TAGS := $(JAVADOC_TAGS)
|
||||
|
||||
# Which doclint checks to ignore
|
||||
JAVADOC_DISABLED_DOCLINT := accessibility html missing syntax reference
|
||||
|
||||
# The initial set of options for javadoc
|
||||
JAVADOC_OPTIONS := -use -keywords -notimestamp \
|
||||
-serialwarn -encoding ISO-8859-1 -docencoding UTF-8 -breakiterator \
|
||||
-splitIndex --system none -html5 -javafx --expand-requires transitive
|
||||
-splitIndex --system none -html5 -javafx --expand-requires transitive \
|
||||
--override-methods=summary
|
||||
|
||||
# The reference options must stay stable to allow for comparisons across the
|
||||
# development cycle.
|
||||
REFERENCE_OPTIONS := -XDignore.symbol.file=true -use -keywords -notimestamp \
|
||||
-serialwarn -encoding ISO-8859-1 -breakiterator -splitIndex --system none \
|
||||
-html5 -javafx --expand-requires transitive
|
||||
|
||||
# Should we add DRAFT stamps to the generated javadoc?
|
||||
ifeq ($(VERSION_IS_GA), true)
|
||||
@ -129,6 +141,11 @@ ifeq ($(IS_DRAFT), true)
|
||||
endif
|
||||
DRAFT_TEXT := This specification is not final and is subject to change. \
|
||||
Use is subject to <a href="$(LICENSE_URL)">license terms</a>.
|
||||
|
||||
# Workaround stylesheet bug
|
||||
HEADER_STYLE := style="margin-top: 9px;"
|
||||
else
|
||||
HEADER_STYLE := style="margin-top: 14px;"
|
||||
endif
|
||||
|
||||
JAVADOC_BOTTOM := \
|
||||
@ -147,12 +164,19 @@ JAVADOC_BOTTOM := \
|
||||
<a href="$(REDISTRIBUTION_URL)">documentation redistribution policy</a>. \
|
||||
$(DRAFT_MARKER_STR) <!-- Version $(VERSION_STRING) -->
|
||||
|
||||
|
||||
JAVADOC_TOP := \
|
||||
<div style="padding: 6px; text-align: center; font-size: 80%; \
|
||||
font-family: DejaVu Sans, Arial, Helvetica, sans-serif; \
|
||||
font-weight: normal;">$(DRAFT_TEXT)</div>
|
||||
|
||||
JDK_INDEX_CONTENT := \
|
||||
<!DOCTYPE html> \
|
||||
<html lang="en"> \
|
||||
<head> \
|
||||
<meta http-equiv="refresh" content="0;url=api/index.html"> \
|
||||
</head> \
|
||||
</html>
|
||||
|
||||
################################################################################
|
||||
# JDK javadoc titles/text snippets
|
||||
|
||||
@ -257,8 +281,14 @@ define SetupApiDocsGenerationBody
|
||||
$1_JAVA_ARGS += -DenableModuleGraph=true
|
||||
endif
|
||||
|
||||
# Always include tags and basic options
|
||||
$1_OPTIONS := $$(JAVADOC_TAGS) $$(JAVADOC_OPTIONS)
|
||||
# Start with basic options and tags
|
||||
ifeq ($$($1_OPTIONS), )
|
||||
$1_OPTIONS := $$(JAVADOC_OPTIONS)
|
||||
endif
|
||||
ifeq ($$($1_TAGS), )
|
||||
$1_TAGS := $$(JAVADOC_TAGS)
|
||||
endif
|
||||
$1_OPTIONS += $$($1_TAGS)
|
||||
|
||||
$1_OPTIONS += --module-source-path $$(MODULES_SOURCE_PATH)
|
||||
$1_OPTIONS += --module $$(call CommaList, $$($1_MODULES))
|
||||
@ -267,15 +297,10 @@ define SetupApiDocsGenerationBody
|
||||
$1_OPTIONS += -Xdoclint:all,$$(call CommaList, $$(addprefix -, \
|
||||
$$(JAVADOC_DISABLED_DOCLINT)))
|
||||
|
||||
$1_DOC_TITLE := $$($1_LONG_NAME)<br>Version $$(VERSION_SPECIFICATION) API Specification
|
||||
$1_WINDOW_TITLE := $$(subst &,&,$$($1_SHORT_NAME)) \
|
||||
$$(DRAFT_MARKER_TITLE)
|
||||
ifeq ($(VERSION_IS_GA), true) # Workaround stylesheet bug
|
||||
$1_HEADER_PAD := 14
|
||||
else
|
||||
$1_HEADER_PAD := 9
|
||||
endif
|
||||
$1_HEADER_TITLE := <div style="margin-top: $$($1_HEADER_PAD)px;"><strong>$$($1_SHORT_NAME)</strong> \
|
||||
$1_DOC_TITLE := $$($1_LONG_NAME)<br>Version $$(VERSION_SPECIFICATION) API \
|
||||
Specification
|
||||
$1_WINDOW_TITLE := $$(subst &,&,$$($1_SHORT_NAME)) $$(DRAFT_MARKER_TITLE)
|
||||
$1_HEADER_TITLE := <div $$(HEADER_STYLE)><strong>$$($1_SHORT_NAME)</strong> \
|
||||
$$(DRAFT_MARKER_STR)</div>
|
||||
|
||||
$1_OPTIONS += -doctitle '$$($1_DOC_TITLE)'
|
||||
@ -302,8 +327,13 @@ define SetupApiDocsGenerationBody
|
||||
$$(eval $1_OPTIONS += -group "$$($$g_GROUP_NAME)" "$$($$g_GROUP_MODULES)") \
|
||||
)
|
||||
|
||||
ifeq ($$($1_JAVADOC_CMD), )
|
||||
$1_JAVADOC_CMD := $$(JAVA) -Djava.awt.headless=true $$($1_JAVA_ARGS) \
|
||||
$$(NEW_JAVADOC)
|
||||
endif
|
||||
|
||||
$1_VARDEPS := $$($1_JAVA_ARGS) $$($1_OPTIONS) $$(MODULES_SOURCE_PATH) \
|
||||
$$($1_ALL_MODULES)
|
||||
$$($1_ALL_MODULES) $$($1_JAVADOC_CMD)
|
||||
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
|
||||
$$(SUPPORT_OUTPUTDIR)/docs/$1.vardeps)
|
||||
|
||||
@ -319,9 +349,8 @@ define SetupApiDocsGenerationBody
|
||||
$$(call LogInfo, Javadoc modules: $$($1_ALL_MODULES))
|
||||
$$(call MakeDir, $$($1_TARGET_DIR))
|
||||
$$(call ExecuteWithLog, $$(SUPPORT_OUTPUTDIR)/docs/$1, \
|
||||
$$(JAVA) -Djava.awt.headless=true $$($1_JAVA_ARGS) \
|
||||
$$(NEW_JAVADOC) -d $$($1_TARGET_DIR) \
|
||||
$$(JAVADOC_TAGS) $$($1_OPTIONS) $$($1_LOG_OPTION))
|
||||
$$($1_JAVADOC_CMD) -d $$($1_TARGET_DIR) \
|
||||
$$($1_OPTIONS) $$($1_LOG_OPTION))
|
||||
|
||||
$1_JAVADOC_TARGETS := $$($1_TARGET_DIR)/index.html
|
||||
|
||||
@ -430,19 +459,30 @@ $(eval $(call SetupApiDocsGeneration, JAVASE_API, \
|
||||
# Targets generated are returned in JAVASE_API_JAVADOC_TARGETS and
|
||||
# JAVASE_API_MODULEGRAPH_TARGETS.
|
||||
|
||||
################################################################################
|
||||
# Setup generation of the reference Java SE API documentation (javadoc + modulegraph)
|
||||
|
||||
# The reference javadoc is just the same as javase, but using the BootJDK javadoc
|
||||
# and a stable set of javadoc options.
|
||||
|
||||
$(eval $(call SetupApiDocsGeneration, REFERENCE_API, \
|
||||
MODULES := $(JAVASE_MODULES), \
|
||||
SHORT_NAME := $(JAVASE_SHORT_NAME), \
|
||||
LONG_NAME := $(JAVASE_LONG_NAME), \
|
||||
TARGET_DIR := $(IMAGES_OUTPUTDIR)/reference-docs/api, \
|
||||
JAVADOC_CMD := $(JAVADOC), \
|
||||
OPTIONS := $(REFERENCE_OPTIONS), \
|
||||
TAGS := $(REFERENCE_TAGS), \
|
||||
))
|
||||
|
||||
# Targets generated are returned in REFERENCE_API_JAVADOC_TARGETS and
|
||||
# REFERENCE_API_MODULEGRAPH_TARGETS.
|
||||
|
||||
################################################################################
|
||||
|
||||
JDK_INDEX_HTML := $(DOCS_OUTPUTDIR)/index.html
|
||||
|
||||
JDK_INDEX_CONTENT := \
|
||||
<!DOCTYPE html> \
|
||||
<html lang="en"> \
|
||||
<head> \
|
||||
<meta http-equiv="refresh" content="0;url=api/index.html"> \
|
||||
</head> \
|
||||
</html>
|
||||
|
||||
$(JDK_INDEX_HTML):
|
||||
$(JDK_INDEX_HTML):
|
||||
$(ECHO) '$(JDK_INDEX_CONTENT)' > $@
|
||||
|
||||
JDK_INDEX_TARGETS += $(JDK_INDEX_HTML)
|
||||
@ -553,6 +593,10 @@ docs-javase-api-javadoc: $(JAVASE_API_JAVADOC_TARGETS) $(JAVASE_API_CUSTOM_TARGE
|
||||
|
||||
docs-javase-api-modulegraph: $(JAVASE_API_MODULEGRAPH_TARGETS)
|
||||
|
||||
docs-reference-api-javadoc: $(REFERENCE_API_JAVADOC_TARGETS) $(REFERENCE_API_CUSTOM_TARGETS)
|
||||
|
||||
docs-reference-api-modulegraph: $(REFERENCE_API_MODULEGRAPH_TARGETS)
|
||||
|
||||
docs-jdk-specs: $(JDK_SPECS_TARGETS)
|
||||
|
||||
docs-jdk-index: $(JDK_INDEX_TARGETS)
|
||||
@ -560,8 +604,10 @@ docs-jdk-index: $(JDK_INDEX_TARGETS)
|
||||
docs-zip: $(ZIP_TARGETS)
|
||||
|
||||
all: docs-jdk-api-javadoc docs-jdk-api-modulegraph docs-javase-api-javadoc \
|
||||
docs-javase-api-modulegraph docs-jdk-specs docs-jdk-index docs-zip
|
||||
docs-javase-api-modulegraph docs-reference-api-javadoc \
|
||||
docs-reference-api-modulegraph docs-jdk-specs docs-jdk-index docs-zip
|
||||
|
||||
.PHONY: default all docs-jdk-api-javadoc docs-jdk-api-modulegraph \
|
||||
docs-javase-api-javadoc docs-javase-api-modulegraph docs-jdk-specs \
|
||||
docs-javase-api-javadoc docs-javase-api-modulegraph \
|
||||
docs-reference-api-javadoc docs-reference-api-modulegraph docs-jdk-specs \
|
||||
docs-jdk-index docs-zip
|
||||
|
@ -432,8 +432,8 @@ $(eval $(call IncludeCustomExtension, Images-post.gmk))
|
||||
$(JRE_TARGETS): $(TOOL_JRE_TARGETS)
|
||||
$(JDK_TARGETS): $(TOOL_JDK_TARGETS)
|
||||
|
||||
jdk: $(JDK_TARGETS)
|
||||
jre: $(JRE_TARGETS)
|
||||
jdk: $(TOOL_JDK_TARGETS) $(JDK_TARGETS)
|
||||
jre: $(TOOL_JRE_TARGETS) $(JRE_TARGETS)
|
||||
symbols: $(SYMBOLS_TARGETS)
|
||||
|
||||
all: jdk jre symbols
|
||||
|
@ -223,9 +223,6 @@ else # HAS_SPEC=true
|
||||
# Our helper functions.
|
||||
include $(TOPDIR)/make/InitSupport.gmk
|
||||
|
||||
# Verify that the spec file we included seems okay.
|
||||
$(eval $(call CheckSpecSanity))
|
||||
|
||||
# Parse COMPARE_BUILD (for makefile development)
|
||||
$(eval $(call ParseCompareBuild))
|
||||
|
||||
|
@ -359,23 +359,6 @@ else # $(HAS_SPEC)=true
|
||||
|
||||
BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
|
||||
|
||||
# Sanity check the spec file, so it matches this source code
|
||||
define CheckSpecSanity
|
||||
ifneq ($$(ACTUAL_TOPDIR), $$(TOPDIR))
|
||||
ifneq ($$(ACTUAL_TOPDIR), $$(ORIGINAL_TOPDIR))
|
||||
ifneq ($$(ACTUAL_TOPDIR), $$(CANONICAL_TOPDIR))
|
||||
$$(info Error: SPEC mismatch! Current working directory)
|
||||
$$(info $$(ACTUAL_TOPDIR))
|
||||
$$(info does not match either TOPDIR, ORIGINAL_TOPDIR or CANONICAL_TOPDIR)
|
||||
$$(info $$(TOPDIR))
|
||||
$$(info $$(ORIGINAL_TOPDIR))
|
||||
$$(info $$(CANONICAL_TOPDIR))
|
||||
$$(error Cannot continue)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
# Parse COMPARE_BUILD into COMPARE_BUILD_*
|
||||
# Syntax: COMPARE_BUILD=CONF=<configure options>:PATCH=<patch file>:
|
||||
# MAKE=<make targets>:COMP_OPTS=<compare script options>:
|
||||
|
@ -382,6 +382,12 @@ docs-javase-api-javadoc:
|
||||
docs-javase-api-modulegraph:
|
||||
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-javase-api-modulegraph)
|
||||
|
||||
docs-reference-api-javadoc:
|
||||
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-reference-api-javadoc)
|
||||
|
||||
docs-reference-api-modulegraph:
|
||||
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-reference-api-modulegraph)
|
||||
|
||||
docs-jdk-specs:
|
||||
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Docs.gmk docs-jdk-specs)
|
||||
|
||||
@ -395,7 +401,8 @@ update-build-docs:
|
||||
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f UpdateBuildDocs.gmk)
|
||||
|
||||
ALL_TARGETS += docs-jdk-api-javadoc docs-jdk-api-modulegraph \
|
||||
docs-javase-api-javadoc docs-javase-api-modulegraph docs-jdk-specs \
|
||||
docs-javase-api-javadoc docs-javase-api-modulegraph \
|
||||
docs-reference-api-javadoc docs-reference-api-modulegraph docs-jdk-specs \
|
||||
docs-jdk-index docs-zip update-build-docs
|
||||
|
||||
################################################################################
|
||||
@ -810,10 +817,14 @@ else
|
||||
|
||||
docs-javase-api-javadoc: $(GENSRC_TARGETS) rmic
|
||||
|
||||
docs-reference-api-javadoc: $(GENSRC_TARGETS) rmic
|
||||
|
||||
docs-jdk-api-modulegraph: exploded-image buildtools-modules
|
||||
|
||||
docs-javase-api-modulegraph: exploded-image buildtools-modules
|
||||
|
||||
docs-reference-api-modulegraph: exploded-image buildtools-modules
|
||||
|
||||
# The gensrc steps for hotspot and jdk.jdi create html spec files.
|
||||
docs-jdk-specs: hotspot-$(JVM_VARIANT_MAIN)-gensrc jdk.jdi-gensrc \
|
||||
docs-jdk-index
|
||||
@ -943,16 +954,19 @@ create-buildjdk: create-buildjdk-copy create-buildjdk-interim-image
|
||||
|
||||
docs-jdk-api: docs-jdk-api-javadoc
|
||||
docs-javase-api: docs-javase-api-javadoc
|
||||
docs-reference-api: docs-reference-api-javadoc
|
||||
|
||||
# If we're building full docs, we must also generate the module graphs to
|
||||
# get non-broken api documentation.
|
||||
ifeq ($(ENABLE_FULL_DOCS), true)
|
||||
docs-jdk-api: docs-jdk-api-modulegraph
|
||||
docs-javase-api: docs-javase-api-modulegraph
|
||||
docs-reference-api: docs-reference-api-modulegraph
|
||||
endif
|
||||
|
||||
docs-jdk: docs-jdk-api docs-jdk-specs docs-jdk-index
|
||||
docs-javase: docs-javase-api
|
||||
docs-reference: docs-reference-api
|
||||
|
||||
# alias for backwards compatibility
|
||||
docs-javadoc: docs-jdk-api
|
||||
@ -1005,8 +1019,8 @@ ALL_TARGETS += buildtools hotspot hotspot-libs hotspot-gensrc gensrc gendata \
|
||||
copy java rmic libs launchers jmods \
|
||||
jdk.jdwp.agent-gensrc $(ALL_MODULES) demos \
|
||||
exploded-image-base exploded-image \
|
||||
create-buildjdk docs-jdk-api docs-javase-api docs-jdk docs-javase \
|
||||
docs-javadoc mac-bundles product-images \
|
||||
create-buildjdk docs-jdk-api docs-javase-api docs-reference-api docs-jdk \
|
||||
docs-javase docs-reference docs-javadoc mac-bundles product-images \
|
||||
profiles profiles-images \
|
||||
docs-image test-image all-images \
|
||||
all-bundles
|
||||
|
@ -561,19 +561,10 @@ AC_DEFUN_ONCE([BASIC_SETUP_PATHS],
|
||||
AC_MSG_RESULT([$TOPDIR])
|
||||
AC_SUBST(TOPDIR)
|
||||
|
||||
# Save the original version of TOPDIR for string comparisons
|
||||
ORIGINAL_TOPDIR="$TOPDIR"
|
||||
AC_SUBST(ORIGINAL_TOPDIR)
|
||||
|
||||
# We can only call BASIC_FIXUP_PATH after BASIC_CHECK_PATHS_WINDOWS.
|
||||
BASIC_FIXUP_PATH(CURDIR)
|
||||
BASIC_FIXUP_PATH(TOPDIR)
|
||||
|
||||
# Calculate a canonical version of TOPDIR for string comparisons
|
||||
CANONICAL_TOPDIR=$TOPDIR
|
||||
BASIC_REMOVE_SYMBOLIC_LINKS([CANONICAL_TOPDIR])
|
||||
AC_SUBST(CANONICAL_TOPDIR)
|
||||
|
||||
# Locate the directory of this script.
|
||||
AUTOCONF_DIR=$TOPDIR/make/autoconf
|
||||
|
||||
|
@ -296,6 +296,7 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVA, java)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAC, javac)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAH, javah)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVADOC, javadoc)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAR, jar)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JARSIGNER, jarsigner)
|
||||
|
||||
|
@ -881,6 +881,7 @@ JAVAC_FLAGS
|
||||
BOOT_JDK_SOURCETARGET
|
||||
JARSIGNER
|
||||
JAR
|
||||
JAVADOC
|
||||
JAVAH
|
||||
JAVAC
|
||||
JAVA
|
||||
@ -964,8 +965,6 @@ DEBUG_LEVEL
|
||||
HOTSPOT_DEBUG_LEVEL
|
||||
JDK_VARIANT
|
||||
USERNAME
|
||||
CANONICAL_TOPDIR
|
||||
ORIGINAL_TOPDIR
|
||||
TOPDIR
|
||||
PATH_SEP
|
||||
HOTSPOT_BUILD_CPU_DEFINE
|
||||
@ -1294,6 +1293,7 @@ PKG_CONFIG
|
||||
JAVA
|
||||
JAVAC
|
||||
JAVAH
|
||||
JAVADOC
|
||||
JAR
|
||||
JARSIGNER
|
||||
CC
|
||||
@ -2237,6 +2237,7 @@ Some influential environment variables:
|
||||
JAVA Override default value for JAVA
|
||||
JAVAC Override default value for JAVAC
|
||||
JAVAH Override default value for JAVAH
|
||||
JAVADOC Override default value for JAVADOC
|
||||
JAR Override default value for JAR
|
||||
JARSIGNER Override default value for JARSIGNER
|
||||
CC C compiler command
|
||||
@ -5114,7 +5115,7 @@ VS_SDK_PLATFORM_NAME_2013=
|
||||
#CUSTOM_AUTOCONF_INCLUDE
|
||||
|
||||
# Do not change or remove the following line, it is needed for consistency checks:
|
||||
DATE_WHEN_GENERATED=1508497666
|
||||
DATE_WHEN_GENERATED=1509013542
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -16533,10 +16534,6 @@ $as_echo_n "checking for top-level directory... " >&6; }
|
||||
$as_echo "$TOPDIR" >&6; }
|
||||
|
||||
|
||||
# Save the original version of TOPDIR for string comparisons
|
||||
ORIGINAL_TOPDIR="$TOPDIR"
|
||||
|
||||
|
||||
# We can only call BASIC_FIXUP_PATH after BASIC_CHECK_PATHS_WINDOWS.
|
||||
|
||||
# Only process if variable expands to non-empty
|
||||
@ -16803,58 +16800,6 @@ $as_echo "$as_me: The path of TOPDIR, which resolves as \"$path\", is invalid."
|
||||
fi
|
||||
|
||||
|
||||
# Calculate a canonical version of TOPDIR for string comparisons
|
||||
CANONICAL_TOPDIR=$TOPDIR
|
||||
|
||||
if test "x$OPENJDK_BUILD_OS" != xwindows; then
|
||||
# Follow a chain of symbolic links. Use readlink
|
||||
# where it exists, else fall back to horribly
|
||||
# complicated shell code.
|
||||
if test "x$READLINK_TESTED" != yes; then
|
||||
# On MacOSX there is a readlink tool with a different
|
||||
# purpose than the GNU readlink tool. Check the found readlink.
|
||||
ISGNU=`$READLINK --version 2>&1 | $GREP GNU`
|
||||
if test "x$ISGNU" = x; then
|
||||
# A readlink that we do not know how to use.
|
||||
# Are there other non-GNU readlinks out there?
|
||||
READLINK_TESTED=yes
|
||||
READLINK=
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$READLINK" != x; then
|
||||
CANONICAL_TOPDIR=`$READLINK -f $CANONICAL_TOPDIR`
|
||||
else
|
||||
# Save the current directory for restoring afterwards
|
||||
STARTDIR=$PWD
|
||||
COUNTER=0
|
||||
sym_link_dir=`$DIRNAME $CANONICAL_TOPDIR`
|
||||
sym_link_file=`$BASENAME $CANONICAL_TOPDIR`
|
||||
cd $sym_link_dir
|
||||
# Use -P flag to resolve symlinks in directories.
|
||||
cd `$THEPWDCMD -P`
|
||||
sym_link_dir=`$THEPWDCMD -P`
|
||||
# Resolve file symlinks
|
||||
while test $COUNTER -lt 20; do
|
||||
ISLINK=`$LS -l $sym_link_dir/$sym_link_file | $GREP '\->' | $SED -e 's/.*-> \(.*\)/\1/'`
|
||||
if test "x$ISLINK" == x; then
|
||||
# This is not a symbolic link! We are done!
|
||||
break
|
||||
fi
|
||||
# Again resolve directory symlinks since the target of the just found
|
||||
# link could be in a different directory
|
||||
cd `$DIRNAME $ISLINK`
|
||||
sym_link_dir=`$THEPWDCMD -P`
|
||||
sym_link_file=`$BASENAME $ISLINK`
|
||||
let COUNTER=COUNTER+1
|
||||
done
|
||||
cd $STARTDIR
|
||||
CANONICAL_TOPDIR=$sym_link_dir/$sym_link_file
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Locate the directory of this script.
|
||||
AUTOCONF_DIR=$TOPDIR/make/autoconf
|
||||
|
||||
@ -31169,6 +31114,144 @@ $as_echo "$tool_specified" >&6; }
|
||||
|
||||
|
||||
|
||||
# Use user overridden value if available, otherwise locate tool in the Boot JDK.
|
||||
|
||||
# Publish this variable in the help.
|
||||
|
||||
|
||||
if [ -z "${JAVADOC+x}" ]; then
|
||||
# The variable is not set by user, try to locate tool using the code snippet
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for javadoc in Boot JDK" >&5
|
||||
$as_echo_n "checking for javadoc in Boot JDK... " >&6; }
|
||||
JAVADOC=$BOOT_JDK/bin/javadoc
|
||||
if test ! -x $JAVADOC; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
$as_echo "not found" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&5
|
||||
$as_echo "$as_me: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&6;}
|
||||
as_fn_error $? "Could not find javadoc in the Boot JDK" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
|
||||
$as_echo "ok" >&6; }
|
||||
|
||||
|
||||
else
|
||||
# The variable is set, but is it from the command line or the environment?
|
||||
|
||||
# Try to remove the string !JAVADOC! from our list.
|
||||
try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!JAVADOC!/}
|
||||
if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
|
||||
# If it failed, the variable was not from the command line. Ignore it,
|
||||
# but warn the user (except for BASH, which is always set by the calling BASH).
|
||||
if test "xJAVADOC" != xBASH; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of JAVADOC from the environment. Use command line variables instead." >&5
|
||||
$as_echo "$as_me: WARNING: Ignoring value of JAVADOC from the environment. Use command line variables instead." >&2;}
|
||||
fi
|
||||
# Try to locate tool using the code snippet
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for javadoc in Boot JDK" >&5
|
||||
$as_echo_n "checking for javadoc in Boot JDK... " >&6; }
|
||||
JAVADOC=$BOOT_JDK/bin/javadoc
|
||||
if test ! -x $JAVADOC; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
$as_echo "not found" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&5
|
||||
$as_echo "$as_me: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&6;}
|
||||
as_fn_error $? "Could not find javadoc in the Boot JDK" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
|
||||
$as_echo "ok" >&6; }
|
||||
|
||||
|
||||
else
|
||||
# If it succeeded, then it was overridden by the user. We will use it
|
||||
# for the tool.
|
||||
|
||||
# First remove it from the list of overridden variables, so we can test
|
||||
# for unknown variables in the end.
|
||||
CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
|
||||
|
||||
# Check if we try to supply an empty value
|
||||
if test "x$JAVADOC" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool JAVADOC= (no value)" >&5
|
||||
$as_echo "$as_me: Setting user supplied tool JAVADOC= (no value)" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JAVADOC" >&5
|
||||
$as_echo_n "checking for JAVADOC... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
|
||||
$as_echo "disabled" >&6; }
|
||||
else
|
||||
# Check if the provided tool contains a complete path.
|
||||
tool_specified="$JAVADOC"
|
||||
tool_basename="${tool_specified##*/}"
|
||||
if test "x$tool_basename" = "x$tool_specified"; then
|
||||
# A command without a complete path is provided, search $PATH.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool JAVADOC=$tool_basename" >&5
|
||||
$as_echo "$as_me: Will search for user supplied tool JAVADOC=$tool_basename" >&6;}
|
||||
# Extract the first word of "$tool_basename", so it can be a program name with args.
|
||||
set dummy $tool_basename; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_JAVADOC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $JAVADOC in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_JAVADOC="$JAVADOC" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_JAVADOC="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
JAVADOC=$ac_cv_path_JAVADOC
|
||||
if test -n "$JAVADOC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVADOC" >&5
|
||||
$as_echo "$JAVADOC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x$JAVADOC" = x; then
|
||||
as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
|
||||
fi
|
||||
else
|
||||
# Otherwise we believe it is a complete path. Use it as it is.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool JAVADOC=$tool_specified" >&5
|
||||
$as_echo "$as_me: Will use user supplied tool JAVADOC=$tool_specified" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JAVADOC" >&5
|
||||
$as_echo_n "checking for JAVADOC... " >&6; }
|
||||
if test ! -x "$tool_specified"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
$as_echo "not found" >&6; }
|
||||
as_fn_error $? "User supplied tool JAVADOC=$tool_specified does not exist or is not executable" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
|
||||
$as_echo "$tool_specified" >&6; }
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Use user overridden value if available, otherwise locate tool in the Boot JDK.
|
||||
|
||||
# Publish this variable in the help.
|
||||
|
@ -127,9 +127,6 @@ SYSROOT_LDFLAGS := @SYSROOT_LDFLAGS@
|
||||
|
||||
# The top-level directory of the source repository
|
||||
TOPDIR:=@TOPDIR@
|
||||
# These two versions of TOPDIR are used in string comparisons
|
||||
ORIGINAL_TOPDIR:=@ORIGINAL_TOPDIR@
|
||||
CANONICAL_TOPDIR:=@CANONICAL_TOPDIR@
|
||||
|
||||
|
||||
IMPORT_MODULES_CLASSES:=@IMPORT_MODULES_CLASSES@
|
||||
@ -526,6 +523,7 @@ SJAVAC_SERVER_JAVA_FLAGS:=@SJAVAC_SERVER_JAVA_FLAGS@
|
||||
JAVA_CMD:=@JAVA@
|
||||
JAVAC_CMD:=@JAVAC@
|
||||
JAVAH_CMD:=@JAVAH@
|
||||
JAVADOC_CMD:=@JAVADOC@
|
||||
JAR_CMD:=@JAR@
|
||||
JLINK_CMD := @JLINK@
|
||||
JMOD_CMD := @JMOD@
|
||||
@ -538,6 +536,7 @@ JAVA_SMALL=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
|
||||
JAVA_JAVAC=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_JAVAC) $(JAVA_FLAGS)
|
||||
JAVAC=@FIXPATH@ $(JAVAC_CMD)
|
||||
JAVAH=@FIXPATH@ $(JAVAH_CMD)
|
||||
JAVADOC=@FIXPATH@ $(JAVADOC_CMD)
|
||||
JAR=@FIXPATH@ $(JAR_CMD)
|
||||
JLINK = @FIXPATH@ $(JLINK_CMD) $(JAVA_TOOL_FLAGS_SMALL)
|
||||
JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
|
||||
@ -823,6 +822,7 @@ JRE_COMPACT3_BUNDLE_NAME := \
|
||||
jre-$(VERSION_SHORT)+$(VERSION_BUILD)-compact3_$(OPENJDK_TARGET_BUNDLE_PLATFORM)_bin$(DEBUG_PART).tar.gz
|
||||
JDK_SYMBOLS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
|
||||
JRE_SYMBOLS_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
|
||||
TEST_DEMOS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests-demos$(DEBUG_PART).tar.gz
|
||||
TEST_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests$(DEBUG_PART).tar.gz
|
||||
DOCS_BUNDLE_NAME := jdk-$(BASE_NAME)_doc-api-spec$(DEBUG_PART).tar.gz
|
||||
|
||||
@ -830,6 +830,7 @@ JDK_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_BUNDLE_NAME)
|
||||
JRE_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JRE_BUNDLE_NAME)
|
||||
JDK_SYMBOLS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_SYMBOLS_BUNDLE_NAME)
|
||||
JRE_SYMBOLS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JRE_SYMBOLS_BUNDLE_NAME)
|
||||
TEST_DEMOS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(TEST_DEMOS_BUNDLE_NAME)
|
||||
TEST_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(TEST_BUNDLE_NAME)
|
||||
DOCS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(DOCS_BUNDLE_NAME)
|
||||
|
||||
|
@ -737,6 +737,7 @@ define AddFileToCopy
|
||||
$$($$(strip $4))
|
||||
|
||||
$3 += $2
|
||||
$3_SOURCES += $1
|
||||
endef
|
||||
|
||||
# Returns the value of the first argument
|
||||
@ -749,6 +750,8 @@ identity = \
|
||||
# Parameter 1 is the name of the rule. This name is used as variable prefix,
|
||||
# and the targets generated are listed in a variable by that name.
|
||||
#
|
||||
# The list of all source files is returned in $1_SOURCES.
|
||||
#
|
||||
# Remaining parameters are named arguments. These include:
|
||||
# SRC : Source root dir (defaults to dir of first file)
|
||||
# DEST : Dest root dir
|
||||
|
@ -251,10 +251,10 @@ SPEC_SUBDIRS += share/specs
|
||||
# configuration.
|
||||
# Param 1 - Module to find for, set to * for finding all
|
||||
FindAllModuleInfos = \
|
||||
$(wildcard \
|
||||
$(sort $(wildcard \
|
||||
$(foreach sub, $(SRC_SUBDIRS), \
|
||||
$(patsubst %,%/$(strip $1)/$(sub)/module-info.java, $(TOP_SRC_DIRS))) \
|
||||
$(patsubst %,%/$(strip $1)/module-info.java, $(IMPORT_MODULES_SRC)))
|
||||
$(patsubst %,%/$(strip $1)/module-info.java, $(IMPORT_MODULES_SRC))))
|
||||
|
||||
# Find module-info.java files in the specific source dir
|
||||
# Param 1 - Src dir to find module-info.java files in
|
||||
|
@ -300,6 +300,14 @@ var getJibProfilesCommon = function (input, data) {
|
||||
],
|
||||
exploded: "images/test"
|
||||
},
|
||||
test_demos: {
|
||||
local: "bundles/\\(jdk.*bin-tests-demos.tar.gz\\)",
|
||||
remote: [
|
||||
"bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-tests-demos.tar.gz",
|
||||
"bundles/" + pf + "/\\1"
|
||||
],
|
||||
exploded: "images/test"
|
||||
},
|
||||
jdk_symbols: {
|
||||
local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)",
|
||||
remote: [
|
||||
@ -998,7 +1006,7 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||
var getJibProfilesDependencies = function (input, common) {
|
||||
|
||||
var devkit_platform_revisions = {
|
||||
linux_x64: "gcc4.9.2-OEL6.4+1.1",
|
||||
linux_x64: "gcc4.9.2-OEL6.4+1.2",
|
||||
macosx_x64: "Xcode6.3-MacOSX10.9+1.0",
|
||||
solaris_x64: "SS12u4-Solaris11u1+1.0",
|
||||
solaris_sparcv9: "SS12u4-Solaris11u1+1.0",
|
||||
|
@ -84,7 +84,8 @@ RPM_LIST := \
|
||||
libXau libXau-devel \
|
||||
libgcc \
|
||||
zlib zlib-devel \
|
||||
libffi libffi-devel
|
||||
libffi libffi-devel \
|
||||
fontconfig fontconfig-devel
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
RPM_DIR ?= $(RPM_DIR_x86_64)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2017, 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
|
||||
@ -63,7 +63,7 @@ endif
|
||||
define generate-preproc-src
|
||||
$(call MakeDir, $(@D))
|
||||
( $(NAWK) '/@@END_COPYRIGHT@@/{exit}1' $< && \
|
||||
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $< \
|
||||
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $< \
|
||||
2> >($(GREP) -v '^$(<F)$$' >&2) \
|
||||
| $(NAWK) '/@@START_HERE@@/,0' \
|
||||
| $(SED) -e 's/@@START_HERE@@/\/\/ AUTOMATICALLY GENERATED FILE - DO NOT EDIT/' \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2017, 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
|
||||
@ -36,6 +36,7 @@ import java.util.*;
|
||||
import java.util.ResourceBundle.Control;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
@ -217,6 +218,7 @@ public class CLDRConverter {
|
||||
|
||||
List<Bundle> bundles = readBundleList();
|
||||
convertBundles(bundles);
|
||||
convertBundles(addedBundles);
|
||||
}
|
||||
|
||||
private static void usage() {
|
||||
@ -293,14 +295,7 @@ public class CLDRConverter {
|
||||
if (fileName.endsWith(".xml")) {
|
||||
String id = fileName.substring(0, fileName.indexOf('.'));
|
||||
Locale cldrLoc = Locale.forLanguageTag(toLanguageTag(id));
|
||||
List<Locale> candList = applyParentLocales("", defCon.getCandidateLocales("", cldrLoc));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Locale loc : candList) {
|
||||
if (!loc.equals(Locale.ROOT)) {
|
||||
sb.append(toLocaleName(loc.toLanguageTag()));
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
StringBuilder sb = getCandLocales(cldrLoc);
|
||||
if (sb.indexOf("root") == -1) {
|
||||
sb.append("root");
|
||||
}
|
||||
@ -319,6 +314,23 @@ public class CLDRConverter {
|
||||
}
|
||||
|
||||
private static final Map<String, Map<String, Object>> cldrBundles = new HashMap<>();
|
||||
// this list will contain additional bundles to be generated for Region dependent Data.
|
||||
private static List<Bundle> addedBundles = new ArrayList<>();
|
||||
|
||||
private static Map<String, SortedSet<String>> metaInfo = new HashMap<>();
|
||||
|
||||
static {
|
||||
// For generating information on supported locales.
|
||||
metaInfo.put("LocaleNames", new TreeSet<>());
|
||||
metaInfo.put("CurrencyNames", new TreeSet<>());
|
||||
metaInfo.put("TimeZoneNames", new TreeSet<>());
|
||||
metaInfo.put("CalendarData", new TreeSet<>());
|
||||
metaInfo.put("FormatData", new TreeSet<>());
|
||||
metaInfo.put("AvailableLocales", new TreeSet<>());
|
||||
}
|
||||
|
||||
|
||||
private static Set<String> calendarDataFields = Set.of("firstDayOfWeek", "minimalDaysInFirstWeek");
|
||||
|
||||
static Map<String, Object> getCLDRBundle(String id) throws Exception {
|
||||
Map<String, Object> bundle = cldrBundles.get(id);
|
||||
@ -411,16 +423,85 @@ public class CLDRConverter {
|
||||
parserLikelySubtags.parse(fileLikelySubtags, handlerLikelySubtags);
|
||||
}
|
||||
|
||||
private static void convertBundles(List<Bundle> bundles) throws Exception {
|
||||
// For generating information on supported locales.
|
||||
Map<String, SortedSet<String>> metaInfo = new HashMap<>();
|
||||
metaInfo.put("LocaleNames", new TreeSet<>());
|
||||
metaInfo.put("CurrencyNames", new TreeSet<>());
|
||||
metaInfo.put("TimeZoneNames", new TreeSet<>());
|
||||
metaInfo.put("CalendarData", new TreeSet<>());
|
||||
metaInfo.put("FormatData", new TreeSet<>());
|
||||
metaInfo.put("AvailableLocales", new TreeSet<>());
|
||||
/**
|
||||
* This method will check if a new region dependent Bundle needs to be
|
||||
* generated for this Locale id and targetMap. New Bundle will be generated
|
||||
* when Locale id has non empty script and country code and targetMap
|
||||
* contains region dependent data. This method will also remove region
|
||||
* dependent data from this targetMap after candidate locales check. E.g. It
|
||||
* will call genRegionDependentBundle() in case of az_Latn_AZ locale and
|
||||
* remove region dependent data from this targetMap so that az_Latn_AZ
|
||||
* bundle will not be created. For az_Cyrl_AZ, new Bundle will be generated
|
||||
* but region dependent data will not be removed from targetMap as its candidate
|
||||
* locales are [az_Cyrl_AZ, az_Cyrl, root], which does not include az_AZ for
|
||||
* fallback.
|
||||
*
|
||||
*/
|
||||
|
||||
private static void checkRegionDependentBundle(Map<String, Object> targetMap, String id) {
|
||||
if ((CLDRConverter.getScript(id) != "")
|
||||
&& (CLDRConverter.getCountryCode(id) != "")) {
|
||||
Map<String, Object> regionDepDataMap = targetMap
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(calendarDataFields::contains)
|
||||
.collect(Collectors.toMap(k -> k, targetMap::get));
|
||||
if (!regionDepDataMap.isEmpty()) {
|
||||
Locale cldrLoc = new Locale(CLDRConverter.getLanguageCode(id),
|
||||
CLDRConverter.getCountryCode(id));
|
||||
genRegionDependentBundle(regionDepDataMap, cldrLoc);
|
||||
if (checkCandidateLocales(id, cldrLoc)) {
|
||||
// Remove matchedKeys from this targetMap only if checkCandidateLocales() returns true.
|
||||
regionDepDataMap.keySet().forEach(targetMap::remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This method will generate a new Bundle for region dependent data,
|
||||
* minimalDaysInFirstWeek and firstDayOfWeek. Newly generated Bundle will be added
|
||||
* to addedBundles list.
|
||||
*/
|
||||
private static void genRegionDependentBundle(Map<String, Object> targetMap, Locale cldrLoc) {
|
||||
String localeId = cldrLoc.toString();
|
||||
StringBuilder sb = getCandLocales(cldrLoc);
|
||||
if (sb.indexOf(localeId) == -1) {
|
||||
sb.append(localeId);
|
||||
}
|
||||
Bundle bundle = new Bundle(localeId, sb.toString(), null, null);
|
||||
cldrBundles.put(localeId, targetMap);
|
||||
addedBundles.add(bundle);
|
||||
}
|
||||
|
||||
private static StringBuilder getCandLocales(Locale cldrLoc) {
|
||||
List<Locale> candList = getCandidateLocales(cldrLoc);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Locale loc : candList) {
|
||||
if (!loc.equals(Locale.ROOT)) {
|
||||
sb.append(toLocaleName(loc.toLanguageTag()));
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static List<Locale> getCandidateLocales(Locale cldrLoc) {
|
||||
List<Locale> candList = new ArrayList<>();
|
||||
candList = applyParentLocales("", defCon.getCandidateLocales("", cldrLoc));
|
||||
return candList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return true, if for a given locale, its language and
|
||||
* country specific locale will exist in runtime lookup path. E.g. it will
|
||||
* return true for bs_Latn_BA.
|
||||
*/
|
||||
private static boolean checkCandidateLocales(String id, Locale cldrLoc) {
|
||||
return(getCandidateLocales(Locale.forLanguageTag(id.replaceAll("_", "-")))
|
||||
.contains(cldrLoc));
|
||||
}
|
||||
|
||||
private static void convertBundles(List<Bundle> bundles) throws Exception {
|
||||
// parent locales map. The mappings are put in base metaInfo file
|
||||
// for now.
|
||||
if (isBaseModule) {
|
||||
@ -433,6 +514,8 @@ public class CLDRConverter {
|
||||
|
||||
Map<String, Object> targetMap = bundle.getTargetMap();
|
||||
|
||||
// check if new region DependentBundle needs to be generated for this Locale.
|
||||
checkRegionDependentBundle(targetMap, bundle.getID());
|
||||
EnumSet<Bundle.Type> bundleTypes = bundle.getBundleTypes();
|
||||
|
||||
if (bundle.isRoot()) {
|
||||
@ -573,6 +656,14 @@ public class CLDRConverter {
|
||||
return Locale.forLanguageTag(id.replaceAll("_", "-")).getCountry();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the script portion of the given id.
|
||||
* If id is "root", "" is returned.
|
||||
*/
|
||||
static String getScript(String id) {
|
||||
return "root".equals(id) ? "" : Locale.forLanguageTag(id.replaceAll("_", "-")).getScript();
|
||||
}
|
||||
|
||||
private static class KeyComparator implements Comparator<String> {
|
||||
static KeyComparator INSTANCE = new KeyComparator();
|
||||
|
||||
|
@ -180,7 +180,8 @@ jprt.test.bundle.targets=\
|
||||
${my.make.rule.test.targets.hotspot.reg}, \
|
||||
${my.make.rule.test.targets.hotspot.gtest} \
|
||||
${my.make.rule.test.targets.nativesanity} \
|
||||
${my.test.target.set:TESTNAME=jdk_lang}
|
||||
${my.test.target.set:TESTNAME=jdk_lang} \
|
||||
${my.test.target.set:TESTNAME=jdk_nio}
|
||||
|
||||
# 7155453: Work-around to prevent popups on OSX from blocking test completion
|
||||
# but the work-around is added to all platforms to be consistent
|
||||
|
@ -75,6 +75,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_ch_FileDispatcherImpl_truncate0;
|
||||
Java_sun_nio_ch_FileDispatcherImpl_write0;
|
||||
Java_sun_nio_ch_FileDispatcherImpl_writev0;
|
||||
Java_sun_nio_ch_FileDispatcherImpl_setDirect0;
|
||||
Java_sun_nio_ch_FileKey_init;
|
||||
Java_sun_nio_ch_FileKey_initIDs;
|
||||
Java_sun_nio_ch_InheritedChannel_close0;
|
||||
|
@ -63,6 +63,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_ch_FileDispatcherImpl_truncate0;
|
||||
Java_sun_nio_ch_FileDispatcherImpl_write0;
|
||||
Java_sun_nio_ch_FileDispatcherImpl_writev0;
|
||||
Java_sun_nio_ch_FileDispatcherImpl_setDirect0;
|
||||
Java_sun_nio_ch_FileKey_init;
|
||||
Java_sun_nio_ch_FileKey_initIDs;
|
||||
Java_sun_nio_ch_InheritedChannel_close0;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,10 @@
|
||||
<name>Solaris_64</name>
|
||||
<type>0</type>
|
||||
</confElem>
|
||||
<confElem>
|
||||
<name>Windws64</name>
|
||||
<type>0</type>
|
||||
</confElem>
|
||||
</confList>
|
||||
<formatting>
|
||||
<project-formatting-style>false</project-formatting-style>
|
||||
|
@ -47,6 +47,10 @@ BUILD_JDK_JTREG_NATIVE_SRC += \
|
||||
$(TOPDIR)/test/jdk/java/lang/String/nativeEncoding \
|
||||
#
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows)
|
||||
BUILD_JDK_JTREG_NATIVE_SRC += $(TOPDIR)/test/jdk/java/nio/channels/FileChannel/directio
|
||||
endif
|
||||
|
||||
BUILD_JDK_JTREG_OUTPUT_DIR := $(OUTPUTDIR)/support/test/jdk/jtreg/native
|
||||
|
||||
BUILD_JDK_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/jdk/jtreg
|
||||
@ -56,8 +60,10 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
|
||||
else ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava -lc
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava -lc
|
||||
else
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
|
||||
endif
|
||||
|
||||
$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \
|
||||
|
@ -1075,11 +1075,7 @@ void LinkResolver::resolve_special_call(CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
TRAPS) {
|
||||
methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK);
|
||||
runtime_resolve_special_method(result, resolved_method,
|
||||
link_info.resolved_klass(),
|
||||
link_info.current_klass(),
|
||||
recv,
|
||||
link_info.check_access(), CHECK);
|
||||
runtime_resolve_special_method(result, link_info, resolved_method, recv, CHECK);
|
||||
}
|
||||
|
||||
// throws linktime exceptions
|
||||
@ -1163,11 +1159,11 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
|
||||
|
||||
// throws runtime exceptions
|
||||
void LinkResolver::runtime_resolve_special_method(CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
const methodHandle& resolved_method,
|
||||
Klass* resolved_klass,
|
||||
Klass* current_klass,
|
||||
Handle recv,
|
||||
bool check_access, TRAPS) {
|
||||
Handle recv, TRAPS) {
|
||||
|
||||
Klass* resolved_klass = link_info.resolved_klass();
|
||||
|
||||
// resolved method is selected method unless we have an old-style lookup
|
||||
// for a superclass method
|
||||
@ -1175,12 +1171,13 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
|
||||
// no checks for shadowing
|
||||
methodHandle sel_method(THREAD, resolved_method());
|
||||
|
||||
if (check_access &&
|
||||
if (link_info.check_access() &&
|
||||
// check if the method is not <init>
|
||||
resolved_method->name() != vmSymbols::object_initializer_name()) {
|
||||
|
||||
// check if this is an old-style super call and do a new lookup if so
|
||||
// check if this is an old-style super call and do a new lookup if so
|
||||
// a) check if ACC_SUPER flag is set for the current class
|
||||
Klass* current_klass = link_info.current_klass();
|
||||
if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
|
||||
// b) check if the class of the resolved_klass is a superclass
|
||||
// (not supertype in order to exclude interface classes) of the current class.
|
||||
@ -1200,6 +1197,9 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
|
||||
Method::name_and_sig_as_C_string(resolved_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature()));
|
||||
// check loader constraints if found a different method
|
||||
} else if (sel_method() != resolved_method()) {
|
||||
check_method_loader_constraints(link_info, sel_method, "method", CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,11 +233,10 @@ class LinkResolver: AllStatic {
|
||||
static methodHandle linktime_resolve_interface_method (const LinkInfo& link_info, TRAPS);
|
||||
|
||||
static void runtime_resolve_special_method (CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
const methodHandle& resolved_method,
|
||||
Klass* resolved_klass,
|
||||
Klass* current_klass,
|
||||
Handle recv,
|
||||
bool check_access, TRAPS);
|
||||
Handle recv, TRAPS);
|
||||
|
||||
static void runtime_resolve_virtual_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
Klass* resolved_klass,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2017, 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
|
||||
@ -156,7 +156,7 @@ abstract class AESCipher extends CipherSpi {
|
||||
throw new InvalidKeyException("Key encoding must not be null");
|
||||
} else if (value.length != fixedKeySize) {
|
||||
throw new InvalidKeyException("The key must be " +
|
||||
fixedKeySize*8 + " bits");
|
||||
fixedKeySize + " bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -509,7 +509,7 @@ abstract class AESCipher extends CipherSpi {
|
||||
throw new InvalidKeyException("Invalid AES key length: " +
|
||||
encoded.length + " bytes");
|
||||
}
|
||||
return encoded.length * 8;
|
||||
return Math.multiplyExact(encoded.length, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -628,9 +628,9 @@ abstract class AESCipher extends CipherSpi {
|
||||
}
|
||||
if (src != null) {
|
||||
int aadLen = src.limit() - src.position();
|
||||
if (aadLen != 0) {
|
||||
if (aadLen > 0) {
|
||||
if (src.hasArray()) {
|
||||
int aadOfs = src.arrayOffset() + src.position();
|
||||
int aadOfs = Math.addExact(src.arrayOffset(), src.position());
|
||||
core.updateAAD(src.array(), aadOfs, aadLen);
|
||||
src.position(src.limit());
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2017, 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
|
||||
@ -156,7 +156,7 @@ abstract class AESWrapCipher extends CipherSpi {
|
||||
if (decrypting) {
|
||||
result = inputLen - 8;
|
||||
} else {
|
||||
result = inputLen + 8;
|
||||
result = Math.addExact(inputLen, 8);
|
||||
}
|
||||
return (result < 0? 0:result);
|
||||
}
|
||||
@ -378,7 +378,7 @@ abstract class AESWrapCipher extends CipherSpi {
|
||||
throw new InvalidKeyException("Invalid key length: " +
|
||||
encoded.length + " bytes");
|
||||
}
|
||||
return encoded.length * 8;
|
||||
return Math.multiplyExact(encoded.length, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -404,7 +404,7 @@ abstract class AESWrapCipher extends CipherSpi {
|
||||
throw new InvalidKeyException("Cannot get an encoding of " +
|
||||
"the key to be wrapped");
|
||||
}
|
||||
byte[] out = new byte[keyVal.length + 8];
|
||||
byte[] out = new byte[Math.addExact(keyVal.length, 8)];
|
||||
|
||||
if (keyVal.length == 8) {
|
||||
System.arraycopy(IV, 0, out, 0, IV.length);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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
|
||||
@ -257,7 +257,7 @@ public final class ARCFOURCipher extends CipherSpi {
|
||||
// see JCE spec
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
byte[] encodedKey = getEncodedKey(key);
|
||||
return encodedKey.length << 3;
|
||||
return Math.multiplyExact(encodedKey.length, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -373,7 +373,7 @@ public final class BlowfishCipher extends CipherSpi {
|
||||
* @exception InvalidKeyException if <code>key</code> is invalid.
|
||||
*/
|
||||
protected int engineGetKeySize(Key key) throws InvalidKeyException {
|
||||
return (key.getEncoded().length * 8);
|
||||
return Math.multiplyExact(key.getEncoded().length, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2017, 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
|
||||
@ -324,13 +324,14 @@ final class CipherCore {
|
||||
}
|
||||
|
||||
private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
|
||||
int totalLen = buffered + inputLen + cipher.getBufferedLength();
|
||||
int totalLen = Math.addExact(buffered, cipher.getBufferedLength());
|
||||
totalLen = Math.addExact(totalLen, inputLen);
|
||||
switch (cipherMode) {
|
||||
case GCM_MODE:
|
||||
if (isDoFinal) {
|
||||
int tagLen = ((GaloisCounterMode) cipher).getTagLen();
|
||||
if (!decrypting) {
|
||||
totalLen += tagLen;
|
||||
totalLen = Math.addExact(totalLen, tagLen);
|
||||
} else {
|
||||
totalLen -= tagLen;
|
||||
}
|
||||
@ -346,10 +347,10 @@ final class CipherCore {
|
||||
totalLen = diffBlocksize;
|
||||
} else {
|
||||
int residue = (totalLen - diffBlocksize) % blockSize;
|
||||
totalLen += (blockSize - residue);
|
||||
totalLen = Math.addExact(totalLen, (blockSize - residue));
|
||||
}
|
||||
} else {
|
||||
totalLen += padding.padLength(totalLen);
|
||||
totalLen = Math.addExact(totalLen, padding.padLength(totalLen));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -711,7 +712,8 @@ final class CipherCore {
|
||||
}
|
||||
|
||||
// figure out how much can be sent to crypto function
|
||||
int len = buffered + inputLen - minBytes;
|
||||
int len = Math.addExact(buffered, inputLen);
|
||||
len -= minBytes;
|
||||
if (padding != null && decrypting) {
|
||||
// do not include the padding bytes when decrypting
|
||||
len -= blockSize;
|
||||
@ -730,12 +732,12 @@ final class CipherCore {
|
||||
int outLen = 0;
|
||||
if (len != 0) { // there is some work to do
|
||||
if ((input == output)
|
||||
&& (outputOffset < (inputOffset + inputLen))
|
||||
&& (inputOffset < (outputOffset + buffer.length))) {
|
||||
&& (outputOffset - inputOffset < inputLen)
|
||||
&& (inputOffset - outputOffset < buffer.length)) {
|
||||
// copy 'input' out to avoid its content being
|
||||
// overwritten prematurely.
|
||||
input = Arrays.copyOfRange(input, inputOffset,
|
||||
inputOffset + inputLen);
|
||||
Math.addExact(inputOffset, inputLen));
|
||||
inputOffset = 0;
|
||||
}
|
||||
if (len <= buffered) {
|
||||
@ -757,13 +759,13 @@ final class CipherCore {
|
||||
if (bufferCapacity != 0) {
|
||||
temp = Math.min(bufferCapacity, inputConsumed);
|
||||
if (unitBytes != blockSize) {
|
||||
temp -= ((buffered + temp) % unitBytes);
|
||||
temp -= (Math.addExact(buffered, temp) % unitBytes);
|
||||
}
|
||||
System.arraycopy(input, inputOffset, buffer, buffered, temp);
|
||||
inputOffset += temp;
|
||||
inputOffset = Math.addExact(inputOffset, temp);
|
||||
inputConsumed -= temp;
|
||||
inputLen -= temp;
|
||||
buffered += temp;
|
||||
buffered = Math.addExact(buffered, temp);
|
||||
}
|
||||
// process 'buffer'
|
||||
if (decrypting) {
|
||||
@ -771,7 +773,7 @@ final class CipherCore {
|
||||
} else {
|
||||
outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
|
||||
}
|
||||
outputOffset += outLen;
|
||||
outputOffset = Math.addExact(outputOffset, outLen);
|
||||
buffered = 0;
|
||||
}
|
||||
if (inputConsumed > 0) { // still has input to process
|
||||
@ -802,7 +804,7 @@ final class CipherCore {
|
||||
if (inputLen > 0) {
|
||||
System.arraycopy(input, inputOffset, buffer, buffered,
|
||||
inputLen);
|
||||
buffered += inputLen;
|
||||
buffered = Math.addExact(buffered, inputLen);
|
||||
}
|
||||
return outLen;
|
||||
}
|
||||
@ -912,10 +914,10 @@ final class CipherCore {
|
||||
}
|
||||
|
||||
// calculate total input length
|
||||
int len = buffered + inputLen;
|
||||
int len = Math.addExact(buffered, inputLen);
|
||||
|
||||
// calculate padding length
|
||||
int totalLen = len + cipher.getBufferedLength();
|
||||
int totalLen = Math.addExact(len, cipher.getBufferedLength());
|
||||
int paddingLen = 0;
|
||||
// will the total input length be a multiple of blockSize?
|
||||
if (unitBytes != blockSize) {
|
||||
@ -948,12 +950,12 @@ final class CipherCore {
|
||||
int finalBufLen = inputLen;
|
||||
if ((buffered != 0) || (!decrypting && padding != null) ||
|
||||
((input == output)
|
||||
&& (outputOffset < (inputOffset + inputLen))
|
||||
&& (inputOffset < (outputOffset + buffer.length)))) {
|
||||
&& (outputOffset - inputOffset < inputLen)
|
||||
&& (inputOffset - outputOffset < buffer.length))) {
|
||||
if (decrypting || padding == null) {
|
||||
paddingLen = 0;
|
||||
}
|
||||
finalBuf = new byte[len + paddingLen];
|
||||
finalBuf = new byte[Math.addExact(len, paddingLen)];
|
||||
finalOffset = 0;
|
||||
if (buffered != 0) {
|
||||
System.arraycopy(buffer, 0, finalBuf, 0, buffered);
|
||||
@ -963,7 +965,7 @@ final class CipherCore {
|
||||
buffered, inputLen);
|
||||
}
|
||||
if (paddingLen != 0) {
|
||||
padding.padWithLen(finalBuf, (buffered+inputLen), paddingLen);
|
||||
padding.padWithLen(finalBuf, Math.addExact(buffered, inputLen), paddingLen);
|
||||
}
|
||||
finalBufLen = finalBuf.length;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2017, 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
|
||||
@ -140,7 +140,7 @@ public final class DESedeWrapCipher extends CipherSpi {
|
||||
if (decrypting) {
|
||||
result = inputLen - 16; // CHECKSUM_LEN + IV_LEN;
|
||||
} else {
|
||||
result = inputLen + 16;
|
||||
result = Math.addExact(inputLen, 16);
|
||||
}
|
||||
return (result < 0? 0:result);
|
||||
}
|
||||
@ -449,11 +449,11 @@ public final class DESedeWrapCipher extends CipherSpi {
|
||||
}
|
||||
|
||||
byte[] cks = getChecksum(keyVal);
|
||||
byte[] in = new byte[keyVal.length + CHECKSUM_LEN];
|
||||
byte[] in = new byte[Math.addExact(keyVal.length, CHECKSUM_LEN)];
|
||||
System.arraycopy(keyVal, 0, in, 0, keyVal.length);
|
||||
System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
|
||||
|
||||
byte[] out = new byte[iv.length + in.length];
|
||||
byte[] out = new byte[Math.addExact(iv.length, in.length)];
|
||||
System.arraycopy(iv, 0, out, 0, iv.length);
|
||||
|
||||
cipher.encrypt(in, 0, in.length, out, iv.length);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -33,6 +33,7 @@ import javax.crypto.spec.DHParameterSpec;
|
||||
import javax.crypto.spec.DHGenParameterSpec;
|
||||
|
||||
import sun.security.provider.ParameterCache;
|
||||
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
|
||||
|
||||
/**
|
||||
* This class represents the key pair generator for Diffie-Hellman key pairs.
|
||||
@ -42,8 +43,7 @@ import sun.security.provider.ParameterCache;
|
||||
* <ul>
|
||||
* <li>By providing the size in bits of the prime modulus -
|
||||
* This will be used to create a prime modulus and base generator, which will
|
||||
* then be used to create the Diffie-Hellman key pair. The default size of the
|
||||
* prime modulus is 2048 bits.
|
||||
* then be used to create the Diffie-Hellman key pair.
|
||||
* <li>By providing a prime modulus and base generator
|
||||
* </ul>
|
||||
*
|
||||
@ -68,7 +68,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
|
||||
public DHKeyPairGenerator() {
|
||||
super();
|
||||
initialize(2048, null);
|
||||
initialize(DEF_DH_KEY_SIZE, null);
|
||||
}
|
||||
|
||||
private static void checkKeySize(int keysize)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -31,6 +31,8 @@ import java.security.spec.*;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
import javax.crypto.spec.DHGenParameterSpec;
|
||||
|
||||
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
|
||||
|
||||
/*
|
||||
* This class generates parameters for the Diffie-Hellman algorithm.
|
||||
* The parameters are a prime, a base, and optionally the length in bits of
|
||||
@ -38,7 +40,6 @@ import javax.crypto.spec.DHGenParameterSpec;
|
||||
*
|
||||
* <p>The Diffie-Hellman parameter generation accepts the size in bits of the
|
||||
* prime modulus and the size in bits of the random exponent as input.
|
||||
* The size of the prime modulus defaults to 2048 bits.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*
|
||||
@ -50,7 +51,7 @@ import javax.crypto.spec.DHGenParameterSpec;
|
||||
public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
|
||||
|
||||
// The size in bits of the prime modulus
|
||||
private int primeSize = 2048;
|
||||
private int primeSize = DEF_DH_KEY_SIZE;
|
||||
|
||||
// The size in bits of the random exponent (private value)
|
||||
private int exponentSize = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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
|
||||
@ -63,7 +63,8 @@ final class ISO10126Padding implements Padding {
|
||||
if (in == null)
|
||||
return;
|
||||
|
||||
if ((off + len) > in.length) {
|
||||
int idx = Math.addExact(off, len);
|
||||
if (idx > in.length) {
|
||||
throw new ShortBufferException("Buffer too small to hold padding");
|
||||
}
|
||||
|
||||
@ -71,7 +72,7 @@ final class ISO10126Padding implements Padding {
|
||||
byte[] padding = new byte[len - 1];
|
||||
SunJCE.getRandom().nextBytes(padding);
|
||||
System.arraycopy(padding, 0, in, off, len - 1);
|
||||
in[off + len - 1] = paddingOctet;
|
||||
in[idx - 1] = paddingOctet;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -94,14 +95,15 @@ final class ISO10126Padding implements Padding {
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte lastByte = in[off + len - 1];
|
||||
int idx = Math.addExact(off, len);
|
||||
byte lastByte = in[idx - 1];
|
||||
int padValue = (int)lastByte & 0x0ff;
|
||||
if ((padValue < 0x01)
|
||||
|| (padValue > blockSize)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int start = off + len - padValue;
|
||||
int start = idx - padValue;
|
||||
if (start < off) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -27,12 +27,14 @@ package com.sun.crypto.provider;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.KeyStoreSpi;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
@ -835,11 +837,21 @@ public final class JceKeyStore extends KeyStoreSpi {
|
||||
// read the sealed key
|
||||
try {
|
||||
ois = new ObjectInputStream(dis);
|
||||
final ObjectInputStream ois2 = ois;
|
||||
// Set a deserialization checker
|
||||
AccessController.doPrivileged(
|
||||
(PrivilegedAction<Void>)() -> {
|
||||
ois2.setObjectInputFilter(
|
||||
new DeserializationChecker());
|
||||
return null;
|
||||
});
|
||||
entry.sealedKey = (SealedObject)ois.readObject();
|
||||
// NOTE: don't close ois here since we are still
|
||||
// using dis!!!
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new IOException(cnfe.getMessage());
|
||||
} catch (InvalidClassException ice) {
|
||||
throw new IOException("Invalid secret key format");
|
||||
}
|
||||
|
||||
// Add the entry to the list
|
||||
@ -916,4 +928,34 @@ public final class JceKeyStore extends KeyStoreSpi {
|
||||
|
||||
return JCEKS_MAGIC == dataStream.readInt();
|
||||
}
|
||||
|
||||
/*
|
||||
* An ObjectInputFilter that checks the format of the secret key being
|
||||
* deserialized.
|
||||
*/
|
||||
private static class DeserializationChecker implements ObjectInputFilter {
|
||||
private static final int MAX_NESTED_DEPTH = 2;
|
||||
|
||||
@Override
|
||||
public ObjectInputFilter.Status
|
||||
checkInput(ObjectInputFilter.FilterInfo info) {
|
||||
|
||||
// First run a custom filter
|
||||
long nestedDepth = info.depth();
|
||||
if ((nestedDepth == 1 &&
|
||||
info.serialClass() != SealedObjectForKeyProtector.class) ||
|
||||
nestedDepth > MAX_NESTED_DEPTH) {
|
||||
return Status.REJECTED;
|
||||
}
|
||||
|
||||
// Next run the default filter, if available
|
||||
ObjectInputFilter defaultFilter =
|
||||
ObjectInputFilter.Config.getSerialFilter();
|
||||
if (defaultFilter != null) {
|
||||
return defaultFilter.checkInput(info);
|
||||
}
|
||||
|
||||
return Status.UNDECIDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -38,6 +38,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
@ -74,6 +75,8 @@ final class KeyProtector {
|
||||
// keys in the keystore implementation that comes with JDK 1.2)
|
||||
private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
|
||||
|
||||
private static final int MAX_ITERATION_COUNT = 5000000;
|
||||
private static final int ITERATION_COUNT = 200000;
|
||||
private static final int SALT_LEN = 20; // the salt length
|
||||
private static final int DIGEST_LEN = 20;
|
||||
|
||||
@ -100,7 +103,7 @@ final class KeyProtector {
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
|
||||
// create PBE parameters from salt and iteration count
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
|
||||
|
||||
// create PBE key from password
|
||||
PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
|
||||
@ -155,6 +158,9 @@ final class KeyProtector {
|
||||
pbeParams.init(encodedParams);
|
||||
PBEParameterSpec pbeSpec =
|
||||
pbeParams.getParameterSpec(PBEParameterSpec.class);
|
||||
if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
|
||||
throw new IOException("PBE iteration count too large");
|
||||
}
|
||||
|
||||
// create PBE key from password
|
||||
PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
|
||||
@ -285,7 +291,7 @@ final class KeyProtector {
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
|
||||
// create PBE parameters from salt and iteration count
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
|
||||
|
||||
// create PBE key from password
|
||||
PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
|
||||
@ -326,6 +332,15 @@ final class KeyProtector {
|
||||
throw new UnrecoverableKeyException("Cannot get " +
|
||||
"algorithm parameters");
|
||||
}
|
||||
PBEParameterSpec pbeSpec;
|
||||
try {
|
||||
pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
throw new IOException("Invalid PBE algorithm parameters");
|
||||
}
|
||||
if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
|
||||
throw new IOException("PBE iteration count too large");
|
||||
}
|
||||
PBEWithMD5AndTripleDESCipher cipherSpi;
|
||||
cipherSpi = new PBEWithMD5AndTripleDESCipher();
|
||||
Cipher cipher = new CipherForKeyProtector(cipherSpi,
|
||||
|
@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, 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.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
/**
|
||||
* This class represents password-based encryption as defined by the PKCS #5
|
||||
* standard.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*
|
||||
*
|
||||
* @see javax.crypto.Cipher
|
||||
*/
|
||||
final class PBECipherCore {
|
||||
|
||||
// the encapsulated DES cipher
|
||||
private CipherCore cipher;
|
||||
private MessageDigest md;
|
||||
private int blkSize;
|
||||
private String algo = null;
|
||||
private byte[] salt = null;
|
||||
private int iCount = 10;
|
||||
|
||||
/**
|
||||
* Creates an instance of PBE Cipher using the specified CipherSpi
|
||||
* instance.
|
||||
*
|
||||
*/
|
||||
PBECipherCore(String cipherAlg) throws NoSuchAlgorithmException,
|
||||
NoSuchPaddingException {
|
||||
algo = cipherAlg;
|
||||
if (algo.equals("DES")) {
|
||||
cipher = new CipherCore(new DESCrypt(),
|
||||
DESConstants.DES_BLOCK_SIZE);
|
||||
} else if (algo.equals("DESede")) {
|
||||
|
||||
cipher = new CipherCore(new DESedeCrypt(),
|
||||
DESConstants.DES_BLOCK_SIZE);
|
||||
} else {
|
||||
throw new NoSuchAlgorithmException("No Cipher implementation " +
|
||||
"for PBEWithMD5And" + algo);
|
||||
}
|
||||
cipher.setMode("CBC");
|
||||
cipher.setPadding("PKCS5Padding");
|
||||
// get instance of MD5
|
||||
md = MessageDigest.getInstance("MD5");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mode of this cipher. This algorithm can only be run in CBC
|
||||
* mode.
|
||||
*
|
||||
* @param mode the cipher mode
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if the requested cipher mode is
|
||||
* invalid
|
||||
*/
|
||||
void setMode(String mode) throws NoSuchAlgorithmException {
|
||||
cipher.setMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the padding mechanism of this cipher. This algorithm only uses
|
||||
* PKCS #5 padding.
|
||||
*
|
||||
* @param padding the padding mechanism
|
||||
*
|
||||
* @exception NoSuchPaddingException if the requested padding mechanism
|
||||
* is invalid
|
||||
*/
|
||||
void setPadding(String paddingScheme) throws NoSuchPaddingException {
|
||||
cipher.setPadding(paddingScheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block size (in bytes).
|
||||
*
|
||||
* @return the block size (in bytes)
|
||||
*/
|
||||
int getBlockSize() {
|
||||
return DESConstants.DES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length in bytes that an output buffer would need to be in
|
||||
* order to hold the result of the next <code>update</code> or
|
||||
* <code>doFinal</code> operation, given the input length
|
||||
* <code>inputLen</code> (in bytes).
|
||||
*
|
||||
* <p>This call takes into account any unprocessed (buffered) data from a
|
||||
* previous <code>update</code> call, and padding.
|
||||
*
|
||||
* <p>The actual output length of the next <code>update</code> or
|
||||
* <code>doFinal</code> call may be smaller than the length returned by
|
||||
* this method.
|
||||
*
|
||||
* @param inputLen the input length (in bytes)
|
||||
*
|
||||
* @return the required output buffer size (in bytes)
|
||||
*
|
||||
*/
|
||||
int getOutputSize(int inputLen) {
|
||||
return cipher.getOutputSize(inputLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the initialization vector (IV) in a new buffer.
|
||||
*
|
||||
* <p> This is useful in the case where a random IV has been created
|
||||
* (see <a href = "#init">init</a>),
|
||||
* or in the context of password-based encryption or
|
||||
* decryption, where the IV is derived from a user-supplied password.
|
||||
*
|
||||
* @return the initialization vector in a new buffer, or null if the
|
||||
* underlying algorithm does not use an IV, or if the IV has not yet
|
||||
* been set.
|
||||
*/
|
||||
byte[] getIV() {
|
||||
return cipher.getIV();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameters used with this cipher.
|
||||
*
|
||||
* <p>The returned parameters may be the same that were used to initialize
|
||||
* this cipher, or may contain the default set of parameters or a set of
|
||||
* randomly generated parameters used by the underlying cipher
|
||||
* implementation (provided that the underlying cipher implementation
|
||||
* uses a default set of parameters or creates new parameters if it needs
|
||||
* parameters but was not initialized with any).
|
||||
*
|
||||
* @return the parameters used with this cipher, or null if this cipher
|
||||
* does not use any parameters.
|
||||
*/
|
||||
AlgorithmParameters getParameters() {
|
||||
AlgorithmParameters params = null;
|
||||
if (salt == null) {
|
||||
salt = new byte[8];
|
||||
SunJCE.getRandom().nextBytes(salt);
|
||||
}
|
||||
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
|
||||
try {
|
||||
params = AlgorithmParameters.getInstance("PBEWithMD5And" +
|
||||
(algo.equalsIgnoreCase("DES")? "DES":"TripleDES"),
|
||||
SunJCE.getInstance());
|
||||
params.init(pbeSpec);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// should never happen
|
||||
throw new RuntimeException("SunJCE called, but not configured");
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// should never happen
|
||||
throw new RuntimeException("PBEParameterSpec not supported");
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this cipher with a key, a set of
|
||||
* algorithm parameters, and a source of randomness.
|
||||
* The cipher is initialized for one of the following four operations:
|
||||
* encryption, decryption, key wrapping or key unwrapping, depending on
|
||||
* the value of <code>opmode</code>.
|
||||
*
|
||||
* <p>If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes, it will get them from <code>random</code>.
|
||||
*
|
||||
* @param opmode the operation mode of this cipher (this is one of
|
||||
* the following:
|
||||
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>),
|
||||
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
||||
* @param key the encryption key
|
||||
* @param params the algorithm parameters
|
||||
* @param random the source of randomness
|
||||
*
|
||||
* @exception InvalidKeyException if the given key is inappropriate for
|
||||
* initializing this cipher
|
||||
* @exception InvalidAlgorithmParameterException if the given algorithm
|
||||
* parameters are inappropriate for this cipher
|
||||
*/
|
||||
void init(int opmode, Key key, AlgorithmParameterSpec params,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
if (((opmode == Cipher.DECRYPT_MODE) ||
|
||||
(opmode == Cipher.UNWRAP_MODE)) && (params == null)) {
|
||||
throw new InvalidAlgorithmParameterException("Parameters "
|
||||
+ "missing");
|
||||
}
|
||||
if ((key == null) ||
|
||||
(key.getEncoded() == null) ||
|
||||
!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) {
|
||||
throw new InvalidKeyException("Missing password");
|
||||
}
|
||||
|
||||
if (params == null) {
|
||||
// create random salt and use default iteration count
|
||||
salt = new byte[8];
|
||||
random.nextBytes(salt);
|
||||
} else {
|
||||
if (!(params instanceof PBEParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Wrong parameter type: PBE expected");
|
||||
}
|
||||
salt = ((PBEParameterSpec) params).getSalt();
|
||||
// salt must be 8 bytes long (by definition)
|
||||
if (salt.length != 8) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Salt must be 8 bytes long");
|
||||
}
|
||||
iCount = ((PBEParameterSpec) params).getIterationCount();
|
||||
if (iCount <= 0) {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("IterationCount must be a positive number");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] derivedKey = deriveCipherKey(key);
|
||||
// use all but the last 8 bytes as the key value
|
||||
SecretKeySpec cipherKey = new SecretKeySpec(derivedKey, 0,
|
||||
derivedKey.length-8, algo);
|
||||
// use the last 8 bytes as the IV
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(derivedKey,
|
||||
derivedKey.length-8,
|
||||
8);
|
||||
// initialize the underlying cipher
|
||||
cipher.init(opmode, cipherKey, ivSpec, random);
|
||||
}
|
||||
|
||||
private byte[] deriveCipherKey(Key key) {
|
||||
|
||||
byte[] result = null;
|
||||
byte[] passwdBytes = key.getEncoded();
|
||||
|
||||
if (algo.equals("DES")) {
|
||||
// P || S (password concatenated with salt)
|
||||
byte[] concat = new byte[passwdBytes.length + salt.length];
|
||||
System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
|
||||
java.util.Arrays.fill(passwdBytes, (byte)0x00);
|
||||
System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
|
||||
|
||||
// digest P || S with c iterations
|
||||
byte[] toBeHashed = concat;
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
md.update(toBeHashed);
|
||||
toBeHashed = md.digest(); // this resets the digest
|
||||
}
|
||||
java.util.Arrays.fill(concat, (byte)0x00);
|
||||
result = toBeHashed;
|
||||
} else if (algo.equals("DESede")) {
|
||||
// if the 2 salt halves are the same, invert one of them
|
||||
int i;
|
||||
for (i=0; i<4; i++) {
|
||||
if (salt[i] != salt[i+4])
|
||||
break;
|
||||
}
|
||||
if (i==4) { // same, invert 1st half
|
||||
for (i=0; i<2; i++) {
|
||||
byte tmp = salt[i];
|
||||
salt[i] = salt[3-i];
|
||||
salt[3-1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// Now digest each half (concatenated with password). For each
|
||||
// half, go through the loop as many times as specified by the
|
||||
// iteration count parameter (inner for loop).
|
||||
// Concatenate the output from each digest round with the
|
||||
// password, and use the result as the input to the next digest
|
||||
// operation.
|
||||
byte[] kBytes = null;
|
||||
IvParameterSpec iv = null;
|
||||
byte[] toBeHashed = null;
|
||||
result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN +
|
||||
DESConstants.DES_BLOCK_SIZE];
|
||||
for (i = 0; i < 2; i++) {
|
||||
toBeHashed = new byte[salt.length/2];
|
||||
System.arraycopy(salt, i*(salt.length/2), toBeHashed, 0,
|
||||
toBeHashed.length);
|
||||
for (int j=0; j < iCount; j++) {
|
||||
md.update(toBeHashed);
|
||||
md.update(passwdBytes);
|
||||
toBeHashed = md.digest(); // this resets the digest
|
||||
}
|
||||
System.arraycopy(toBeHashed, 0, result, i*16,
|
||||
toBeHashed.length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void init(int opmode, Key key, AlgorithmParameters params,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
PBEParameterSpec pbeSpec = null;
|
||||
if (params != null) {
|
||||
try {
|
||||
pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
throw new InvalidAlgorithmParameterException("Wrong parameter "
|
||||
+ "type: PBE "
|
||||
+ "expected");
|
||||
}
|
||||
}
|
||||
init(opmode, key, pbeSpec, random);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multiple-part encryption or decryption operation
|
||||
* (depending on how this cipher was initialized), processing another data
|
||||
* part.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code>, are processed, and the
|
||||
* result is stored in a new buffer.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
*
|
||||
* @return the new buffer with the result
|
||||
*
|
||||
*/
|
||||
byte[] update(byte[] input, int inputOffset, int inputLen) {
|
||||
return cipher.update(input, inputOffset, inputLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multiple-part encryption or decryption operation
|
||||
* (depending on how this cipher was initialized), processing another data
|
||||
* part.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code>, are processed, and the
|
||||
* result is stored in the <code>output</code> buffer, starting at
|
||||
* <code>outputOffset</code>.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
* @param output the buffer for the result
|
||||
* @param outputOffset the offset in <code>output</code> where the result
|
||||
* is stored
|
||||
*
|
||||
* @return the number of bytes stored in <code>output</code>
|
||||
*
|
||||
* @exception ShortBufferException if the given output buffer is too small
|
||||
* to hold the result
|
||||
*/
|
||||
int update(byte[] input, int inputOffset, int inputLen,
|
||||
byte[] output, int outputOffset)
|
||||
throws ShortBufferException {
|
||||
return cipher.update(input, inputOffset, inputLen,
|
||||
output, outputOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts data in a single-part operation,
|
||||
* or finishes a multiple-part operation.
|
||||
* The data is encrypted or decrypted, depending on how this cipher was
|
||||
* initialized.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code>, and any input bytes that
|
||||
* may have been buffered during a previous <code>update</code> operation,
|
||||
* are processed, with padding (if requested) being applied.
|
||||
* The result is stored in a new buffer.
|
||||
*
|
||||
* <p>The cipher is reset to its initial state (uninitialized) after this
|
||||
* call.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
*
|
||||
* @return the new buffer with the result
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
||||
* no padding has been requested (only in encryption mode), and the total
|
||||
* input length of the data processed by this cipher is not a multiple of
|
||||
* block size
|
||||
* @exception BadPaddingException if decrypting and padding is chosen,
|
||||
* but the last input data does not have proper padding bytes.
|
||||
*/
|
||||
byte[] doFinal(byte[] input, int inputOffset, int inputLen)
|
||||
throws IllegalBlockSizeException, BadPaddingException {
|
||||
return cipher.doFinal(input, inputOffset, inputLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts data in a single-part operation,
|
||||
* or finishes a multiple-part operation.
|
||||
* The data is encrypted or decrypted, depending on how this cipher was
|
||||
* initialized.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code>, and any input bytes that
|
||||
* may have been buffered during a previous <code>update</code> operation,
|
||||
* are processed, with padding (if requested) being applied.
|
||||
* The result is stored in the <code>output</code> buffer, starting at
|
||||
* <code>outputOffset</code>.
|
||||
*
|
||||
* <p>The cipher is reset to its initial state (uninitialized) after this
|
||||
* call.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
* @param output the buffer for the result
|
||||
* @param outputOffset the offset in <code>output</code> where the result
|
||||
* is stored
|
||||
*
|
||||
* @return the number of bytes stored in <code>output</code>
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
||||
* no padding has been requested (only in encryption mode), and the total
|
||||
* input length of the data processed by this cipher is not a multiple of
|
||||
* block size
|
||||
* @exception ShortBufferException if the given output buffer is too small
|
||||
* to hold the result
|
||||
* @exception BadPaddingException if decrypting and padding is chosen,
|
||||
* but the last input data does not have proper padding bytes.
|
||||
*/
|
||||
int doFinal(byte[] input, int inputOffset, int inputLen,
|
||||
byte[] output, int outputOffset)
|
||||
throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
return cipher.doFinal(input, inputOffset, inputLen,
|
||||
output, outputOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a key.
|
||||
*
|
||||
* @param key the key to be wrapped.
|
||||
*
|
||||
* @return the wrapped key.
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block
|
||||
* cipher, no padding has been requested, and the length of the
|
||||
* encoding of the key to be wrapped is not a
|
||||
* multiple of the block size.
|
||||
*
|
||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||
* being passed to a software only cipher).
|
||||
*/
|
||||
byte[] wrap(Key key)
|
||||
throws IllegalBlockSizeException, InvalidKeyException {
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
byte[] encodedKey = key.getEncoded();
|
||||
if ((encodedKey == null) || (encodedKey.length == 0)) {
|
||||
throw new InvalidKeyException("Cannot get an encoding of " +
|
||||
"the key to be wrapped");
|
||||
}
|
||||
|
||||
result = doFinal(encodedKey, 0, encodedKey.length);
|
||||
} catch (BadPaddingException e) {
|
||||
// Should never happen
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a previously wrapped key.
|
||||
*
|
||||
* @param wrappedKey the key to be unwrapped.
|
||||
*
|
||||
* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
|
||||
*
|
||||
* @param wrappedKeyType the type of the wrapped key.
|
||||
* This is one of <code>Cipher.SECRET_KEY</code>,
|
||||
* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
|
||||
*
|
||||
* @return the unwrapped key.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no installed providers
|
||||
* can create keys of type <code>wrappedKeyType</code> for the
|
||||
* <code>wrappedKeyAlgorithm</code>.
|
||||
*
|
||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
||||
* the <code>wrappedKeyAlgorithm</code>.
|
||||
*/
|
||||
Key unwrap(byte[] wrappedKey,
|
||||
String wrappedKeyAlgorithm,
|
||||
int wrappedKeyType)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException {
|
||||
byte[] encodedKey;
|
||||
try {
|
||||
encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
|
||||
} catch (BadPaddingException ePadding) {
|
||||
throw new InvalidKeyException("The wrapped key is not padded " +
|
||||
"correctly");
|
||||
} catch (IllegalBlockSizeException eBlockSize) {
|
||||
throw new InvalidKeyException("The wrapped key does not have " +
|
||||
"the correct length");
|
||||
}
|
||||
return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
|
||||
wrappedKeyType);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2017, 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
|
||||
@ -260,7 +260,7 @@ final class PBES1Core {
|
||||
|
||||
if (algo.equals("DES")) {
|
||||
// P || S (password concatenated with salt)
|
||||
byte[] concat = new byte[passwdBytes.length + salt.length];
|
||||
byte[] concat = new byte[Math.addExact(passwdBytes.length, salt.length)];
|
||||
System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
|
||||
java.util.Arrays.fill(passwdBytes, (byte)0x00);
|
||||
System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
|
||||
@ -284,7 +284,7 @@ final class PBES1Core {
|
||||
for (i=0; i<2; i++) {
|
||||
byte tmp = salt[i];
|
||||
salt[i] = salt[3-i];
|
||||
salt[3-1] = tmp;
|
||||
salt[3-i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -26,6 +26,7 @@
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import javax.crypto.ShortBufferException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class implements padding as specified in the PKCS#5 standard.
|
||||
@ -63,14 +64,13 @@ final class PKCS5Padding implements Padding {
|
||||
if (in == null)
|
||||
return;
|
||||
|
||||
if ((off + len) > in.length) {
|
||||
int idx = Math.addExact(off, len);
|
||||
if (idx > in.length) {
|
||||
throw new ShortBufferException("Buffer too small to hold padding");
|
||||
}
|
||||
|
||||
byte paddingOctet = (byte) (len & 0xff);
|
||||
for (int i = 0; i < len; i++) {
|
||||
in[i + off] = paddingOctet;
|
||||
}
|
||||
Arrays.fill(in, off, idx, paddingOctet);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -92,25 +92,24 @@ final class PKCS5Padding implements Padding {
|
||||
(len == 0)) { // this can happen if input is really a padded buffer
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte lastByte = in[off + len - 1];
|
||||
int idx = Math.addExact(off, len);
|
||||
byte lastByte = in[idx - 1];
|
||||
int padValue = (int)lastByte & 0x0ff;
|
||||
if ((padValue < 0x01)
|
||||
|| (padValue > blockSize)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int start = off + len - ((int)lastByte & 0x0ff);
|
||||
int start = idx - padValue;
|
||||
if (start < off) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((int)lastByte & 0x0ff); i++) {
|
||||
if (in[start+i] != lastByte) {
|
||||
for (int i = start; i < idx; i++) {
|
||||
if (in[i] != lastByte) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ package com.sun.net.ssl.internal.www.protocol.https;
|
||||
import java.net.URL;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.io.*;
|
||||
import java.net.Authenticator;
|
||||
import javax.net.ssl.*;
|
||||
@ -78,10 +79,18 @@ public class HttpsURLConnectionOldImpl
|
||||
this(u, null, handler);
|
||||
}
|
||||
|
||||
static URL checkURL(URL u) throws IOException {
|
||||
if (u != null) {
|
||||
if (u.toExternalForm().indexOf('\n') > -1) {
|
||||
throw new MalformedURLException("Illegal character in URL");
|
||||
}
|
||||
}
|
||||
return u;
|
||||
}
|
||||
// For both copies of the file, uncomment one line and comment the other
|
||||
// HttpsURLConnectionImpl(URL u, Handler handler) throws IOException {
|
||||
HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
|
||||
super(u);
|
||||
super(checkURL(u));
|
||||
delegate = new DelegateHttpsURLConnection(url, p, handler, this);
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,8 @@ class FileInputStream extends InputStream
|
||||
synchronized (this) {
|
||||
fc = this.channel;
|
||||
if (fc == null) {
|
||||
this.channel = fc = FileChannelImpl.open(fd, path, true, false, this);
|
||||
this.channel = fc = FileChannelImpl.open(fd, path, true,
|
||||
false, false, this);
|
||||
if (closed) {
|
||||
try {
|
||||
// possible race with close(), benign since
|
||||
|
@ -410,7 +410,8 @@ class FileOutputStream extends OutputStream
|
||||
synchronized (this) {
|
||||
fc = this.channel;
|
||||
if (fc == null) {
|
||||
this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
|
||||
this.channel = fc = FileChannelImpl.open(fd, path, false,
|
||||
true, false, this);
|
||||
if (closed) {
|
||||
try {
|
||||
// possible race with close(), benign since
|
||||
|
@ -44,7 +44,6 @@ import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
|
||||
import jdk.internal.misc.ObjectStreamClassValidator;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
@ -1282,6 +1281,33 @@ public class ObjectInputStream
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given array type and length to ensure that creation of such
|
||||
* an array is permitted by this ObjectInputStream. The arrayType argument
|
||||
* must represent an actual array type.
|
||||
*
|
||||
* This private method is called via SharedSecrets.
|
||||
*
|
||||
* @param arrayType the array type
|
||||
* @param arrayLength the array length
|
||||
* @throws NullPointerException if arrayType is null
|
||||
* @throws IllegalArgumentException if arrayType isn't actually an array type
|
||||
* @throws NegativeArraySizeException if arrayLength is negative
|
||||
* @throws InvalidClassException if the filter rejects creation
|
||||
*/
|
||||
private void checkArray(Class<?> arrayType, int arrayLength) throws InvalidClassException {
|
||||
Objects.requireNonNull(arrayType);
|
||||
if (! arrayType.isArray()) {
|
||||
throw new IllegalArgumentException("not an array type");
|
||||
}
|
||||
|
||||
if (arrayLength < 0) {
|
||||
throw new NegativeArraySizeException();
|
||||
}
|
||||
|
||||
filterCheck(arrayType, arrayLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide access to the persistent fields read from the input stream.
|
||||
*/
|
||||
@ -1740,9 +1766,6 @@ public class ObjectInputStream
|
||||
throw new StreamCorruptedException(
|
||||
String.format("invalid type code: %02X", tc));
|
||||
}
|
||||
if (descriptor != null) {
|
||||
validateDescriptor(descriptor);
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@ -1770,6 +1793,10 @@ public class ObjectInputStream
|
||||
passHandle = NULL_HANDLE;
|
||||
|
||||
int numIfaces = bin.readInt();
|
||||
if (numIfaces > 65535) {
|
||||
throw new InvalidObjectException("interface limit exceeded: "
|
||||
+ numIfaces);
|
||||
}
|
||||
String[] ifaces = new String[numIfaces];
|
||||
for (int i = 0; i < numIfaces; i++) {
|
||||
ifaces[i] = bin.readUTF();
|
||||
@ -3978,20 +4005,8 @@ public class ObjectInputStream
|
||||
}
|
||||
}
|
||||
|
||||
private void validateDescriptor(ObjectStreamClass descriptor) {
|
||||
ObjectStreamClassValidator validating = validator;
|
||||
if (validating != null) {
|
||||
validating.validateDescriptor(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
// controlled access to ObjectStreamClassValidator
|
||||
private volatile ObjectStreamClassValidator validator;
|
||||
|
||||
private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
|
||||
ois.validator = validator;
|
||||
}
|
||||
static {
|
||||
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
|
||||
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::checkArray);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,14 +32,19 @@ import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Permissions;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -53,7 +58,8 @@ import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.reflect.ReflectionFactory;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.JavaSecurityAccess;
|
||||
import static java.io.ObjectStreamField.*;
|
||||
|
||||
/**
|
||||
@ -176,6 +182,9 @@ public class ObjectStreamClass implements Serializable {
|
||||
|
||||
/** serialization-appropriate constructor, or null if none */
|
||||
private Constructor<?> cons;
|
||||
/** protection domains that need to be checked when calling the constructor */
|
||||
private ProtectionDomain[] domains;
|
||||
|
||||
/** class-defined writeObject method, or null if none */
|
||||
private Method writeObjectMethod;
|
||||
/** class-defined readObject method, or null if none */
|
||||
@ -508,6 +517,7 @@ public class ObjectStreamClass implements Serializable {
|
||||
cl, "readObjectNoData", null, Void.TYPE);
|
||||
hasWriteObjectData = (writeObjectMethod != null);
|
||||
}
|
||||
domains = getProtectionDomains(cons, cl);
|
||||
writeReplaceMethod = getInheritableMethod(
|
||||
cl, "writeReplace", null, Object.class);
|
||||
readResolveMethod = getInheritableMethod(
|
||||
@ -550,6 +560,65 @@ public class ObjectStreamClass implements Serializable {
|
||||
ObjectStreamClass() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PermissionDomain that grants no permission.
|
||||
*/
|
||||
private ProtectionDomain noPermissionsDomain() {
|
||||
PermissionCollection perms = new Permissions();
|
||||
perms.setReadOnly();
|
||||
return new ProtectionDomain(null, perms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregate the ProtectionDomains of all the classes that separate
|
||||
* a concrete class {@code cl} from its ancestor's class declaring
|
||||
* a constructor {@code cons}.
|
||||
*
|
||||
* If {@code cl} is defined by the boot loader, or the constructor
|
||||
* {@code cons} is declared by {@code cl}, or if there is no security
|
||||
* manager, then this method does nothing and {@code null} is returned.
|
||||
*
|
||||
* @param cons A constructor declared by {@code cl} or one of its
|
||||
* ancestors.
|
||||
* @param cl A concrete class, which is either the class declaring
|
||||
* the constructor {@code cons}, or a serializable subclass
|
||||
* of that class.
|
||||
* @return An array of ProtectionDomain representing the set of
|
||||
* ProtectionDomain that separate the concrete class {@code cl}
|
||||
* from its ancestor's declaring {@code cons}, or {@code null}.
|
||||
*/
|
||||
private ProtectionDomain[] getProtectionDomains(Constructor<?> cons,
|
||||
Class<?> cl) {
|
||||
ProtectionDomain[] domains = null;
|
||||
if (cons != null && cl.getClassLoader() != null
|
||||
&& System.getSecurityManager() != null) {
|
||||
Class<?> cls = cl;
|
||||
Class<?> fnscl = cons.getDeclaringClass();
|
||||
Set<ProtectionDomain> pds = null;
|
||||
while (cls != fnscl) {
|
||||
ProtectionDomain pd = cls.getProtectionDomain();
|
||||
if (pd != null) {
|
||||
if (pds == null) pds = new HashSet<>();
|
||||
pds.add(pd);
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
if (cls == null) {
|
||||
// that's not supposed to happen
|
||||
// make a ProtectionDomain with no permission.
|
||||
// should we throw instead?
|
||||
if (pds == null) pds = new HashSet<>();
|
||||
else pds.clear();
|
||||
pds.add(noPermissionsDomain());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pds != null) {
|
||||
domains = pds.toArray(new ProtectionDomain[0]);
|
||||
}
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes class descriptor representing a proxy class.
|
||||
*/
|
||||
@ -580,6 +649,7 @@ public class ObjectStreamClass implements Serializable {
|
||||
writeReplaceMethod = localDesc.writeReplaceMethod;
|
||||
readResolveMethod = localDesc.readResolveMethod;
|
||||
deserializeEx = localDesc.deserializeEx;
|
||||
domains = localDesc.domains;
|
||||
cons = localDesc.cons;
|
||||
}
|
||||
fieldRefl = getReflector(fields, localDesc);
|
||||
@ -666,6 +736,7 @@ public class ObjectStreamClass implements Serializable {
|
||||
if (deserializeEx == null) {
|
||||
deserializeEx = localDesc.deserializeEx;
|
||||
}
|
||||
domains = localDesc.domains;
|
||||
cons = localDesc.cons;
|
||||
}
|
||||
|
||||
@ -1006,7 +1077,35 @@ public class ObjectStreamClass implements Serializable {
|
||||
requireInitialized();
|
||||
if (cons != null) {
|
||||
try {
|
||||
return cons.newInstance();
|
||||
if (domains == null || domains.length == 0) {
|
||||
return cons.newInstance();
|
||||
} else {
|
||||
JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
|
||||
PrivilegedAction<?> pea = () -> {
|
||||
try {
|
||||
return cons.newInstance();
|
||||
} catch (InstantiationException
|
||||
| InvocationTargetException
|
||||
| IllegalAccessException x) {
|
||||
throw new UndeclaredThrowableException(x);
|
||||
}
|
||||
}; // Can't use PrivilegedExceptionAction with jsa
|
||||
try {
|
||||
return jsa.doIntersectionPrivilege(pea,
|
||||
AccessController.getContext(),
|
||||
new AccessControlContext(domains));
|
||||
} catch (UndeclaredThrowableException x) {
|
||||
Throwable cause = x.getCause();
|
||||
if (cause instanceof InstantiationException)
|
||||
throw (InstantiationException) cause;
|
||||
if (cause instanceof InvocationTargetException)
|
||||
throw (InvocationTargetException) cause;
|
||||
if (cause instanceof IllegalAccessException)
|
||||
throw (IllegalAccessException) cause;
|
||||
// not supposed to happen
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
// should not occur, as access checks have been suppressed
|
||||
throw new InternalError(ex);
|
||||
|
@ -298,7 +298,8 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
||||
synchronized (this) {
|
||||
fc = this.channel;
|
||||
if (fc == null) {
|
||||
this.channel = fc = FileChannelImpl.open(fd, path, true, rw, this);
|
||||
this.channel = fc = FileChannelImpl.open(fd, path, true,
|
||||
rw, false, this);
|
||||
if (closed.get()) {
|
||||
try {
|
||||
fc.close();
|
||||
|
@ -2166,7 +2166,7 @@ public abstract class ClassLoader {
|
||||
* @spec JPMS
|
||||
*
|
||||
* @jvms 5.3 Run-time package
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#package-sealing">
|
||||
* The JAR File Specification: Package Sealing</a>
|
||||
*/
|
||||
protected Package definePackage(String name, String specTitle,
|
||||
|
@ -109,7 +109,7 @@ import jdk.internal.reflect.Reflection;
|
||||
* and have no specification and implementation versioning information.
|
||||
*
|
||||
* @jvms 5.3 Run-time package
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#package-sealing">
|
||||
* The JAR File Specification: Package Sealing</a>
|
||||
* @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
|
||||
*
|
||||
|
@ -2664,6 +2664,7 @@ public final class String
|
||||
* point</a> is passed through uninterpreted.
|
||||
*
|
||||
* @return an IntStream of char values from this sequence
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public IntStream chars() {
|
||||
@ -2683,6 +2684,7 @@ public final class String
|
||||
* {@code int} values which are then passed to the stream.
|
||||
*
|
||||
* @return an IntStream of Unicode code points from this sequence
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public IntStream codePoints() {
|
||||
|
@ -88,7 +88,7 @@ final class WeakPairMap<K1, K2, V> {
|
||||
* Maps the specified key pair to the specified value in this WeakPairMap.
|
||||
* Neither the keys nor the value can be null.
|
||||
* <p>The value can be retrieved by calling the {@link #get} method
|
||||
* with the the same keys (compared by identity).
|
||||
* with the same keys (compared by identity).
|
||||
*
|
||||
* @param k1 the 1st of the pair of keys with which the specified value is to
|
||||
* be associated
|
||||
|
@ -1196,7 +1196,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
static
|
||||
MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
|
||||
// Code in the the boot layer should now be careful while creating method handles or
|
||||
// Code in the boot layer should now be careful while creating method handles or
|
||||
// functional interface instances created from method references to @CallerSensitive methods,
|
||||
// it needs to be ensured the handles or interface instances are kept safe and are not passed
|
||||
// from the boot layer to untrusted code.
|
||||
|
@ -195,7 +195,7 @@ public final class StringConcatFactory {
|
||||
// In case we need to double-back onto the StringConcatFactory during this
|
||||
// static initialization, make sure we have the reasonable defaults to complete
|
||||
// the static initialization properly. After that, actual users would use the
|
||||
// the proper values we have read from the the properties.
|
||||
// the proper values we have read from the properties.
|
||||
STRATEGY = DEFAULT_STRATEGY;
|
||||
// CACHE_ENABLE = false; // implied
|
||||
// CACHE = null; // implied
|
||||
@ -398,8 +398,8 @@ public final class StringConcatFactory {
|
||||
* <p>Then the following linkage invariants must hold:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The parameter count in {@code concatType} is less than or equal to 200</li>
|
||||
*
|
||||
* <li>The number of parameter slots in {@code concatType} is
|
||||
* less than or equal to 200</li>
|
||||
* <li>The return type in {@code concatType} is assignable from {@link java.lang.String}</li>
|
||||
* </ul>
|
||||
*
|
||||
@ -487,8 +487,8 @@ public final class StringConcatFactory {
|
||||
* <p>Then the following linkage invariants must hold:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The parameter count in {@code concatType} is less than or equal to
|
||||
* 200</li>
|
||||
* <li>The number of parameter slots in {@code concatType} is less than
|
||||
* or equal to 200</li>
|
||||
*
|
||||
* <li>The parameter count in {@code concatType} equals to number of \1 tags
|
||||
* in {@code recipe}</li>
|
||||
@ -613,9 +613,9 @@ public final class StringConcatFactory {
|
||||
concatType.returnType());
|
||||
}
|
||||
|
||||
if (concatType.parameterCount() > MAX_INDY_CONCAT_ARG_SLOTS) {
|
||||
if (concatType.parameterSlotCount() > MAX_INDY_CONCAT_ARG_SLOTS) {
|
||||
throw new StringConcatException("Too many concat argument slots: " +
|
||||
concatType.parameterCount() +
|
||||
concatType.parameterSlotCount() +
|
||||
", can only accept " +
|
||||
MAX_INDY_CONCAT_ARG_SLOTS);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, 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
|
||||
@ -111,6 +111,31 @@ public abstract class FileStore {
|
||||
*/
|
||||
public abstract long getUsableSpace() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the number of bytes per block in this file store.
|
||||
*
|
||||
* <p> File storage is typically organized into discrete sequences of bytes
|
||||
* called <i>blocks</i>. A block is the smallest storage unit of a file store.
|
||||
* Every read and write operation is performed on a multiple of blocks.
|
||||
*
|
||||
* @implSpec The implementation in this class throws an
|
||||
* {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @return a positive value representing the block size of this file store,
|
||||
* in bytes
|
||||
*
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* if the operation is not supported
|
||||
*
|
||||
* @since 10
|
||||
*/
|
||||
public long getBlockSize() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of unallocated bytes in the file store.
|
||||
*
|
||||
|
@ -35,6 +35,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.*;
|
||||
import sun.net.util.URLUtil;
|
||||
import sun.security.util.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -571,6 +572,8 @@ public class CodeSource implements java.io.Serializable {
|
||||
// could all be present in the stream at the same time
|
||||
cfs = new Hashtable<>(3);
|
||||
certList = new ArrayList<>(size > 20 ? 20 : size);
|
||||
} else if (size < 0) {
|
||||
throw new IOException("size cannot be negative");
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
@ -592,13 +595,7 @@ public class CodeSource implements java.io.Serializable {
|
||||
cfs.put(certType, cf);
|
||||
}
|
||||
// parse the certificate
|
||||
byte[] encoded = null;
|
||||
try {
|
||||
encoded = new byte[ois.readInt()];
|
||||
} catch (OutOfMemoryError oome) {
|
||||
throw new IOException("Certificate too big");
|
||||
}
|
||||
ois.readFully(encoded);
|
||||
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
|
||||
try {
|
||||
certList.add(cf.generateCertificate(bais));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -25,12 +25,16 @@
|
||||
|
||||
package java.security;
|
||||
|
||||
import sun.security.util.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.lang.reflect.*;
|
||||
import java.security.cert.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The UnresolvedPermission class is used to hold Permissions that
|
||||
@ -550,6 +554,7 @@ implements java.io.Serializable
|
||||
{
|
||||
CertificateFactory cf;
|
||||
Hashtable<String, CertificateFactory> cfs = null;
|
||||
List<Certificate> certList = null;
|
||||
|
||||
ois.defaultReadObject();
|
||||
|
||||
@ -562,7 +567,9 @@ implements java.io.Serializable
|
||||
// we know of 3 different cert types: X.509, PGP, SDSI, which
|
||||
// could all be present in the stream at the same time
|
||||
cfs = new Hashtable<>(3);
|
||||
this.certs = new java.security.cert.Certificate[size];
|
||||
certList = new ArrayList<>(size > 20 ? 20 : size);
|
||||
} else if (size < 0) {
|
||||
throw new IOException("size cannot be negative");
|
||||
}
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
@ -584,20 +591,18 @@ implements java.io.Serializable
|
||||
cfs.put(certType, cf);
|
||||
}
|
||||
// parse the certificate
|
||||
byte[] encoded=null;
|
||||
try {
|
||||
encoded = new byte[ois.readInt()];
|
||||
} catch (OutOfMemoryError oome) {
|
||||
throw new IOException("Certificate too big");
|
||||
}
|
||||
ois.readFully(encoded);
|
||||
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
|
||||
try {
|
||||
this.certs[i] = cf.generateCertificate(bais);
|
||||
certList.add(cf.generateCertificate(bais));
|
||||
} catch (CertificateException ce) {
|
||||
throw new IOException(ce.getMessage());
|
||||
}
|
||||
bais.close();
|
||||
}
|
||||
if (certList != null) {
|
||||
this.certs = certList.toArray(
|
||||
new java.security.cert.Certificate[size]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, 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
|
||||
@ -34,6 +34,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.util.IOUtils;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.x509.InvalidityDateExtension;
|
||||
|
||||
@ -230,17 +231,17 @@ public class CertificateRevokedException extends CertificateException {
|
||||
int size = ois.readInt();
|
||||
if (size == 0) {
|
||||
extensions = Collections.emptyMap();
|
||||
} else if (size < 0) {
|
||||
throw new IOException("size cannot be negative");
|
||||
} else {
|
||||
extensions = new HashMap<>(size);
|
||||
extensions = new HashMap<>(size > 20 ? 20 : size);
|
||||
}
|
||||
|
||||
// Read in the extensions and put the mappings in the extensions map
|
||||
for (int i = 0; i < size; i++) {
|
||||
String oid = (String) ois.readObject();
|
||||
boolean critical = ois.readBoolean();
|
||||
int length = ois.readInt();
|
||||
byte[] extVal = new byte[length];
|
||||
ois.readFully(extVal);
|
||||
byte[] extVal = IOUtils.readNBytes(ois, ois.readInt());
|
||||
Extension ext = sun.security.x509.Extension.newExtension
|
||||
(new ObjectIdentifier(oid), critical, extVal);
|
||||
extensions.put(oid, ext);
|
||||
|
@ -38,6 +38,7 @@ import java.io.Serializable;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Resizable-array implementation of the {@link Deque} interface. Array
|
||||
@ -1194,6 +1195,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
|
||||
// Read in size and allocate array
|
||||
int size = s.readInt();
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size + 1);
|
||||
elements = new Object[size + 1];
|
||||
this.tail = size;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -28,6 +28,7 @@ package java.util;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Resizable-array implementation of the {@code List} interface. Implements
|
||||
@ -814,6 +815,7 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
|
||||
if (size > 0) {
|
||||
// like clone(), allocate array based upon size not capacity
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
|
||||
Object[] elements = new Object[size];
|
||||
|
||||
// Read in all elements in the proper order.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -34,6 +34,7 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Hash table based implementation of the {@code Map} interface. This
|
||||
@ -1448,6 +1449,10 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||
float ft = (float)cap * lf;
|
||||
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
|
||||
(int)ft : Integer.MAX_VALUE);
|
||||
|
||||
// Check Map.Entry[].class since it's the nearest public type to
|
||||
// what we're actually creating.
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, cap);
|
||||
@SuppressWarnings({"rawtypes","unchecked"})
|
||||
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
|
||||
table = tab;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -26,6 +26,7 @@
|
||||
package java.util;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* This class implements the {@code Set} interface, backed by a hash table
|
||||
@ -322,6 +323,13 @@ public class HashSet<E>
|
||||
capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
|
||||
HashMap.MAXIMUM_CAPACITY);
|
||||
|
||||
// Constructing the backing map will lazily create an array when the first element is
|
||||
// added, so check it before construction. Call HashMap.tableSizeFor to compute the
|
||||
// actual allocation size. Check Map.Entry[].class since it's the nearest public type to
|
||||
// what is actually created.
|
||||
SharedSecrets.getJavaObjectInputStreamAccess()
|
||||
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));
|
||||
|
||||
// Create backing HashMap
|
||||
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
|
||||
new LinkedHashMap<>(capacity, loadFactor) :
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2017, 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
|
||||
@ -29,6 +29,7 @@ import java.io.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* This class implements a hash table, which maps keys to values. Any
|
||||
@ -1291,6 +1292,10 @@ public class Hashtable<K,V>
|
||||
if (length > elements && (length & 1) == 0)
|
||||
length--;
|
||||
length = Math.min(length, origlength);
|
||||
|
||||
// Check Map.Entry[].class since it's the nearest public type to
|
||||
// what we're actually creating.
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length);
|
||||
table = new Entry<?,?>[length];
|
||||
threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
|
||||
count = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -29,6 +29,7 @@ import java.lang.reflect.Array;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* This class implements the {@code Map} interface with a hash table, using
|
||||
@ -1304,7 +1305,9 @@ public class IdentityHashMap<K,V>
|
||||
if (size < 0)
|
||||
throw new java.io.StreamCorruptedException
|
||||
("Illegal mappings count: " + size);
|
||||
init(capacity(size));
|
||||
int cap = capacity(size);
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap);
|
||||
init(cap);
|
||||
|
||||
// Read the keys and values, and put the mappings in the table
|
||||
for (int i=0; i<size; i++) {
|
||||
|
@ -35,6 +35,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.vm.annotation.Stable;
|
||||
|
||||
/**
|
||||
@ -885,6 +886,7 @@ final class CollSer implements Serializable {
|
||||
throw new InvalidObjectException("negative length " + len);
|
||||
}
|
||||
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, len);
|
||||
Object[] a = new Object[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
a[i] = ois.readObject();
|
||||
|
@ -1909,7 +1909,7 @@ public final class Locale implements Cloneable, Serializable {
|
||||
* Returns a name for the locale that is appropriate for display to the
|
||||
* user. This will be the values returned by getDisplayLanguage(),
|
||||
* getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled
|
||||
* into a single string. The the non-empty values are used in order,
|
||||
* into a single string. The non-empty values are used in order,
|
||||
* with the second and subsequent names in parentheses. For example:
|
||||
* <blockquote>
|
||||
* language (script, country, variant)<br>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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
|
||||
@ -26,6 +26,7 @@
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* An unbounded priority {@linkplain Queue queue} based on a priority heap.
|
||||
@ -795,6 +796,7 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
// Read in (and discard) array length
|
||||
s.readInt();
|
||||
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
|
||||
queue = new Object[size];
|
||||
|
||||
// Read in all elements.
|
||||
|
@ -42,6 +42,7 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.util.xml.PropertiesDefaultHandler;
|
||||
|
||||
/**
|
||||
@ -1441,6 +1442,16 @@ class Properties extends Hashtable<Object,Object> {
|
||||
throw new StreamCorruptedException("Illegal # of Elements: " + elements);
|
||||
}
|
||||
|
||||
// Constructing the backing map will lazily create an array when the first element is
|
||||
// added, so check it before construction. Note that CHM's constructor takes a size
|
||||
// that is the number of elements to be stored -- not the table size -- so it must be
|
||||
// inflated by the default load factor of 0.75, then inflated to the next power of two.
|
||||
// (CHM uses the same power-of-two computation as HashMap, and HashMap.tableSizeFor is
|
||||
// accessible here.) Check Map.Entry[].class since it's the nearest public type to
|
||||
// what is actually created.
|
||||
SharedSecrets.getJavaObjectInputStreamAccess()
|
||||
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor((int)(elements / 0.75)));
|
||||
|
||||
// create CHM of appropriate capacity
|
||||
map = new ConcurrentHashMap<>(elements);
|
||||
|
||||
|
@ -1409,7 +1409,7 @@ public final class ServiceLoader<S>
|
||||
*
|
||||
* <p> To achieve laziness the actual work of locating providers is done
|
||||
* when processing the stream. If a service provider cannot be loaded for any
|
||||
* of the the reasons specified in the <a href="#errors">Errors</a> section
|
||||
* of the reasons specified in the <a href="#errors">Errors</a> section
|
||||
* above then {@link ServiceConfigurationError} is thrown by whatever method
|
||||
* caused the service provider to be loaded. </p>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
@ -41,6 +41,7 @@ package java.util;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import sun.util.calendar.CalendarSystem;
|
||||
import sun.util.calendar.CalendarUtils;
|
||||
import sun.util.calendar.BaseCalendar;
|
||||
@ -1278,6 +1279,9 @@ public class SimpleTimeZone extends TimeZone {
|
||||
*/
|
||||
private int serialVersionOnStream = currentSerialVersion;
|
||||
|
||||
// Maximum number of rules.
|
||||
private static final int MAX_RULE_NUM = 6;
|
||||
|
||||
private synchronized void invalidateCache() {
|
||||
cacheYear = startYear - 1;
|
||||
cacheStart = cacheEnd = 0;
|
||||
@ -1569,7 +1573,7 @@ public class SimpleTimeZone extends TimeZone {
|
||||
*/
|
||||
private byte[] packRules()
|
||||
{
|
||||
byte[] rules = new byte[6];
|
||||
byte[] rules = new byte[MAX_RULE_NUM];
|
||||
rules[0] = (byte)startDay;
|
||||
rules[1] = (byte)startDayOfWeek;
|
||||
rules[2] = (byte)endDay;
|
||||
@ -1594,7 +1598,7 @@ public class SimpleTimeZone extends TimeZone {
|
||||
endDayOfWeek = rules[3];
|
||||
|
||||
// As of serial version 2, include time modes
|
||||
if (rules.length >= 6) {
|
||||
if (rules.length >= MAX_RULE_NUM) {
|
||||
startTimeMode = rules[4];
|
||||
endTimeMode = rules[5];
|
||||
}
|
||||
@ -1691,9 +1695,13 @@ public class SimpleTimeZone extends TimeZone {
|
||||
// store the actual rules (which have not be made compatible with 1.1)
|
||||
// in the optional area. Read them in here and parse them.
|
||||
int length = stream.readInt();
|
||||
byte[] rules = new byte[length];
|
||||
stream.readFully(rules);
|
||||
unpackRules(rules);
|
||||
if (length <= MAX_RULE_NUM) {
|
||||
byte[] rules = new byte[length];
|
||||
stream.readFully(rules);
|
||||
unpackRules(rules);
|
||||
} else {
|
||||
throw new InvalidObjectException("Too many rules: " + length);
|
||||
}
|
||||
}
|
||||
|
||||
if (serialVersionOnStream >= 2) {
|
||||
|
@ -51,6 +51,7 @@ import java.util.Spliterators;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* A thread-safe variant of {@link java.util.ArrayList} in which all mutative
|
||||
@ -933,6 +934,7 @@ public class CopyOnWriteArrayList<E>
|
||||
|
||||
// Read in array length and allocate array
|
||||
int len = s.readInt();
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, len);
|
||||
Object[] elements = new Object[len];
|
||||
|
||||
// Read in all elements in the proper order.
|
||||
|
@ -568,7 +568,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
/**
|
||||
* {@code Name} object for {@code Sealed} manifest attribute
|
||||
* used for sealing.
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#package-sealing">
|
||||
* Package Sealing</a>
|
||||
*/
|
||||
public static final Name SEALED = new Name("Sealed");
|
||||
|
@ -134,7 +134,7 @@ import sun.security.util.Debug;
|
||||
* setting the value of the {@code auth.policy.provider} security property to
|
||||
* the fully qualified name of the desired {@code Policy} implementation class.
|
||||
*
|
||||
* @deprecated as of JDK version 1.4 -- Replaced by java.security.Policy.
|
||||
* @deprecated Replaced by java.security.Policy.
|
||||
* java.security.Policy has a method:
|
||||
* <pre>
|
||||
* public PermissionCollection getPermissions
|
||||
@ -152,11 +152,12 @@ import sun.security.util.Debug;
|
||||
*
|
||||
* These two APIs provide callers the means to query the
|
||||
* Policy for Principal-based Permission entries.
|
||||
* This class is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @since 1.4
|
||||
* @see java.security.Security security properties
|
||||
*/
|
||||
@Deprecated(since="1.4")
|
||||
@Deprecated(since="1.4", forRemoval=true)
|
||||
public abstract class Policy {
|
||||
|
||||
private static Policy policy;
|
||||
|
@ -29,7 +29,6 @@ import java.security.AccessController;
|
||||
import java.security.Permission;
|
||||
import java.security.Permissions;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Policy;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
@ -57,7 +56,7 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
|
||||
sun.security.util.Debug.getInstance("combiner",
|
||||
"\t[SubjectDomainCombiner]");
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
// Note: check only at classloading time, not dynamically during combine()
|
||||
private static final boolean useJavaxPolicy =
|
||||
javax.security.auth.Policy.isCustomPolicySet(debug);
|
||||
@ -303,7 +302,7 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
|
||||
if (!allowCaching) {
|
||||
java.security.AccessController.doPrivileged
|
||||
(new PrivilegedAction<Void>() {
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public Void run() {
|
||||
// Call refresh only caching is disallowed
|
||||
javax.security.auth.Policy.getPolicy().refresh();
|
||||
@ -374,7 +373,7 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner {
|
||||
PermissionCollection newPerms =
|
||||
java.security.AccessController.doPrivileged
|
||||
(new PrivilegedAction<PermissionCollection>() {
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public PermissionCollection run() {
|
||||
return
|
||||
javax.security.auth.Policy.getPolicy().getPermissions
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 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
|
||||
@ -25,17 +25,14 @@
|
||||
|
||||
package jdk.internal.misc;
|
||||
|
||||
import java.io.InvalidClassException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
/**
|
||||
* The interface to specify methods for accessing {@code ObjectInputStream}
|
||||
* @author sjiang
|
||||
* Interface to specify methods for accessing {@code ObjectInputStream}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface JavaObjectInputStreamAccess {
|
||||
/**
|
||||
* Sets a descriptor validating.
|
||||
* @param ois stream to have the descriptors validated
|
||||
* @param validator validator used to validate a descriptor.
|
||||
*/
|
||||
public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator);
|
||||
void checkArray(ObjectInputStream ois, Class<?> arrayType, int arrayLength)
|
||||
throws InvalidClassException;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ import jdk.internal.perf.PerfCounter;
|
||||
* -m and --add-modules options. The modules are located on a module path that
|
||||
* is constructed from the upgrade module path, system modules, and application
|
||||
* module path. The Configuration is instantiated as the boot layer with each
|
||||
* module in the the configuration defined to a class loader.
|
||||
* module in the configuration defined to a class loader.
|
||||
*/
|
||||
|
||||
public final class ModuleBootstrap {
|
||||
|
@ -74,7 +74,7 @@ public class ModuleHashesBuilder {
|
||||
* the outgoing edges from M to non-candidate modules.
|
||||
*/
|
||||
public Map<String, ModuleHashes> computeHashes(Set<String> roots) {
|
||||
// build a graph containing the the packaged modules and
|
||||
// build a graph containing the packaged modules and
|
||||
// its transitive dependences matching --hash-modules
|
||||
Graph.Builder<String> builder = new Graph.Builder<>();
|
||||
Deque<ResolvedModule> deque = new ArrayDeque<>(configuration.modules());
|
||||
|
@ -56,7 +56,7 @@ public final class Resources {
|
||||
/**
|
||||
* Derive a <em>package name</em> for a resource. The package name
|
||||
* returned by this method may not be a legal package name. This method
|
||||
* returns null if the the resource name ends with a "/" (a directory)
|
||||
* returns null if the resource name ends with a "/" (a directory)
|
||||
* or the resource name does not contain a "/".
|
||||
*/
|
||||
public static String toPackageName(String name) {
|
||||
|
@ -192,7 +192,7 @@ final class Frame {
|
||||
private static final int LOCAL = 0x2000000;
|
||||
|
||||
/**
|
||||
* Kind of the the types that are relative to the stack of an input stack
|
||||
* Kind of the types that are relative to the stack of an input stack
|
||||
* map frame. The value of such types is a position relatively to the top of
|
||||
* this stack.
|
||||
*/
|
||||
|
@ -115,8 +115,8 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
|
||||
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
|
||||
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
|
||||
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
|
||||
encs[0] = System.getProperty("file.encoding", "ISO8859_1");
|
||||
return null;
|
||||
}
|
||||
|
@ -843,18 +843,36 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
this(u, null, handler);
|
||||
}
|
||||
|
||||
public HttpURLConnection(URL u, String host, int port) {
|
||||
this(u, new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(host, port)));
|
||||
private static String checkHost(String h) throws IOException {
|
||||
if (h != null) {
|
||||
if (h.indexOf('\n') > -1) {
|
||||
throw new MalformedURLException("Illegal character in host");
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
public HttpURLConnection(URL u, String host, int port) throws IOException {
|
||||
this(u, new Proxy(Proxy.Type.HTTP,
|
||||
InetSocketAddress.createUnresolved(checkHost(host), port)));
|
||||
}
|
||||
|
||||
/** this constructor is used by other protocol handlers such as ftp
|
||||
that want to use http to fetch urls on their behalf.*/
|
||||
public HttpURLConnection(URL u, Proxy p) {
|
||||
public HttpURLConnection(URL u, Proxy p) throws IOException {
|
||||
this(u, p, new Handler());
|
||||
}
|
||||
|
||||
protected HttpURLConnection(URL u, Proxy p, Handler handler) {
|
||||
super(u);
|
||||
private static URL checkURL(URL u) throws IOException {
|
||||
if (u != null) {
|
||||
if (u.toExternalForm().indexOf('\n') > -1) {
|
||||
throw new MalformedURLException("Illegal character in URL");
|
||||
}
|
||||
}
|
||||
return u;
|
||||
}
|
||||
protected HttpURLConnection(URL u, Proxy p, Handler handler)
|
||||
throws IOException {
|
||||
super(checkURL(u));
|
||||
requests = new MessageHeader();
|
||||
responses = new MessageHeader();
|
||||
userHeaders = new MessageHeader();
|
||||
|
@ -38,6 +38,7 @@ package sun.net.www.protocol.https;
|
||||
import java.net.URL;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.io.*;
|
||||
import java.net.Authenticator;
|
||||
import javax.net.ssl.*;
|
||||
@ -80,10 +81,18 @@ public class HttpsURLConnectionImpl
|
||||
this(u, null, handler);
|
||||
}
|
||||
|
||||
static URL checkURL(URL u) throws IOException {
|
||||
if (u != null) {
|
||||
if (u.toExternalForm().indexOf('\n') > -1) {
|
||||
throw new MalformedURLException("Illegal character in URL");
|
||||
}
|
||||
}
|
||||
return u;
|
||||
}
|
||||
// For both copies of the file, uncomment one line and comment the other
|
||||
HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException {
|
||||
// HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
|
||||
super(u);
|
||||
super(checkURL(u));
|
||||
delegate = new DelegateHttpsURLConnection(url, p, handler, this);
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,11 @@ import java.nio.channels.OverlappingFileLockException;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.FileStore;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -87,6 +92,12 @@ public class FileChannelImpl
|
||||
// Positional-read is not interruptible
|
||||
private volatile boolean uninterruptible;
|
||||
|
||||
// DirectIO flag
|
||||
private final boolean direct;
|
||||
|
||||
// IO alignment value for DirectIO
|
||||
private final int alignment;
|
||||
|
||||
// Cleanable with an action which closes this channel's file descriptor
|
||||
private final Cleanable closer;
|
||||
|
||||
@ -103,14 +114,22 @@ public class FileChannelImpl
|
||||
}
|
||||
|
||||
private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
|
||||
boolean writable, Object parent)
|
||||
boolean writable, boolean direct, Object parent)
|
||||
{
|
||||
this.fd = fd;
|
||||
this.readable = readable;
|
||||
this.writable = writable;
|
||||
this.parent = parent;
|
||||
this.path = path;
|
||||
this.direct = direct;
|
||||
this.nd = new FileDispatcherImpl();
|
||||
if (direct) {
|
||||
assert path != null;
|
||||
this.alignment = nd.setDirectIO(fd, path);
|
||||
} else {
|
||||
this.alignment = -1;
|
||||
}
|
||||
|
||||
// Register a cleaning action if and only if there is no parent
|
||||
// as the parent will take care of closing the file descriptor.
|
||||
// FileChannel is used by the LambdaMetaFactory so a lambda cannot
|
||||
@ -123,9 +142,9 @@ public class FileChannelImpl
|
||||
// and RandomAccessFile.getChannel()
|
||||
public static FileChannel open(FileDescriptor fd, String path,
|
||||
boolean readable, boolean writable,
|
||||
Object parent)
|
||||
boolean direct, Object parent)
|
||||
{
|
||||
return new FileChannelImpl(fd, path, readable, writable, parent);
|
||||
return new FileChannelImpl(fd, path, readable, writable, direct, parent);
|
||||
}
|
||||
|
||||
private void ensureOpen() throws IOException {
|
||||
@ -181,6 +200,8 @@ public class FileChannelImpl
|
||||
if (!readable)
|
||||
throw new NonReadableChannelException();
|
||||
synchronized (positionLock) {
|
||||
if (direct)
|
||||
Util.checkChannelPositionAligned(position(), alignment);
|
||||
int n = 0;
|
||||
int ti = -1;
|
||||
try {
|
||||
@ -189,7 +210,7 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return 0;
|
||||
do {
|
||||
n = IOUtil.read(fd, dst, -1, nd);
|
||||
n = IOUtil.read(fd, dst, -1, direct, alignment, nd);
|
||||
} while ((n == IOStatus.INTERRUPTED) && isOpen());
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
@ -209,6 +230,8 @@ public class FileChannelImpl
|
||||
if (!readable)
|
||||
throw new NonReadableChannelException();
|
||||
synchronized (positionLock) {
|
||||
if (direct)
|
||||
Util.checkChannelPositionAligned(position(), alignment);
|
||||
long n = 0;
|
||||
int ti = -1;
|
||||
try {
|
||||
@ -217,7 +240,8 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return 0;
|
||||
do {
|
||||
n = IOUtil.read(fd, dsts, offset, length, nd);
|
||||
n = IOUtil.read(fd, dsts, offset, length,
|
||||
direct, alignment, nd);
|
||||
} while ((n == IOStatus.INTERRUPTED) && isOpen());
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
@ -233,6 +257,8 @@ public class FileChannelImpl
|
||||
if (!writable)
|
||||
throw new NonWritableChannelException();
|
||||
synchronized (positionLock) {
|
||||
if (direct)
|
||||
Util.checkChannelPositionAligned(position(), alignment);
|
||||
int n = 0;
|
||||
int ti = -1;
|
||||
try {
|
||||
@ -241,7 +267,7 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return 0;
|
||||
do {
|
||||
n = IOUtil.write(fd, src, -1, nd);
|
||||
n = IOUtil.write(fd, src, -1, direct, alignment, nd);
|
||||
} while ((n == IOStatus.INTERRUPTED) && isOpen());
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
@ -261,6 +287,8 @@ public class FileChannelImpl
|
||||
if (!writable)
|
||||
throw new NonWritableChannelException();
|
||||
synchronized (positionLock) {
|
||||
if (direct)
|
||||
Util.checkChannelPositionAligned(position(), alignment);
|
||||
long n = 0;
|
||||
int ti = -1;
|
||||
try {
|
||||
@ -269,7 +297,8 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return 0;
|
||||
do {
|
||||
n = IOUtil.write(fd, srcs, offset, length, nd);
|
||||
n = IOUtil.write(fd, srcs, offset, length,
|
||||
direct, alignment, nd);
|
||||
} while ((n == IOStatus.INTERRUPTED) && isOpen());
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
@ -752,6 +781,8 @@ public class FileChannelImpl
|
||||
throw new IllegalArgumentException("Negative position");
|
||||
if (!readable)
|
||||
throw new NonReadableChannelException();
|
||||
if (direct)
|
||||
Util.checkChannelPositionAligned(position, alignment);
|
||||
ensureOpen();
|
||||
if (nd.needsPositionLock()) {
|
||||
synchronized (positionLock) {
|
||||
@ -774,7 +805,7 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return -1;
|
||||
do {
|
||||
n = IOUtil.read(fd, dst, position, nd);
|
||||
n = IOUtil.read(fd, dst, position, direct, alignment, nd);
|
||||
} while ((n == IOStatus.INTERRUPTED) && isOpen());
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
@ -791,6 +822,8 @@ public class FileChannelImpl
|
||||
throw new IllegalArgumentException("Negative position");
|
||||
if (!writable)
|
||||
throw new NonWritableChannelException();
|
||||
if (direct)
|
||||
Util.checkChannelPositionAligned(position, alignment);
|
||||
ensureOpen();
|
||||
if (nd.needsPositionLock()) {
|
||||
synchronized (positionLock) {
|
||||
@ -811,7 +844,7 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return -1;
|
||||
do {
|
||||
n = IOUtil.write(fd, src, position, nd);
|
||||
n = IOUtil.write(fd, src, position, direct, alignment, nd);
|
||||
} while ((n == IOStatus.INTERRUPTED) && isOpen());
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, 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
|
||||
@ -61,4 +61,6 @@ abstract class FileDispatcher extends NativeDispatcher {
|
||||
abstract boolean canTransferToDirectly(SelectableChannel sc);
|
||||
|
||||
abstract boolean transferToDirectlyNeedsPositionLock();
|
||||
|
||||
abstract int setDirectIO(FileDescriptor fd, String path);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -47,22 +47,38 @@ public class IOUtil {
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
if (src instanceof DirectBuffer)
|
||||
return writeFromNativeBuffer(fd, src, position, nd);
|
||||
return write(fd, src, position, false, -1, nd);
|
||||
}
|
||||
|
||||
static int write(FileDescriptor fd, ByteBuffer src, long position,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
if (src instanceof DirectBuffer) {
|
||||
return writeFromNativeBuffer(fd, src, position,
|
||||
directIO, alignment, nd);
|
||||
}
|
||||
|
||||
// Substitute a native buffer
|
||||
int pos = src.position();
|
||||
int lim = src.limit();
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
|
||||
ByteBuffer bb;
|
||||
if (directIO) {
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
bb = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
|
||||
} else {
|
||||
bb = Util.getTemporaryDirectBuffer(rem);
|
||||
}
|
||||
try {
|
||||
bb.put(src);
|
||||
bb.flip();
|
||||
// Do not update src until we see how many bytes were written
|
||||
src.position(pos);
|
||||
|
||||
int n = writeFromNativeBuffer(fd, bb, position, nd);
|
||||
int n = writeFromNativeBuffer(fd, bb, position,
|
||||
directIO, alignment, nd);
|
||||
if (n > 0) {
|
||||
// now update src
|
||||
src.position(pos + n);
|
||||
@ -74,7 +90,8 @@ public class IOUtil {
|
||||
}
|
||||
|
||||
private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
|
||||
long position, NativeDispatcher nd)
|
||||
long position, boolean directIO,
|
||||
int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
int pos = bb.position();
|
||||
@ -82,6 +99,11 @@ public class IOUtil {
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (directIO) {
|
||||
Util.checkBufferPositionAligned(bb, pos, alignment);
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
}
|
||||
|
||||
int written = 0;
|
||||
if (rem == 0)
|
||||
return 0;
|
||||
@ -100,12 +122,19 @@ public class IOUtil {
|
||||
static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return write(fd, bufs, 0, bufs.length, nd);
|
||||
return write(fd, bufs, 0, bufs.length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return write(fd, bufs, offset, length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
IOVecWrapper vec = IOVecWrapper.get(length);
|
||||
|
||||
@ -122,12 +151,20 @@ public class IOUtil {
|
||||
int lim = buf.limit();
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
if (directIO)
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
|
||||
if (rem > 0) {
|
||||
vec.setBuffer(iov_len, buf, pos, rem);
|
||||
|
||||
// allocate shadow buffer to ensure I/O is done with direct buffer
|
||||
if (!(buf instanceof DirectBuffer)) {
|
||||
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
ByteBuffer shadow;
|
||||
if (directIO)
|
||||
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
|
||||
alignment);
|
||||
else
|
||||
shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
shadow.put(buf);
|
||||
shadow.flip();
|
||||
vec.setShadow(iov_len, shadow);
|
||||
@ -185,16 +222,33 @@ public class IOUtil {
|
||||
static int read(FileDescriptor fd, ByteBuffer dst, long position,
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return read(fd, dst, position, false, -1, nd);
|
||||
}
|
||||
|
||||
static int read(FileDescriptor fd, ByteBuffer dst, long position,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
if (dst.isReadOnly())
|
||||
throw new IllegalArgumentException("Read-only buffer");
|
||||
if (dst instanceof DirectBuffer)
|
||||
return readIntoNativeBuffer(fd, dst, position, nd);
|
||||
return readIntoNativeBuffer(fd, dst, position,
|
||||
directIO, alignment, nd);
|
||||
|
||||
// Substitute a native buffer
|
||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
|
||||
ByteBuffer bb;
|
||||
int rem = dst.remaining();
|
||||
if (directIO) {
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
bb = Util.getTemporaryAlignedDirectBuffer(rem,
|
||||
alignment);
|
||||
} else {
|
||||
bb = Util.getTemporaryDirectBuffer(rem);
|
||||
}
|
||||
try {
|
||||
int n = readIntoNativeBuffer(fd, bb, position, nd);
|
||||
int n = readIntoNativeBuffer(fd, bb, position,
|
||||
directIO, alignment,nd);
|
||||
bb.flip();
|
||||
if (n > 0)
|
||||
dst.put(bb);
|
||||
@ -205,7 +259,8 @@ public class IOUtil {
|
||||
}
|
||||
|
||||
private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb,
|
||||
long position, NativeDispatcher nd)
|
||||
long position, boolean directIO,
|
||||
int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
int pos = bb.position();
|
||||
@ -213,6 +268,11 @@ public class IOUtil {
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (directIO) {
|
||||
Util.checkBufferPositionAligned(bb, pos, alignment);
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
}
|
||||
|
||||
if (rem == 0)
|
||||
return 0;
|
||||
int n = 0;
|
||||
@ -230,12 +290,19 @@ public class IOUtil {
|
||||
static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return read(fd, bufs, 0, bufs.length, nd);
|
||||
return read(fd, bufs, 0, bufs.length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return read(fd, bufs, offset, bufs.length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
IOVecWrapper vec = IOVecWrapper.get(length);
|
||||
|
||||
@ -255,12 +322,21 @@ public class IOUtil {
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (directIO)
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
|
||||
if (rem > 0) {
|
||||
vec.setBuffer(iov_len, buf, pos, rem);
|
||||
|
||||
// allocate shadow buffer to ensure I/O is done with direct buffer
|
||||
if (!(buf instanceof DirectBuffer)) {
|
||||
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
ByteBuffer shadow;
|
||||
if (directIO) {
|
||||
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
|
||||
alignment);
|
||||
} else {
|
||||
shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
}
|
||||
vec.setShadow(iov_len, shadow);
|
||||
buf = shadow;
|
||||
pos = shadow.position();
|
||||
|
@ -37,7 +37,7 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Util {
|
||||
|
||||
@ -236,6 +236,33 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a temporary buffer of at least the given size and
|
||||
* aligned to the alignment
|
||||
*/
|
||||
public static ByteBuffer getTemporaryAlignedDirectBuffer(int size,
|
||||
int alignment) {
|
||||
if (isBufferTooLarge(size)) {
|
||||
return ByteBuffer.allocateDirect(size + alignment - 1)
|
||||
.alignedSlice(alignment);
|
||||
}
|
||||
|
||||
BufferCache cache = bufferCache.get();
|
||||
ByteBuffer buf = cache.get(size);
|
||||
if (buf != null) {
|
||||
if (buf.alignmentOffset(0, alignment) == 0) {
|
||||
return buf;
|
||||
}
|
||||
} else {
|
||||
if (!cache.isEmpty()) {
|
||||
buf = cache.removeFirst();
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
return ByteBuffer.allocateDirect(size + alignment - 1)
|
||||
.alignedSlice(alignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases a temporary buffer by returning to the cache or freeing it.
|
||||
*/
|
||||
@ -459,4 +486,37 @@ public class Util {
|
||||
}
|
||||
return dbb;
|
||||
}
|
||||
|
||||
static void checkBufferPositionAligned(ByteBuffer bb,
|
||||
int pos, int alignment)
|
||||
throws IOException
|
||||
{
|
||||
if (bb.alignmentOffset(pos, alignment) != 0) {
|
||||
throw new IOException("Current location of the bytebuffer ("
|
||||
+ pos + ") is not a multiple of the block size ("
|
||||
+ alignment + ")");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkRemainingBufferSizeAligned(int rem,
|
||||
int alignment)
|
||||
throws IOException
|
||||
{
|
||||
if (rem % alignment != 0) {
|
||||
throw new IOException("Number of remaining bytes ("
|
||||
+ rem + ") is not a multiple of the block size ("
|
||||
+ alignment + ")");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkChannelPositionAligned(long position,
|
||||
int alignment)
|
||||
throws IOException
|
||||
{
|
||||
if (position % alignment != 0) {
|
||||
throw new IOException("Channel position (" + position
|
||||
+ ") is not a multiple of the block size ("
|
||||
+ alignment + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -137,6 +137,8 @@ public final class ExtendedOptions {
|
||||
|
||||
public static final InternalOption<Void> FILE_TREE = new InternalOption<>();
|
||||
|
||||
public static final InternalOption<Void> DIRECT = new InternalOption<>();
|
||||
|
||||
public static final InternalOption<Integer> SENSITIVITY_HIGH = new InternalOption<>();
|
||||
public static final InternalOption<Integer> SENSITIVITY_MEDIUM = new InternalOption<>();
|
||||
public static final InternalOption<Integer> SENSITIVITY_LOW = new InternalOption<>();
|
||||
|
@ -57,21 +57,22 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable {
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) {
|
||||
String member = method.getName();
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
int parameterCount = method.getParameterCount();
|
||||
|
||||
// Handle Object and Annotation methods
|
||||
if (member.equals("equals") && paramTypes.length == 1 &&
|
||||
paramTypes[0] == Object.class)
|
||||
if (parameterCount == 1 && member == "equals" &&
|
||||
method.getParameterTypes()[0] == Object.class) {
|
||||
return equalsImpl(proxy, args[0]);
|
||||
if (paramTypes.length != 0)
|
||||
}
|
||||
if (parameterCount != 0) {
|
||||
throw new AssertionError("Too many parameters for an annotation method");
|
||||
}
|
||||
|
||||
switch(member) {
|
||||
case "toString":
|
||||
if (member == "toString") {
|
||||
return toStringImpl();
|
||||
case "hashCode":
|
||||
} else if (member == "hashCode") {
|
||||
return hashCodeImpl();
|
||||
case "annotationType":
|
||||
} else if (member == "annotationType") {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.*;
|
||||
@ -147,6 +148,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
"keystore.PKCS12.keyProtectionAlgorithm"
|
||||
};
|
||||
|
||||
private static final int MAX_ITERATION_COUNT = 5000000;
|
||||
private static final int PBE_ITERATION_COUNT = 50000; // default
|
||||
private static final int MAC_ITERATION_COUNT = 100000; // default
|
||||
private static final int SALT_LEN = 20;
|
||||
|
||||
// friendlyName, localKeyId, trustedKeyUsage
|
||||
private static final String[] CORE_ATTRIBUTES = {
|
||||
"1.2.840.113549.1.9.20",
|
||||
@ -192,8 +198,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
private static ObjectIdentifier[] AnyUsage;
|
||||
|
||||
private int counter = 0;
|
||||
private static final int iterationCount = 1024;
|
||||
private static final int SALT_LEN = 20;
|
||||
|
||||
// private key count
|
||||
// Note: This is a workaround to allow null localKeyID attribute
|
||||
@ -327,6 +331,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
byte[] encryptedKey;
|
||||
AlgorithmParameters algParams;
|
||||
ObjectIdentifier algOid;
|
||||
|
||||
try {
|
||||
// get the encrypted private key
|
||||
EncryptedPrivateKeyInfo encrInfo =
|
||||
@ -347,7 +352,24 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
throw uke;
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
PBEParameterSpec pbeSpec;
|
||||
int ic = 0;
|
||||
|
||||
if (algParams != null) {
|
||||
try {
|
||||
pbeSpec =
|
||||
algParams.getParameterSpec(PBEParameterSpec.class);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
throw new IOException("Invalid PBE algorithm parameters");
|
||||
}
|
||||
ic = pbeSpec.getIterationCount();
|
||||
|
||||
if (ic > MAX_ITERATION_COUNT) {
|
||||
throw new IOException("PBE iteration count too large");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] keyInfo;
|
||||
while (true) {
|
||||
try {
|
||||
@ -387,9 +409,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
key = kfac.generatePrivate(kspec);
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Retrieved a protected private key (" +
|
||||
key.getClass().getName() + ") at alias '" + alias +
|
||||
"'");
|
||||
debug.println("Retrieved a protected private key at alias" +
|
||||
" '" + alias + "' (" +
|
||||
new AlgorithmId(algOid).getName() +
|
||||
" iterations: " + ic + ")");
|
||||
}
|
||||
|
||||
// decode secret key
|
||||
@ -410,9 +433,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Retrieved a protected secret key (" +
|
||||
key.getClass().getName() + ") at alias '" + alias +
|
||||
"'");
|
||||
debug.println("Retrieved a protected secret key at alias " +
|
||||
"'" + alias + "' (" +
|
||||
new AlgorithmId(algOid).getName() +
|
||||
" iterations: " + ic + ")");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -590,9 +614,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
(key.getFormat().equals("PKCS8"))) {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Setting a protected private key (" +
|
||||
key.getClass().getName() + ") at alias '" + alias +
|
||||
"'");
|
||||
debug.println(
|
||||
"Setting a protected private key at alias '" +
|
||||
alias + "'");
|
||||
}
|
||||
|
||||
// Encrypt the private key
|
||||
@ -638,9 +662,8 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
encryptPrivateKey(pkcs8.toByteArray(), passwordProtection);
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Setting a protected secret key (" +
|
||||
key.getClass().getName() + ") at alias '" + alias +
|
||||
"'");
|
||||
debug.println("Setting a protected secret key at alias '" +
|
||||
alias + "'");
|
||||
}
|
||||
secretKeyCount++;
|
||||
entry = keyEntry;
|
||||
@ -761,19 +784,19 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
/*
|
||||
* Generate PBE Algorithm Parameters
|
||||
*/
|
||||
private AlgorithmParameters getAlgorithmParameters(String algorithm)
|
||||
private AlgorithmParameters getPBEAlgorithmParameters(String algorithm)
|
||||
throws IOException
|
||||
{
|
||||
AlgorithmParameters algParams = null;
|
||||
|
||||
// create PBE parameters from salt and iteration count
|
||||
PBEParameterSpec paramSpec =
|
||||
new PBEParameterSpec(getSalt(), iterationCount);
|
||||
new PBEParameterSpec(getSalt(), PBE_ITERATION_COUNT);
|
||||
try {
|
||||
algParams = AlgorithmParameters.getInstance(algorithm);
|
||||
algParams.init(paramSpec);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("getAlgorithmParameters failed: " +
|
||||
throw new IOException("getPBEAlgorithmParameters failed: " +
|
||||
e.getMessage(), e);
|
||||
}
|
||||
return algParams;
|
||||
@ -859,7 +882,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
algParams = AlgorithmParameters.getInstance(algorithm);
|
||||
algParams.init(algParamSpec);
|
||||
} else {
|
||||
algParams = getAlgorithmParameters(algorithm);
|
||||
algParams = getPBEAlgorithmParameters(algorithm);
|
||||
}
|
||||
} else {
|
||||
// Check default key protection algorithm for PKCS12 keystores
|
||||
@ -879,7 +902,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
if (algorithm == null || algorithm.isEmpty()) {
|
||||
algorithm = "PBEWithSHA1AndDESede";
|
||||
}
|
||||
algParams = getAlgorithmParameters(algorithm);
|
||||
algParams = getPBEAlgorithmParameters(algorithm);
|
||||
}
|
||||
|
||||
ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
|
||||
@ -1194,7 +1217,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Storing " + (privateKeyCount + secretKeyCount) +
|
||||
" protected key(s) in a PKCS#7 data content-type");
|
||||
" protected key(s) in a PKCS#7 data");
|
||||
}
|
||||
|
||||
byte[] safeContentData = createSafeContent();
|
||||
@ -1207,7 +1230,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Storing " + certificateCount +
|
||||
" certificate(s) in a PKCS#7 encryptedData content-type");
|
||||
" certificate(s) in a PKCS#7 encryptedData");
|
||||
}
|
||||
|
||||
byte[] encrData = createEncryptedData(password);
|
||||
@ -1478,7 +1501,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
// generate MAC (MAC key is generated within JCE)
|
||||
Mac m = Mac.getInstance("HmacPBESHA1");
|
||||
PBEParameterSpec params =
|
||||
new PBEParameterSpec(salt, iterationCount);
|
||||
new PBEParameterSpec(salt, MAC_ITERATION_COUNT);
|
||||
SecretKey key = getPBEKey(passwd);
|
||||
m.init(key, params);
|
||||
m.update(data);
|
||||
@ -1486,7 +1509,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
// encode as MacData
|
||||
MacData macData = new MacData(algName, macResult, salt,
|
||||
iterationCount);
|
||||
MAC_ITERATION_COUNT);
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
bytes.write(macData.getEncoded());
|
||||
mData = bytes.toByteArray();
|
||||
@ -1878,7 +1901,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
// create AlgorithmParameters
|
||||
AlgorithmParameters algParams =
|
||||
getAlgorithmParameters("PBEWithSHA1AndRC2_40");
|
||||
getPBEAlgorithmParameters("PBEWithSHA1AndRC2_40");
|
||||
DerOutputStream bytes = new DerOutputStream();
|
||||
AlgorithmId algId =
|
||||
new AlgorithmId(pbeWithSHAAnd40BitRC2CBC_OID, algParams);
|
||||
@ -1998,7 +2021,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
if (contentType.equals(ContentInfo.DATA_OID)) {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Loading PKCS#7 data content-type");
|
||||
debug.println("Loading PKCS#7 data");
|
||||
}
|
||||
|
||||
safeContentsData = safeContents.getData();
|
||||
@ -2007,15 +2030,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Warning: skipping PKCS#7 encryptedData" +
|
||||
" content-type - no password was supplied");
|
||||
" - no password was supplied");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Loading PKCS#7 encryptedData content-type");
|
||||
}
|
||||
|
||||
DerInputStream edi =
|
||||
safeContents.getContent().toDerInputStream();
|
||||
int edVersion = edi.getInteger();
|
||||
@ -2036,6 +2055,30 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
ObjectIdentifier algOid = in.getOID();
|
||||
AlgorithmParameters algParams = parseAlgParameters(algOid, in);
|
||||
|
||||
PBEParameterSpec pbeSpec;
|
||||
int ic = 0;
|
||||
|
||||
if (algParams != null) {
|
||||
try {
|
||||
pbeSpec =
|
||||
algParams.getParameterSpec(PBEParameterSpec.class);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
throw new IOException(
|
||||
"Invalid PBE algorithm parameters");
|
||||
}
|
||||
ic = pbeSpec.getIterationCount();
|
||||
|
||||
if (ic > MAX_ITERATION_COUNT) {
|
||||
throw new IOException("PBE iteration count too large");
|
||||
}
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Loading PKCS#7 encryptedData " +
|
||||
"(" + new AlgorithmId(algOid).getName() +
|
||||
" iterations: " + ic + ")");
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// Use JCE
|
||||
@ -2066,8 +2109,15 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
// The MacData is optional.
|
||||
if (password != null && s.available() > 0) {
|
||||
MacData macData = new MacData(s);
|
||||
try {
|
||||
MacData macData = new MacData(s);
|
||||
int ic = macData.getIterations();
|
||||
|
||||
try {
|
||||
if (ic > MAX_ITERATION_COUNT) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"MAC iteration count too large: " + ic);
|
||||
}
|
||||
|
||||
String algName =
|
||||
macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
|
||||
|
||||
@ -2077,8 +2127,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
// generate MAC (MAC key is created within JCE)
|
||||
Mac m = Mac.getInstance("HmacPBE" + algName);
|
||||
PBEParameterSpec params =
|
||||
new PBEParameterSpec(macData.getSalt(),
|
||||
macData.getIterations());
|
||||
new PBEParameterSpec(macData.getSalt(), ic);
|
||||
SecretKey key = getPBEKey(password);
|
||||
m.init(key, params);
|
||||
m.update(authSafeData);
|
||||
@ -2086,16 +2135,16 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Checking keystore integrity " +
|
||||
"(MAC algorithm: " + m.getAlgorithm() + ")");
|
||||
"(" + m.getAlgorithm() + " iterations: " + ic + ")");
|
||||
}
|
||||
|
||||
if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
|
||||
throw new UnrecoverableKeyException("Failed PKCS12" +
|
||||
" integrity checking");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Integrity check failed: " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -65,6 +65,7 @@ import sun.security.util.PropertyExpander;
|
||||
* This class is entirely deprecated.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("removal")
|
||||
public class AuthPolicyFile extends javax.security.auth.Policy {
|
||||
|
||||
static final ResourceBundle rb =
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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,6 +35,8 @@ import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
|
||||
import sun.security.jca.JCAUtil;
|
||||
import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
|
||||
import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
|
||||
|
||||
/**
|
||||
* This class generates DSA key parameters and public/private key
|
||||
@ -45,15 +47,14 @@ import sun.security.jca.JCAUtil;
|
||||
* @author Andreas Sterbenz
|
||||
*
|
||||
*/
|
||||
public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
implements java.security.interfaces.DSAKeyPairGenerator {
|
||||
class DSAKeyPairGenerator extends KeyPairGenerator {
|
||||
|
||||
/* Length for prime P and subPrime Q in bits */
|
||||
private int plen;
|
||||
private int qlen;
|
||||
|
||||
/* whether to force new parameters to be generated for each KeyPair */
|
||||
private boolean forceNewParameters;
|
||||
boolean forceNewParameters;
|
||||
|
||||
/* preset algorithm parameters. */
|
||||
private DSAParameterSpec params;
|
||||
@ -61,9 +62,9 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
/* The source of random bits to use */
|
||||
private SecureRandom random;
|
||||
|
||||
public DSAKeyPairGenerator() {
|
||||
DSAKeyPairGenerator(int defaultKeySize) {
|
||||
super("DSA");
|
||||
initialize(1024, null);
|
||||
initialize(defaultKeySize, null);
|
||||
}
|
||||
|
||||
private static void checkStrength(int sizeP, int sizeQ) {
|
||||
@ -84,61 +85,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
}
|
||||
|
||||
public void initialize(int modlen, SecureRandom random) {
|
||||
// generate new parameters when no precomputed ones available.
|
||||
initialize(modlen, true, random);
|
||||
this.forceNewParameters = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the DSA key pair generator. If <code>genParams</code>
|
||||
* is false, a set of pre-computed parameters is used.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(int modlen, boolean genParams, SecureRandom random)
|
||||
throws InvalidParameterException {
|
||||
|
||||
int subPrimeLen = -1;
|
||||
if (modlen <= 1024) {
|
||||
subPrimeLen = 160;
|
||||
} else if (modlen == 2048) {
|
||||
subPrimeLen = 224;
|
||||
} else if (modlen == 3072) {
|
||||
subPrimeLen = 256;
|
||||
}
|
||||
checkStrength(modlen, subPrimeLen);
|
||||
if (genParams) {
|
||||
params = null;
|
||||
} else {
|
||||
params = ParameterCache.getCachedDSAParameterSpec(modlen,
|
||||
subPrimeLen);
|
||||
if (params == null) {
|
||||
throw new InvalidParameterException
|
||||
("No precomputed parameters for requested modulus size "
|
||||
+ "available");
|
||||
}
|
||||
|
||||
}
|
||||
this.plen = modlen;
|
||||
this.qlen = subPrimeLen;
|
||||
this.random = random;
|
||||
this.forceNewParameters = genParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the DSA object using a DSA parameter object.
|
||||
*
|
||||
* @param params a fully initialized DSA parameter object.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(DSAParams params, SecureRandom random)
|
||||
throws InvalidParameterException {
|
||||
|
||||
if (params == null) {
|
||||
throw new InvalidParameterException("Params must not be null");
|
||||
}
|
||||
DSAParameterSpec spec = new DSAParameterSpec
|
||||
(params.getP(), params.getQ(), params.getG());
|
||||
initialize0(spec, random);
|
||||
init(modlen, random, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,10 +104,21 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Inappropriate parameter");
|
||||
}
|
||||
initialize0((DSAParameterSpec)params, random);
|
||||
init((DSAParameterSpec)params, random, false);
|
||||
}
|
||||
|
||||
private void initialize0(DSAParameterSpec params, SecureRandom random) {
|
||||
void init(int modlen, SecureRandom random, boolean forceNew) {
|
||||
int subPrimeLen = getDefDSASubprimeSize(modlen);
|
||||
checkStrength(modlen, subPrimeLen);
|
||||
this.plen = modlen;
|
||||
this.qlen = subPrimeLen;
|
||||
this.params = null;
|
||||
this.random = random;
|
||||
this.forceNewParameters = forceNew;
|
||||
}
|
||||
|
||||
void init(DSAParameterSpec params, SecureRandom random,
|
||||
boolean forceNew) {
|
||||
int sizeP = params.getP().bitLength();
|
||||
int sizeQ = params.getQ().bitLength();
|
||||
checkStrength(sizeP, sizeQ);
|
||||
@ -168,7 +126,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
this.qlen = sizeQ;
|
||||
this.params = params;
|
||||
this.random = random;
|
||||
this.forceNewParameters = false;
|
||||
this.forceNewParameters = forceNew;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,7 +155,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
return generateKeyPair(spec.getP(), spec.getQ(), spec.getG(), random);
|
||||
}
|
||||
|
||||
public KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
|
||||
private KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
|
||||
SecureRandom random) {
|
||||
|
||||
BigInteger x = generateX(random, q);
|
||||
@ -252,4 +210,55 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
|
||||
return y;
|
||||
}
|
||||
|
||||
public static final class Current extends DSAKeyPairGenerator {
|
||||
public Current() {
|
||||
super(DEF_DSA_KEY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Legacy extends DSAKeyPairGenerator
|
||||
implements java.security.interfaces.DSAKeyPairGenerator {
|
||||
|
||||
public Legacy() {
|
||||
super(1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the DSA key pair generator. If <code>genParams</code>
|
||||
* is false, a set of pre-computed parameters is used.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(int modlen, boolean genParams,
|
||||
SecureRandom random) throws InvalidParameterException {
|
||||
if (genParams) {
|
||||
super.init(modlen, random, true);
|
||||
} else {
|
||||
DSAParameterSpec cachedParams =
|
||||
ParameterCache.getCachedDSAParameterSpec(modlen,
|
||||
getDefDSASubprimeSize(modlen));
|
||||
if (cachedParams == null) {
|
||||
throw new InvalidParameterException
|
||||
("No precomputed parameters for requested modulus" +
|
||||
" size available");
|
||||
}
|
||||
super.init(cachedParams, random, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the DSA object using a DSA parameter object.
|
||||
*
|
||||
* @param params a fully initialized DSA parameter object.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(DSAParams params, SecureRandom random)
|
||||
throws InvalidParameterException {
|
||||
if (params == null) {
|
||||
throw new InvalidParameterException("Params must not be null");
|
||||
}
|
||||
DSAParameterSpec spec = new DSAParameterSpec
|
||||
(params.getP(), params.getQ(), params.getG());
|
||||
super.init(spec, random, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -34,15 +34,18 @@ import java.security.NoSuchProviderException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.ProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.DSAGenParameterSpec;
|
||||
|
||||
import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
|
||||
import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
|
||||
|
||||
|
||||
/**
|
||||
* This class generates parameters for the DSA algorithm. It uses a default
|
||||
* prime modulus size of 1024 bits, which can be overwritten during
|
||||
* initialization.
|
||||
* This class generates parameters for the DSA algorithm.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*
|
||||
@ -56,10 +59,6 @@ import java.security.spec.DSAGenParameterSpec;
|
||||
|
||||
public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
|
||||
|
||||
// the default parameters
|
||||
private static final DSAGenParameterSpec DEFAULTS =
|
||||
new DSAGenParameterSpec(1024, 160, 160);
|
||||
|
||||
// the length of prime P, subPrime Q, and seed in bits
|
||||
private int valueL = -1;
|
||||
private int valueN = -1;
|
||||
@ -80,18 +79,14 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
|
||||
*/
|
||||
@Override
|
||||
protected void engineInit(int strength, SecureRandom random) {
|
||||
if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
|
||||
this.valueN = 160;
|
||||
} else if (strength == 2048) {
|
||||
this.valueN = 224;
|
||||
} else if (strength == 3072) {
|
||||
this.valueN = 256;
|
||||
} else {
|
||||
if ((strength != 2048) && (strength != 3072) &&
|
||||
((strength < 512) || (strength > 1024) || (strength % 64 != 0))) {
|
||||
throw new InvalidParameterException(
|
||||
"Unexpected strength (size of prime): " + strength + ". " +
|
||||
"Prime size should be 512 - 1024, or 2048, 3072");
|
||||
"Unexpected strength (size of prime): " + strength +
|
||||
". Prime size should be 512-1024, 2048, or 3072");
|
||||
}
|
||||
this.valueL = strength;
|
||||
this.valueN = getDefDSASubprimeSize(strength);
|
||||
this.seedLen = valueN;
|
||||
this.random = random;
|
||||
}
|
||||
@ -110,7 +105,6 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
|
||||
@Override
|
||||
protected void engineInit(AlgorithmParameterSpec genParamSpec,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException {
|
||||
|
||||
if (!(genParamSpec instanceof DSAGenParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException("Invalid parameter");
|
||||
}
|
||||
@ -136,11 +130,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
|
||||
this.random = new SecureRandom();
|
||||
}
|
||||
if (valueL == -1) {
|
||||
try {
|
||||
engineInit(DEFAULTS, this.random);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should never happen
|
||||
}
|
||||
engineInit(DEF_DSA_KEY_SIZE, this.random);
|
||||
}
|
||||
BigInteger[] pAndQ = generatePandQ(this.random, valueL,
|
||||
valueN, seedLen);
|
||||
@ -206,13 +196,17 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
|
||||
int b = (valueL - 1) % outLen;
|
||||
byte[] seedBytes = new byte[seedLen/8];
|
||||
BigInteger twoSl = BigInteger.TWO.pow(seedLen);
|
||||
int primeCertainty = 80; // for 1024-bit prime P
|
||||
if (valueL == 2048) {
|
||||
int primeCertainty = -1;
|
||||
if (valueL <= 1024) {
|
||||
primeCertainty = 80;
|
||||
} else if (valueL == 2048) {
|
||||
primeCertainty = 112;
|
||||
} else if (valueL == 3072) {
|
||||
primeCertainty = 128;
|
||||
}
|
||||
|
||||
if (primeCertainty < 0) {
|
||||
throw new ProviderException("Invalid valueL: " + valueL);
|
||||
}
|
||||
BigInteger resultP, resultQ, seed = null;
|
||||
int counter;
|
||||
while (true) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
@ -29,6 +29,7 @@ import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.Map;
|
||||
import java.security.*;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* Defines the entries of the SUN provider.
|
||||
@ -74,6 +75,10 @@ import java.security.*;
|
||||
|
||||
final class SunEntries {
|
||||
|
||||
private static final boolean useLegacyDSA =
|
||||
Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
|
||||
("jdk.security.legacyDSAKeyPairGenerator"));
|
||||
|
||||
private SunEntries() {
|
||||
// empty
|
||||
}
|
||||
@ -174,8 +179,9 @@ final class SunEntries {
|
||||
/*
|
||||
* Key Pair Generator engines
|
||||
*/
|
||||
map.put("KeyPairGenerator.DSA",
|
||||
"sun.security.provider.DSAKeyPairGenerator");
|
||||
String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
|
||||
dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
|
||||
map.put("KeyPairGenerator.DSA", dsaKPGImplClass);
|
||||
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
|
||||
map.put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
|
||||
map.put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
|
||||
|
@ -119,7 +119,7 @@ public final class ResponderId {
|
||||
* When encoded in DER this object will use the byKey option, a
|
||||
* SHA-1 hash of the responder's public key.
|
||||
*
|
||||
* @param pubKey the the OCSP responder's public key
|
||||
* @param pubKey the OCSP responder's public key
|
||||
*
|
||||
* @throws IOException if the internal DER-encoding of the
|
||||
* {@code KeyIdentifier} fails.
|
||||
|
@ -94,7 +94,7 @@ public class SunCertPathBuilderException extends CertPathBuilderException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>SunCertPathBuilderException</code> withe the specified
|
||||
* Creates a <code>SunCertPathBuilderException</code> with the specified
|
||||
* detail message and adjacency list.
|
||||
*
|
||||
* @param msg the detail message
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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
|
||||
@ -32,6 +32,7 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
|
||||
import sun.security.jca.JCAUtil;
|
||||
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
|
||||
|
||||
/**
|
||||
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
|
||||
@ -55,7 +56,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
|
||||
public RSAKeyPairGenerator() {
|
||||
// initialize to default in case the app does not call initialize()
|
||||
initialize(2048, null);
|
||||
initialize(DEF_RSA_KEY_SIZE, null);
|
||||
}
|
||||
|
||||
// initialize the generator. See JCA doc
|
||||
|
@ -145,7 +145,7 @@ final class CertStatusReqItemV2 {
|
||||
* @return the encoded length of this {@code CertStatusReqItemV2}
|
||||
*/
|
||||
int length() {
|
||||
// The length is the the status type (1 byte) + the request length
|
||||
// The length is the status type (1 byte) + the request length
|
||||
// field (2 bytes) + the StatusRequest data length.
|
||||
return request.length() + 3;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ final class MAC extends Authenticator {
|
||||
* @param type record type
|
||||
* @param bb a ByteBuffer in which the position and limit
|
||||
* demarcate the data to be MAC'd.
|
||||
* @param isSimulated if true, simulate the the MAC computation
|
||||
* @param isSimulated if true, simulate the MAC computation
|
||||
*
|
||||
* @return the MAC result
|
||||
*/
|
||||
|
@ -333,7 +333,7 @@ final class TrustStoreManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the the KeyStore as described in the specified descriptor.
|
||||
* Load the KeyStore as described in the specified descriptor.
|
||||
*/
|
||||
private static KeyStore loadKeyStore(
|
||||
TrustStoreDescriptor descriptor) throws Exception {
|
||||
|
@ -26,6 +26,8 @@
|
||||
package sun.security.tools.keytool;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.CodeSigner;
|
||||
import java.security.CryptoPrimitive;
|
||||
import java.security.KeyStore;
|
||||
@ -72,6 +74,7 @@ import sun.security.pkcs10.PKCS10Attribute;
|
||||
import sun.security.provider.X509Factory;
|
||||
import sun.security.provider.certpath.ssl.SSLServerCertStore;
|
||||
import sun.security.util.Password;
|
||||
import sun.security.util.SecurityProviderConstants;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
@ -168,7 +171,12 @@ public final class Main {
|
||||
private List<String> ids = new ArrayList<>(); // used in GENCRL
|
||||
private List<String> v3ext = new ArrayList<>();
|
||||
|
||||
// Warnings on weak algorithms
|
||||
// In-place importkeystore is special.
|
||||
// A backup is needed, and no need to prompt for deststorepass.
|
||||
private boolean inplaceImport = false;
|
||||
private String inplaceBackupName = null;
|
||||
|
||||
// Warnings on weak algorithms etc
|
||||
private List<String> weakWarnings = new ArrayList<>();
|
||||
|
||||
private static final DisabledAlgorithmConstraints DISABLED_CHECK =
|
||||
@ -846,37 +854,52 @@ public final class Main {
|
||||
("New.password.must.be.at.least.6.characters"));
|
||||
}
|
||||
|
||||
// Set this before inplaceImport check so we can compare name.
|
||||
if (ksfname == null) {
|
||||
ksfname = System.getProperty("user.home") + File.separator
|
||||
+ ".keystore";
|
||||
}
|
||||
|
||||
KeyStore srcKeyStore = null;
|
||||
if (command == IMPORTKEYSTORE) {
|
||||
inplaceImport = inplaceImportCheck();
|
||||
if (inplaceImport) {
|
||||
// We load srckeystore first so we have srcstorePass that
|
||||
// can be assigned to storePass
|
||||
srcKeyStore = loadSourceKeyStore();
|
||||
if (storePass == null) {
|
||||
storePass = srcstorePass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if keystore exists.
|
||||
// If no keystore has been specified at the command line, try to use
|
||||
// the default, which is located in $HOME/.keystore.
|
||||
// If the command is "genkey", "identitydb", "import", or "printcert",
|
||||
// it is OK not to have a keystore.
|
||||
if (isKeyStoreRelated(command)) {
|
||||
if (ksfname == null) {
|
||||
ksfname = System.getProperty("user.home") + File.separator
|
||||
+ ".keystore";
|
||||
}
|
||||
|
||||
if (!nullStream) {
|
||||
try {
|
||||
ksfile = new File(ksfname);
|
||||
// Check if keystore file is empty
|
||||
if (ksfile.exists() && ksfile.length() == 0) {
|
||||
throw new Exception(rb.getString
|
||||
("Keystore.file.exists.but.is.empty.") + ksfname);
|
||||
}
|
||||
ksStream = new FileInputStream(ksfile);
|
||||
} catch (FileNotFoundException e) {
|
||||
if (command != GENKEYPAIR &&
|
||||
// DO NOT open the existing keystore if this is an in-place import.
|
||||
// The keystore should be created as brand new.
|
||||
if (isKeyStoreRelated(command) && !nullStream && !inplaceImport) {
|
||||
try {
|
||||
ksfile = new File(ksfname);
|
||||
// Check if keystore file is empty
|
||||
if (ksfile.exists() && ksfile.length() == 0) {
|
||||
throw new Exception(rb.getString
|
||||
("Keystore.file.exists.but.is.empty.") + ksfname);
|
||||
}
|
||||
ksStream = new FileInputStream(ksfile);
|
||||
} catch (FileNotFoundException e) {
|
||||
if (command != GENKEYPAIR &&
|
||||
command != GENSECKEY &&
|
||||
command != IDENTITYDB &&
|
||||
command != IMPORTCERT &&
|
||||
command != IMPORTPASS &&
|
||||
command != IMPORTKEYSTORE &&
|
||||
command != PRINTCRL) {
|
||||
throw new Exception(rb.getString
|
||||
("Keystore.file.does.not.exist.") + ksfname);
|
||||
}
|
||||
throw new Exception(rb.getString
|
||||
("Keystore.file.does.not.exist.") + ksfname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -900,7 +923,7 @@ public final class Main {
|
||||
// Create new keystore
|
||||
// Probe for keystore type when filename is available
|
||||
if (ksfile != null && ksStream != null && providerName == null &&
|
||||
hasStoretypeOption == false) {
|
||||
hasStoretypeOption == false && !inplaceImport) {
|
||||
keyStore = KeyStore.getInstance(ksfile, storePass);
|
||||
} else {
|
||||
if (providerName == null) {
|
||||
@ -930,7 +953,11 @@ public final class Main {
|
||||
* Null stream keystores are loaded later.
|
||||
*/
|
||||
if (!nullStream) {
|
||||
keyStore.load(ksStream, storePass);
|
||||
if (inplaceImport) {
|
||||
keyStore.load(null, storePass);
|
||||
} else {
|
||||
keyStore.load(ksStream, storePass);
|
||||
}
|
||||
if (ksStream != null) {
|
||||
ksStream.close();
|
||||
}
|
||||
@ -1167,7 +1194,11 @@ public final class Main {
|
||||
}
|
||||
}
|
||||
} else if (command == IMPORTKEYSTORE) {
|
||||
doImportKeyStore();
|
||||
// When not in-place import, srcKeyStore is not loaded yet.
|
||||
if (srcKeyStore == null) {
|
||||
srcKeyStore = loadSourceKeyStore();
|
||||
}
|
||||
doImportKeyStore(srcKeyStore);
|
||||
kssave = true;
|
||||
} else if (command == KEYCLONE) {
|
||||
keyPassNew = newPass;
|
||||
@ -1298,6 +1329,51 @@ public final class Main {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isKeyStoreRelated(command)
|
||||
&& !token && !nullStream && ksfname != null) {
|
||||
|
||||
// JKS storetype warning on the final result keystore
|
||||
File f = new File(ksfname);
|
||||
char[] pass = (storePassNew!=null) ? storePassNew : storePass;
|
||||
if (f.exists()) {
|
||||
// Probe for real type. A JKS can be loaded as PKCS12 because
|
||||
// DualFormat support, vice versa.
|
||||
keyStore = KeyStore.getInstance(f, pass);
|
||||
String realType = keyStore.getType();
|
||||
if (realType.equalsIgnoreCase("JKS")
|
||||
|| realType.equalsIgnoreCase("JCEKS")) {
|
||||
boolean allCerts = true;
|
||||
for (String a : Collections.list(keyStore.aliases())) {
|
||||
if (!keyStore.entryInstanceOf(
|
||||
a, TrustedCertificateEntry.class)) {
|
||||
allCerts = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Don't warn for "cacerts" style keystore.
|
||||
if (!allCerts) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("jks.storetype.warning"),
|
||||
realType, ksfname));
|
||||
}
|
||||
}
|
||||
if (inplaceImport) {
|
||||
String realSourceStoreType = KeyStore.getInstance(
|
||||
new File(inplaceBackupName), srcstorePass).getType();
|
||||
String format =
|
||||
realType.equalsIgnoreCase(realSourceStoreType) ?
|
||||
rb.getString("backup.keystore.warning") :
|
||||
rb.getString("migrate.keystore.warning");
|
||||
weakWarnings.add(
|
||||
String.format(format,
|
||||
srcksfname,
|
||||
realSourceStoreType,
|
||||
inplaceBackupName,
|
||||
realType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1742,9 +1818,12 @@ public final class Main {
|
||||
{
|
||||
if (keysize == -1) {
|
||||
if ("EC".equalsIgnoreCase(keyAlgName)) {
|
||||
keysize = 256;
|
||||
} else {
|
||||
keysize = 2048; // RSA and DSA
|
||||
keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
|
||||
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
|
||||
keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
|
||||
} else if ("DSA".equalsIgnoreCase(keyAlgName)) {
|
||||
// hardcode for now as DEF_DSA_KEY_SIZE is still 1024
|
||||
keysize = 2048; // SecurityProviderConstants.DEF_DSA_KEY_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1989,12 +2068,40 @@ public final class Main {
|
||||
}
|
||||
}
|
||||
|
||||
boolean inplaceImportCheck() throws Exception {
|
||||
if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
|
||||
KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (srcksfname != null) {
|
||||
File srcksfile = new File(srcksfname);
|
||||
if (srcksfile.exists() && srcksfile.length() == 0) {
|
||||
throw new Exception(rb.getString
|
||||
("Source.keystore.file.exists.but.is.empty.") +
|
||||
srcksfname);
|
||||
}
|
||||
if (srcksfile.getCanonicalFile()
|
||||
.equals(new File(ksfname).getCanonicalFile())) {
|
||||
return true;
|
||||
} else {
|
||||
// Informational, especially if destkeystore is not
|
||||
// provided, which default to ~/.keystore.
|
||||
System.err.println(String.format(rb.getString(
|
||||
"importing.keystore.status"), srcksfname, ksfname));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
throw new Exception(rb.getString
|
||||
("Please.specify.srckeystore"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the srckeystore from a stream, used in -importkeystore
|
||||
* @return the src KeyStore
|
||||
*/
|
||||
KeyStore loadSourceKeyStore() throws Exception {
|
||||
boolean isPkcs11 = false;
|
||||
|
||||
InputStream is = null;
|
||||
File srcksfile = null;
|
||||
@ -2007,20 +2114,9 @@ public final class Main {
|
||||
System.err.println();
|
||||
tinyHelp();
|
||||
}
|
||||
isPkcs11 = true;
|
||||
} else {
|
||||
if (srcksfname != null) {
|
||||
srcksfile = new File(srcksfname);
|
||||
if (srcksfile.exists() && srcksfile.length() == 0) {
|
||||
throw new Exception(rb.getString
|
||||
("Source.keystore.file.exists.but.is.empty.") +
|
||||
srcksfname);
|
||||
}
|
||||
is = new FileInputStream(srcksfile);
|
||||
} else {
|
||||
throw new Exception(rb.getString
|
||||
("Please.specify.srckeystore"));
|
||||
}
|
||||
srcksfile = new File(srcksfname);
|
||||
is = new FileInputStream(srcksfile);
|
||||
}
|
||||
|
||||
KeyStore store;
|
||||
@ -2087,17 +2183,32 @@ public final class Main {
|
||||
* keep alias unchanged if no name conflict, otherwise, prompt.
|
||||
* keep keypass unchanged for keys
|
||||
*/
|
||||
private void doImportKeyStore() throws Exception {
|
||||
private void doImportKeyStore(KeyStore srcKS) throws Exception {
|
||||
|
||||
if (alias != null) {
|
||||
doImportKeyStoreSingle(loadSourceKeyStore(), alias);
|
||||
doImportKeyStoreSingle(srcKS, alias);
|
||||
} else {
|
||||
if (dest != null || srckeyPass != null) {
|
||||
throw new Exception(rb.getString(
|
||||
"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified"));
|
||||
}
|
||||
doImportKeyStoreAll(loadSourceKeyStore());
|
||||
doImportKeyStoreAll(srcKS);
|
||||
}
|
||||
|
||||
if (inplaceImport) {
|
||||
// Backup to file.old or file.old2...
|
||||
// The keystore is not rewritten yet now.
|
||||
for (int n = 1; /* forever */; n++) {
|
||||
inplaceBackupName = srcksfname + ".old" + (n == 1 ? "" : n);
|
||||
File bkFile = new File(inplaceBackupName);
|
||||
if (!bkFile.exists()) {
|
||||
Files.copy(Paths.get(srcksfname), bkFile.toPath());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Information display rule of -importkeystore
|
||||
* 1. inside single, shows failure
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -471,6 +471,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{"verified.by.s.in.s.weak", "Verified by %s in %s with a %s"},
|
||||
{"whose.sigalg.risk", "%s uses the %s signature algorithm which is considered a security risk."},
|
||||
{"whose.key.risk", "%s uses a %s which is considered a security risk."},
|
||||
{"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."},
|
||||
{"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
|
||||
{"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},
|
||||
{"importing.keystore.status", "Importing keystore %1$s to %2$s..."},
|
||||
};
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ import java.util.Arrays;
|
||||
public class IOUtils {
|
||||
|
||||
/**
|
||||
* Read up to <code>length</code> of bytes from <code>in</code>
|
||||
* Read up to {@code length} of bytes from {@code in}
|
||||
* until EOF is detected.
|
||||
* @param is input stream, must not be null
|
||||
* @param length number of bytes to read
|
||||
@ -78,4 +78,22 @@ public class IOUtils {
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read {@code length} of bytes from {@code in}. An exception is
|
||||
* thrown if there are not enough bytes in the stream.
|
||||
*
|
||||
* @param is input stream, must not be null
|
||||
* @param length number of bytes to read, must not be negative
|
||||
* @return bytes read
|
||||
* @throws IOException if any IO error or a premature EOF is detected, or
|
||||
* if {@code length} is negative since this length is usually also
|
||||
* read from {@code is}.
|
||||
*/
|
||||
public static byte[] readNBytes(InputStream is, int length) throws IOException {
|
||||
if (length < 0) {
|
||||
throw new IOException("length cannot be negative: " + length);
|
||||
}
|
||||
return readFully(is, length, true);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
@ -111,7 +111,11 @@ class ObjectIdentifier implements Serializable
|
||||
is.defaultReadObject();
|
||||
|
||||
if (encoding == null) { // from an old version
|
||||
init((int[])components, componentLen);
|
||||
int[] comp = (int[])components;
|
||||
if (componentLen > comp.length) {
|
||||
componentLen = comp.length;
|
||||
}
|
||||
init(comp, componentLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user