diff --git a/closed/GensrcJ9JCL.gmk b/closed/GensrcJ9JCL.gmk index 19629e8ebfc..eaded1a21df 100644 --- a/closed/GensrcJ9JCL.gmk +++ b/closed/GensrcJ9JCL.gmk @@ -60,7 +60,7 @@ $(J9JCL_SOURCES_DONEFILE) : \ @$(MKDIR) -p $(J9TOOLS_DIR) $(MAKE) $(MAKE_ARGS) -C $(OPENJ9_TOPDIR)/sourcetools -f buildj9tools.mk \ BOOT_JDK=$(BOOT_JDK) \ - DEST_DIR=$(call FixPath,$(J9TOOLS_DIR)) \ + DEST_DIR=$(call MixedPath,$(J9TOOLS_DIR)) \ JAVA_HOME=$(BOOT_JDK) \ preprocessor @$(ECHO) Generating J9JCL sources diff --git a/closed/JPP.gmk b/closed/JPP.gmk index 6790e844fa1..4f28bc94081 100644 --- a/closed/JPP.gmk +++ b/closed/JPP.gmk @@ -36,28 +36,17 @@ endif # OPENJ9_ENABLE_OPENJDK_METHODHANDLES # $3 - destination subdirectory # $4 - more options (optional) define RunJPP - @$(ECHO) $(BOOT_JDK)/bin/java \ - -cp "$(call FixPath,$(JPP_JAR))" \ + $(call EchoAndRun, $(BOOT_JDK)/bin/java \ + -cp "$(call MixedPath,$(JPP_JAR))" \ -Dfile.encoding=US-ASCII \ com.ibm.jpp.commandline.CommandlineBuilder \ -verdict \ -config $1 \ - -baseDir "$(call FixPath,$(dir $2))" \ + -baseDir "$(call MixedPath,$(dir $2))" \ -srcRoot $(notdir $2)/ \ - -xml "$(call FixPath,$(OPENJ9_TOPDIR)/jcl/jpp_configuration.xml)" \ - -dest "$(call FixPath,$(SUPPORT_OUTPUTDIR)$(strip $3))" \ + -xml "$(call MixedPath,$(OPENJ9_TOPDIR)/jcl/jpp_configuration.xml)" \ + -dest "$(call MixedPath,$(SUPPORT_OUTPUTDIR)$(strip $3))" \ -tag:define "$(subst $(SPACE),;,$(sort $(JPP_TAGS)))" \ - $4 - @$(BOOT_JDK)/bin/java \ - -cp "$(call FixPath,$(JPP_JAR))" \ - -Dfile.encoding=US-ASCII \ - com.ibm.jpp.commandline.CommandlineBuilder \ - -verdict \ - -config $1 \ - -baseDir "$(call FixPath,$(dir $2))" \ - -srcRoot $(notdir $2)/ \ - -xml "$(call FixPath,$(OPENJ9_TOPDIR)/jcl/jpp_configuration.xml)" \ - -dest "$(call FixPath,$(SUPPORT_OUTPUTDIR)$(strip $3))" \ - -tag:define "$(subst $(SPACE),;,$(sort $(JPP_TAGS)))" \ - $4 + $4 \ + ) endef # RunJPP diff --git a/closed/OpenJ9.gmk b/closed/OpenJ9.gmk index f6ba0aa2ae5..0276b8bed99 100644 --- a/closed/OpenJ9.gmk +++ b/closed/OpenJ9.gmk @@ -27,6 +27,7 @@ ifeq (,$(wildcard $(SPEC))) endif include $(SPEC) include $(TOPDIR)/make/common/MakeBase.gmk +include $(TOPDIR)/closed/JPP.gmk ifeq (,$(BUILD_ID)) BUILD_ID := 000000 @@ -314,8 +315,6 @@ $(foreach file, \ $(notdir $(wildcard $(OPENJ9_TOPDIR)/buildspecs/*)), \ $(eval $(call openj9_stage_buildspec_file,$(file)))) -J9TOOLS_DIR := $(SUPPORT_OUTPUTDIR)/j9tools - stage-j9 : @$(ECHO) Staging OpenJ9 runtime in $(OUTPUTDIR)/vm $(call openj9_copy_tree,$(OUTPUTDIR)/vm,$(OPENJ9_TOPDIR)/runtime) @@ -480,13 +479,13 @@ run-preprocessors-j9 : stage-j9 +BOOT_JDK=$(BOOT_JDK) $(EXPORT_COMPILER_ENV_VARS) OPENJDK_VERSION_NUMBER_FOUR_POSITIONS=$(VERSION_NUMBER_FOUR_POSITIONS) \ $(MAKE) $(MAKE_ARGS) -C $(OUTPUTDIR)/vm -f $(OPENJ9_TOPDIR)/runtime/buildtools.mk \ BUILD_ID=$(BUILD_ID) \ - DEST_DIR=$(call FixPath,$(J9TOOLS_DIR)) \ + DEST_DIR=$(call MixedPath,$(J9TOOLS_DIR)) \ EXTRA_CONFIGURE_ARGS=$(OMR_EXTRA_CONFIGURE_ARGS) \ FREEMARKER_JAR="$(FREEMARKER_JAR)" \ J9VM_SHA=$(OPENJ9_SHA) \ JAVA_HOME=$(BOOT_JDK) \ OMR_DIR=$(OUTPUTDIR)/vm/omr \ - SOURCETOOLS_DIR=$(call FixPath,$(OPENJ9_TOPDIR))/sourcetools \ + SOURCETOOLS_DIR=$(call MixedPath,$(OPENJ9_TOPDIR))/sourcetools \ SPEC=$(OPENJ9_BUILDSPEC) \ UMA_OPTIONS_EXTRA="-buildDate $(shell date +'%Y%m%d')" \ VERSION_MAJOR=$(VERSION_FEATURE) \ diff --git a/closed/custom/common/MakeBase.gmk b/closed/custom/common/MakeBase.gmk new file mode 100644 index 00000000000..bc55724eefe --- /dev/null +++ b/closed/custom/common/MakeBase.gmk @@ -0,0 +1,34 @@ +# =========================================================================== +# (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved +# =========================================================================== +# 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. +# +# IBM designates this particular file as subject to the "Classpath" exception +# as provided by IBM 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, see . +# =========================================================================== + +# Echo a command and then execute it. +# $1 - the command +define EchoAndRun + @ $(ECHO) $1 + @ $1 +endef + +# On Windows, FixPath yields backslashes which can cause problems, so +# we use PATHTOOL instead for tools (like java) that support both. +ifeq ($(call isTargetOs, windows), true) + MixedPath = $(shell $(PATHTOOL) -m $1) +else + MixedPath = $1 +endif diff --git a/closed/openjdk-tag.gmk b/closed/openjdk-tag.gmk index 071211ea481..06bac66d77e 100644 --- a/closed/openjdk-tag.gmk +++ b/closed/openjdk-tag.gmk @@ -1 +1 @@ -OPENJDK_TAG := jdk-11.0.20+7 +OPENJDK_TAG := jdk-11.0.20+8 diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers index 0ddf9b29c58..f6618777ecf 100644 --- a/make/autoconf/version-numbers +++ b/make/autoconf/version-numbers @@ -37,7 +37,7 @@ DEFAULT_VERSION_DATE=2023-07-18 DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="10 11" -DEFAULT_PROMOTED_VERSION_PRE=ea +DEFAULT_PROMOTED_VERSION_PRE= LAUNCHER_NAME=openjdk PRODUCT_NAME=OpenJDK diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java index c902a53d950..cb7e308e0d7 100644 --- a/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/src/java.base/share/classes/java/util/jar/JarFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -153,8 +153,6 @@ class JarFile extends ZipFile { private static final boolean MULTI_RELEASE_ENABLED; private static final boolean MULTI_RELEASE_FORCED; private static final ThreadLocal isInitializing = new ThreadLocal<>(); - // The maximum size of array to allocate. Some VMs reserve some header words in an array. - private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private SoftReference manRef; private JarEntry manEntry; @@ -807,8 +805,11 @@ private void initializeVerifier() { private byte[] getBytes(ZipEntry ze) throws IOException { try (InputStream is = super.getInputStream(ze)) { long uncompressedSize = ze.getSize(); - if (uncompressedSize > MAX_ARRAY_SIZE) { - throw new IOException("Unsupported size: " + uncompressedSize); + if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) { + throw new IOException("Unsupported size: " + uncompressedSize + + " for JarEntry " + ze.getName() + + ". Allowed max size: " + + SignatureFileVerifier.MAX_SIG_FILE_SIZE + " bytes"); } int len = (int)uncompressedSize; int bytesRead; diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 4e90503dd1b..85da9318815 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -66,6 +66,8 @@ import jdk.internal.ref.CleanerFactory; import jdk.internal.vm.annotation.Stable; import sun.nio.cs.UTF_8; +import sun.security.action.GetBooleanAction; +import java.security.AccessController; import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipUtils.*; @@ -117,6 +119,13 @@ class ZipFile implements ZipConstants, Closeable { */ public static final int OPEN_READ = 0x1; + /** + * Flag which specifies whether the validation of the Zip64 extra + * fields should be disabled + */ + private static final boolean disableZip64ExtraFieldValidation = + AccessController.doPrivileged + (new GetBooleanAction("jdk.util.zip.disableZip64ExtraFieldValidation")); /** * Mode flag to open a zip file and mark it for deletion. The file will be * deleted some time between the moment that it is opened and the moment @@ -1211,6 +1220,119 @@ private int addEntry(int index, int hash, int next, int pos) { entries[index++] = pos; return index; } + + /** + * Validate the Zip64 Extra block fields + * @param startingOffset Extra Field starting offset within the CEN + * @param extraFieldLen Length of this Extra field + * @throws ZipException If an error occurs validating the Zip64 Extra + * block + */ + private void checkExtraFields(int cenPos, int startingOffset, + int extraFieldLen) throws ZipException { + // Extra field Length cannot exceed 65,535 bytes per the PKWare + // APP.note 4.4.11 + if (extraFieldLen > 0xFFFF) { + zerror("invalid extra field length"); + } + // CEN Offset where this Extra field ends + int extraEndOffset = startingOffset + extraFieldLen; + if (extraEndOffset > cen.length) { + zerror("Invalid CEN header (extra data field size too long)"); + } + int currentOffset = startingOffset; + while (currentOffset < extraEndOffset) { + int tag = get16(cen, currentOffset); + currentOffset += Short.BYTES; + + int tagBlockSize = get16(cen, currentOffset); + int tagBlockEndingOffset = currentOffset + tagBlockSize; + + // The ending offset for this tag block should not go past the + // offset for the end of the extra field + if (tagBlockEndingOffset > extraEndOffset) { + zerror("Invalid CEN header (invalid zip64 extra data field size)"); + } + currentOffset += Short.BYTES; + + if (tag == ZIP64_EXTID) { + // Get the compressed size; + long csize = CENSIZ(cen, cenPos); + // Get the uncompressed size; + long size = CENLEN(cen, cenPos); + checkZip64ExtraFieldValues(currentOffset, tagBlockSize, + csize, size); + } + currentOffset += tagBlockSize; + } + } + + /** + * Validate the Zip64 Extended Information Extra Field (0x0001) block + * size and that the uncompressed size and compressed size field + * values are not negative. + * Note: As we do not use the LOC offset or Starting disk number + * field value we will not validate them + * @param off the starting offset for the Zip64 field value + * @param blockSize the size of the Zip64 Extended Extra Field + * @param csize CEN header compressed size value + * @param size CEN header uncompressed size value + * @throws ZipException if an error occurs + */ + private void checkZip64ExtraFieldValues(int off, int blockSize, long csize, + long size) + throws ZipException { + byte[] cen = this.cen; + // Validate the Zip64 Extended Information Extra Field (0x0001) + // length. + if (!isZip64ExtBlockSizeValid(blockSize)) { + zerror("Invalid CEN header (invalid zip64 extra data field size)"); + } + // Check the uncompressed size is not negative + // Note we do not need to check blockSize is >= 8 as + // we know its length is at least 8 from the call to + // isZip64ExtBlockSizeValid() + if ((size == ZIP64_MAGICVAL)) { + if(get64(cen, off) < 0) { + zerror("Invalid zip64 extra block size value"); + } + } + // Check the compressed size is not negative + if ((csize == ZIP64_MAGICVAL) && (blockSize >= 16)) { + if (get64(cen, off + 8) < 0) { + zerror("Invalid zip64 extra block compressed size value"); + } + } + } + + /** + * Validate the size and contents of a Zip64 extended information field + * The order of the Zip64 fields is fixed, but the fields MUST + * only appear if the corresponding LOC or CEN field is set to 0xFFFF: + * or 0xFFFFFFFF: + * Uncompressed Size - 8 bytes + * Compressed Size - 8 bytes + * LOC Header offset - 8 bytes + * Disk Start Number - 4 bytes + * See PKWare APP.Note Section 4.5.3 for more details + * + * @param blockSize the Zip64 Extended Information Extra Field size + * @return true if the extra block size is valid; false otherwise + */ + private static boolean isZip64ExtBlockSizeValid(int blockSize) { + /* + * As the fields must appear in order, the block size indicates which + * fields to expect: + * 8 - uncompressed size + * 16 - uncompressed size, compressed size + * 24 - uncompressed size, compressed sise, LOC Header offset + * 28 - uncompressed size, compressed sise, LOC Header offset, + * and Disk start number + */ + int i = blockSize; + return i == 8 || i == 16 || i == 24 || i == 28 ? true : false; + } + private int getEntryHash(int index) { return entries[index]; } private int getEntryNext(int index) { return entries[index + 1]; } private int getEntryPos(int index) { return entries[index + 2]; } @@ -1571,6 +1693,13 @@ private void initCEN(int knownTotal, ZipCoder zc) throws IOException { } else { checkEncoding(zc, cen, pos + CENHDR, nlen); } + if (elen > 0 && !disableZip64ExtraFieldValidation) { + long extraStartingOffset = pos + CENHDR + nlen; + if ((int)extraStartingOffset != extraStartingOffset) { + zerror("invalid CEN header (bad extra offset)"); + } + checkExtraFields(pos, (int)extraStartingOffset, elen); + } // Record the CEN offset and the name hash in our hash cell. hash = hashN(cen, pos + CENHDR, nlen); hsh = (hash & 0x7fffffff) % tablelen; diff --git a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java index 9981bdd5a2b..cb477fc1340 100644 --- a/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java +++ b/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -50,6 +50,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; +import sun.security.action.GetIntegerAction; import sun.security.jca.Providers; import sun.security.pkcs.PKCS7; import sun.security.pkcs.SignerInfo; @@ -95,6 +96,12 @@ public class SignatureFileVerifier { /** ConstraintsParameters for checking disabled algorithms */ private JarConstraintsParameters params; + // the maximum allowed size in bytes for the signature-related files + public static final int MAX_SIG_FILE_SIZE = initializeMaxSigFileSize(); + + // The maximum size of array to allocate. Some VMs reserve some header words in an array. + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** * Create the named SignatureFileVerifier. * @@ -838,4 +845,24 @@ void updateSigners(CodeSigner[] newSigners, signerCache.add(cachedSigners); signers.put(name, cachedSigners); } + + private static int initializeMaxSigFileSize() { + /* + * System property "jdk.jar.maxSignatureFileSize" used to configure + * the maximum allowed number of bytes for the signature-related files + * in a JAR file. + */ + Integer tmp = GetIntegerAction.privilegedGetProperty( + "jdk.jar.maxSignatureFileSize", 8000000); + if (tmp < 0 || tmp > MAX_ARRAY_SIZE) { + if (debug != null) { + debug.println("Default signature file size 8000000 bytes " + + "is used as the specified size for the " + + "jdk.jar.maxSignatureFileSize system property " + + "is out of range: " + tmp); + } + tmp = 8000000; + } + return tmp; + } } diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index aec184b2772..30751aa7a9e 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -976,7 +976,8 @@ jdk.tls.legacyAlgorithms= \ # Note: This property is currently used by OpenJDK's JSSE implementation. It # is not guaranteed to be examined and used by other implementations. # -jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37 +jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37, \ + ChaCha20-Poly1305 KeyUpdate 2^37 # # Cryptographic Jurisdiction Policy defaults diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java b/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java index 3a7eddd2524..9adbc2747f5 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java @@ -74,10 +74,6 @@ static Path fromUri(UnixFileSystem fs, URI uri) { int pos = 0; while (pos < len) { char c = p.charAt(pos++); - if ((c == '/') && (pos < len) && (p.charAt(pos) == '/')) { - // skip redundant slashes - continue; - } byte b; if (c == '%') { assert (pos+2) <= len; @@ -91,6 +87,10 @@ static Path fromUri(UnixFileSystem fs, URI uri) { throw new IllegalArgumentException("Bad escape"); b = (byte)c; } + if (b == '/' && rlen > 0 && result[rlen-1] == '/') { + // skip redundant slashes + continue; + } result[rlen++] = b; } if (rlen != result.length) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m index 2c991a2fc2f..328cdc6cc22 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTStrike.m @@ -102,7 +102,7 @@ + (AWTStrike *) awtStrikeForFont:(AWTFont *)awtFont #define AWT_FONT_CLEANUP_FINISH \ if (_fontThrowJavaException == YES) { \ char s[512]; \ - sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \ + snprintf(s, sizeof(s), "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \ JNU_ThrowByName(env, "java/lang/RuntimeException", s); \ } diff --git a/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp b/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp index ed2de311c22..5f868f6e408 100644 --- a/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp +++ b/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp @@ -635,7 +635,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) { if (channelName == NULL) { return; } - sprintf(channelName, "Ch %d", ch); + snprintf(channelName, 16, "Ch %d", ch); } void* jControls[2]; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java index 02150052124..9616e8eea78 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java @@ -588,6 +588,18 @@ public void load(InputStream input, Class resourceBase) throws * new URL(synthFile, path). Refer to * Synth File Format for more * information. + *

+ * Whilst this API may be safe for loading local resources that are + * delivered with a {@code LookAndFeel} or application, and so have an + * equal level of trust with application code, using it to load from + * remote resources, particularly any which may have a lower level of + * trust, is strongly discouraged. + * The alternative mechanisms to load styles from an {@code InputStream} + * {@linkplain #load(InputStream, Class)} + * using resources co-located with the application or by providing a + * {@code SynthStyleFactory} to + * {@linkplain #setStyleFactory setStyleFactory(SynthStyleFactory)} + * are preferred. * * @param url the URL to load the set of * SynthStyle from diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html b/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html index 35e16e2076e..956554702c2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html @@ -70,6 +70,8 @@

File Format

This example loads the look and feel from an input stream, using the specified class as the resource base to resolve paths. +

+

It is also possible to load a look and feel from an arbitrary URL as in the following example.

@@ -94,6 +96,11 @@

File Format

  • Remote JAR file, e.g. jar:http://host/synth-laf.jar!/laf.xml
  • +

    Note: Synth's file format allows for the definition of code to be executed. + Loading any code from a remote location should be used only + with extreme caution from a trusted source over a secure connection. + It is strongly discouraged for an application or a LookAndFeel to do so. +

    While the DTD for synth is specified, the parser is not validating. Parsing will fail only if a necessary attribute is not diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java index 1ebcfca9f62..364c695f0b2 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java @@ -44,6 +44,7 @@ import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.ResponseInfo; import java.net.http.HttpResponse.BodySubscriber; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import jdk.internal.net.http.ResponseSubscribers.PathSubscriber; @@ -200,16 +201,120 @@ private FileDownloadBodyHandler(Path directory, static final String DISPOSITION_TYPE = "attachment;"; /** The "filename" parameter. */ - static final Pattern FILENAME = Pattern.compile("filename\\s*=", CASE_INSENSITIVE); + static final Pattern FILENAME = Pattern.compile("filename\\s*=\\s*", CASE_INSENSITIVE); static final List PROHIBITED = List.of(".", "..", "", "~" , "|"); + // Characters disallowed in token values + + static final Set NOT_ALLOWED_IN_TOKEN = Set.of( + '(', ')', '<', '>', '@', + ',', ';', ':', '\\', '"', + '/', '[', ']', '?', '=', + '{', '}', ' ', '\t'); + + static boolean allowedInToken(char c) { + if (NOT_ALLOWED_IN_TOKEN.contains(c)) + return false; + // exclude CTL chars <= 31, == 127, or anything >= 128 + return isTokenText(c); + } + static final UncheckedIOException unchecked(ResponseInfo rinfo, String msg) { String s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); return new UncheckedIOException(new IOException(s)); } + static final UncheckedIOException unchecked(String msg) { + return new UncheckedIOException(new IOException(msg)); + } + + // Process a "filename=" parameter, which is either a "token" + // or a "quoted string". If a token, it is terminated by a + // semicolon or the end of the string. + // If a quoted string (surrounded by "" chars then the closing " + // terminates the name. + // quoted strings may contain quoted-pairs (eg embedded " chars) + + static String processFilename(String src) throws UncheckedIOException { + if ("".equals(src)) + return src; + if (src.charAt(0) == '\"') { + return processQuotedString(src.substring(1)); + } else { + return processToken(src); + } + } + + static boolean isTokenText(char c) throws UncheckedIOException { + return c > 31 && c < 127; + } + + static boolean isQuotedStringText(char c) throws UncheckedIOException { + return c > 31; + } + + static String processQuotedString(String src) throws UncheckedIOException { + boolean inqpair = false; + int len = src.length(); + StringBuilder sb = new StringBuilder(); + + for (int i=0; i apply(ResponseInfo responseInfo) { String dispoHeader = responseInfo.headers().firstValue("Content-Disposition") @@ -227,13 +332,7 @@ public BodySubscriber apply(ResponseInfo responseInfo) { } int n = matcher.end(); - int semi = dispoHeader.substring(n).indexOf(";"); - String filenameParam; - if (semi < 0) { - filenameParam = dispoHeader.substring(n); - } else { - filenameParam = dispoHeader.substring(n, n + semi); - } + String filenameParam = processFilename(dispoHeader.substring(n)); // strip all but the last path segment int x = filenameParam.lastIndexOf("/"); @@ -247,19 +346,6 @@ public BodySubscriber apply(ResponseInfo responseInfo) { filenameParam = filenameParam.trim(); - if (filenameParam.startsWith("\"")) { // quoted-string - if (!filenameParam.endsWith("\"") || filenameParam.length() == 1) { - throw unchecked(responseInfo, - "Badly quoted Content-Disposition filename parameter"); - } - filenameParam = filenameParam.substring(1, filenameParam.length() -1 ); - } else { // token, - if (filenameParam.contains(" ")) { // space disallowed - throw unchecked(responseInfo, - "unquoted space in Content-Disposition filename parameter"); - } - } - if (PROHIBITED.contains(filenameParam)) { throw unchecked(responseInfo, "Prohibited Content-Disposition filename parameter:" diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java index 950f0ed2474..63ca048481f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java @@ -342,6 +342,24 @@ static SecretKey secretKey(Session session, long keyID, String algorithm, new CK_ATTRIBUTE(CKA_SENSITIVE), new CK_ATTRIBUTE(CKA_EXTRACTABLE), }); + + if ((SunPKCS11.mysunpkcs11 != null) && !SunPKCS11.isExportWrapKey.get() + && ("AES".equals(algorithm) || "TripleDES".equals(algorithm)) + ) { + if (attributes[0].getBoolean() || attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) { + try { + byte[] key = SunPKCS11.mysunpkcs11.exportKey(session.id(), attributes, keyID); + SecretKey secretKey = new SecretKeySpec(key, algorithm); + return new P11SecretKeyFIPS(session, keyID, algorithm, keyLength, attributes, secretKey); + } catch (PKCS11Exception e) { + // Attempt failed, create a P11SecretKey object. + if (debug != null) { + debug.println("Attempt failed, creating a SecretKey object for " + algorithm); + } + } + } + } + return new P11SecretKey(session, keyID, algorithm, keyLength, attributes); } @@ -494,6 +512,29 @@ byte[] getEncodedInternal() { } } + private static final class P11SecretKeyFIPS extends P11Key implements SecretKey { + + private static final long serialVersionUID = -9186806495402041696L; + private final SecretKey key; + + P11SecretKeyFIPS(Session session, long keyID, String algorithm, + int keyLength, CK_ATTRIBUTE[] attributes, SecretKey key) { + super(SECRET, session, keyID, algorithm, keyLength, attributes); + this.key = key; + } + + @Override + public String getFormat() { + return "RAW"; + } + + @Override + byte[] getEncodedInternal() { + return key.getEncoded(); + } + + } + private static class P11SecretKey extends P11Key implements SecretKey { private static final long serialVersionUID = -7828241727014329084L; private volatile byte[] encoded; diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index 2176ee12fe3..de77baf91f4 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -118,6 +118,8 @@ public final class SunPKCS11 extends AuthProvider { // FIPS mode. static SunPKCS11 mysunpkcs11; + static final ThreadLocal isExportWrapKey = ThreadLocal.withInitial(() -> Boolean.FALSE); + Token getToken() { return token; } @@ -503,10 +505,12 @@ byte[] exportKey(long hSession, CK_ATTRIBUTE[] attributes, long keyId) throws PK try { long genKeyId = token.p11.C_GenerateKey(wrapKeyGenSession.id(), new CK_MECHANISM(CKM_AES_KEY_GEN), wrapKeyAttributes); + isExportWrapKey.set(Boolean.TRUE); wrapKey = (P11Key)P11Key.secretKey(wrapKeyGenSession, genKeyId, "AES", 256 >> 3, null); } catch (PKCS11Exception e) { throw e; } finally { + isExportWrapKey.set(Boolean.FALSE); token.releaseSession(wrapKeyGenSession); } diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index c85b122f1ef..087ff688a4c 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, 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 @@ -711,6 +711,13 @@ void verifyJar(String jarName) && SignatureFileVerifier.isBlockOrSF(name)) { String alias = name.substring(name.lastIndexOf('/') + 1, name.lastIndexOf('.')); + long uncompressedSize = je.getSize(); + if (uncompressedSize > SignatureFileVerifier.MAX_SIG_FILE_SIZE) { + unparsableSignatures.putIfAbsent(alias, String.format( + rb.getString("history.unparsable"), name)); + continue; + } + try { if (name.endsWith(".SF")) { Manifest sf = new Manifest(is); diff --git a/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java b/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java index d06d587f277..61ddf1759ef 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java @@ -79,7 +79,8 @@ public class JdiInitiator { * @param timeout the start-up time-out in milliseconds. If zero or negative, * will not wait thus will timeout immediately if not already started. * @param customConnectorArgs custom arguments passed to the connector. - * These are JDI com.sun.jdi.connect.Connector arguments. + * These are JDI com.sun.jdi.connect.Connector arguments. The {@code vmexec} + * argument is not supported. */ public JdiInitiator(int port, List remoteVMOptions, String remoteAgent, boolean isLaunch, String host, int timeout, @@ -104,7 +105,10 @@ public JdiInitiator(int port, List remoteVMOptions, String remoteAgent, argumentName2Value.put("localAddress", host); } } - argumentName2Value.putAll(customConnectorArgs); + customConnectorArgs.entrySet() + .stream() + .filter(e -> !"vmexec".equals(e.getKey())) + .forEach(e -> argumentName2Value.put(e.getKey(), e.getValue())); this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value); this.vm = isLaunch ? launchTarget() diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 355e6ac208e..abd96c42cfd 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, 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 @@ -2561,6 +2561,11 @@ void readExtra(ZipFileSystem zipfs) throws IOException { if (extra == null) return; int elen = extra.length; + // Extra field Length cannot exceed 65,535 bytes per the PKWare + // APP.note 4.4.11 + if (elen > 0xFFFF) { + throw new ZipException("invalid extra field length"); + } int off = 0; int newOff = 0; while (off + 4 < elen) { @@ -2569,20 +2574,31 @@ void readExtra(ZipFileSystem zipfs) throws IOException { int tag = SH(extra, pos); int sz = SH(extra, pos + 2); pos += 4; - if (pos + sz > elen) // invalid data - break; + if (pos + sz > elen) { // invalid data + throw new ZipException("Invalid CEN header (invalid zip64 extra data field size)"); + } switch (tag) { case EXTID_ZIP64 : + // Check to see if we have a valid block size + if (!isZip64ExtBlockSizeValid(sz)) { + throw new ZipException("Invalid CEN header (invalid zip64 extra data field size)"); + } if (size == ZIP64_MINVAL) { if (pos + 8 > elen) // invalid zip64 extra break; // fields, just skip size = LL(extra, pos); + if (size < 0) { + throw new ZipException("Invalid zip64 extra block size value"); + } pos += 8; } if (csize == ZIP64_MINVAL) { if (pos + 8 > elen) break; csize = LL(extra, pos); + if (csize < 0) { + throw new ZipException("Invalid zip64 extra block compressed size value"); + } pos += 8; } if (locoff == ZIP64_MINVAL) { @@ -2590,6 +2606,9 @@ void readExtra(ZipFileSystem zipfs) throws IOException { break; locoff = LL(extra, pos); pos += 8; + if (locoff < 0) { + throw new ZipException("Invalid zip64 extra block LOC offset value"); + } } break; case EXTID_NTFS: @@ -2670,6 +2689,34 @@ void readExtra(ZipFileSystem zipfs) throws IOException { extra = null; } + /** + * Validate the size and contents of a Zip64 extended information field + * The order of the Zip64 fields is fixed, but the fields MUST + * only appear if the corresponding LOC or CEN field is set to 0xFFFF: + * or 0xFFFFFFFF: + * Uncompressed Size - 8 bytes + * Compressed Size - 8 bytes + * LOC Header offset - 8 bytes + * Disk Start Number - 4 bytes + * See PKWare APP.Note Section 4.5.3 for more details + * + * @param blockSize the Zip64 Extended Information Extra Field size + * @return true if the extra block size is valid; false otherwise + */ + private static boolean isZip64ExtBlockSizeValid(int blockSize) { + /* + * As the fields must appear in order, the block size indicates which + * fields to expect: + * 8 - uncompressed size + * 16 - uncompressed size, compressed size + * 24 - uncompressed size, compressed sise, LOC Header offset + * 28 - uncompressed size, compressed sise, LOC Header offset, + * and Disk start number + */ + int i = blockSize; + return i == 8 || i == 16 || i == 24 || i == 28 ? true : false; + } + ///////// basic file attributes /////////// @Override public FileTime creationTime() { diff --git a/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java b/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java new file mode 100644 index 00000000000..1d0c4039717 --- /dev/null +++ b/test/hotspot/jtreg/compiler/codegen/aes/CTR_Wraparound.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2023, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Check for 128-bit AES/CTR wraparound + * @library /test/lib / + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.FileInstaller . . + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.CTR_Wraparound 32 + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.CTR_Wraparound 1009 + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.CTR_Wraparound 2048 + */ + +package compiler.codegen.aes; + +import java.util.Arrays; +import java.util.Random; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import compiler.whitebox.CompilerWhiteBoxTest; +import sun.hotspot.code.Compiler; +import jdk.test.lib.Utils; +import jtreg.SkippedException; + +public class CTR_Wraparound { + private static final String ALGO = "AES/CTR/NoPadding"; + private static final int LOOPS = 100000; + + public static void main(String[] args) throws Exception { + int length = Integer.parseInt(args[0]); + int maxOffset = 60; + if (args.length > 1) { + maxOffset = Integer.parseInt(args[1]); + System.out.println("InitialOffset = " + maxOffset); + } + + if (!Compiler.isIntrinsicAvailable(CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "com.sun.crypto.provider.CounterMode", "implCrypt", byte[].class, int.class, int.class, byte[].class, int.class)) { + throw new SkippedException("AES-CTR intrinsic is not available"); + } + + Random random = Utils.getRandomInstance(); + + byte[] keyBytes = new byte[32]; + Arrays.fill(keyBytes, (byte)0xff); + SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); + + byte[] ivBytes = new byte[16]; + + Arrays.fill(ivBytes, (byte)0xff); + + byte[][] plaintext = new byte[maxOffset][]; + byte[][] ciphertext = new byte[maxOffset][]; + + for (int offset = 0; offset < maxOffset; offset++) { + ivBytes[ivBytes.length - 1] = (byte)-offset; + IvParameterSpec iv = new IvParameterSpec(ivBytes); + + Cipher encryptCipher = Cipher.getInstance(ALGO); + Cipher decryptCipher = Cipher.getInstance(ALGO); + + encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv); + decryptCipher.init(Cipher.DECRYPT_MODE, key, iv); + + plaintext[offset] = new byte[length]; + ciphertext[offset] = new byte[length]; + random.nextBytes(plaintext[offset]); + + byte[] decrypted = new byte[length]; + + encryptCipher.doFinal(plaintext[offset], 0, length, ciphertext[offset]); + decryptCipher.doFinal(ciphertext[offset], 0, length, decrypted); + + if (!Arrays.equals(plaintext[offset], decrypted)) { + throw new Exception("mismatch in setup at offset " + offset); + } + } + + for (int offset = 0; offset < maxOffset; offset++) { + ivBytes[ivBytes.length - 1] = (byte)-offset; + IvParameterSpec iv = new IvParameterSpec(ivBytes); + + Cipher encryptCipher = Cipher.getInstance(ALGO); + + encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv); + + byte[] encrypted = new byte[length]; + + for (int i = 0; i < LOOPS; i++) { + encryptCipher.doFinal(plaintext[offset], 0, length, encrypted); + if (!Arrays.equals(ciphertext[offset], encrypted)) { + throw new Exception("array mismatch at offset " + offset + + " with length " + length); + } + } + } + } +} diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.java b/test/jdk/java/net/httpclient/AsFileDownloadTest.java index 52b5a1f90d0..6a79eccdb0c 100644 --- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java +++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java @@ -24,7 +24,7 @@ /* * @test * @summary Basic test for ofFileDownload - * @bug 8196965 + * @bug 8196965 8302475 * @modules java.base/sun.net.www.http * java.net.http/jdk.internal.net.http.common * java.net.http/jdk.internal.net.http.frame @@ -127,18 +127,18 @@ public class AsFileDownloadTest { { "024", "attachment; filename=me.txt; filename*=utf-8''you.txt", "me.txt" }, { "025", "attachment; filename=\"m y.txt\"; filename*=utf-8''you.txt", "m y.txt" }, - { "030", "attachment; filename=foo/file1.txt", "file1.txt" }, - { "031", "attachment; filename=foo/bar/file2.txt", "file2.txt" }, - { "032", "attachment; filename=baz\\file3.txt", "file3.txt" }, - { "033", "attachment; filename=baz\\bar\\file4.txt", "file4.txt" }, - { "034", "attachment; filename=x/y\\file5.txt", "file5.txt" }, - { "035", "attachment; filename=x/y\\file6.txt", "file6.txt" }, - { "036", "attachment; filename=x/y\\z/file7.txt", "file7.txt" }, - { "037", "attachment; filename=x/y\\z/\\x/file8.txt", "file8.txt" }, - { "038", "attachment; filename=/root/file9.txt", "file9.txt" }, - { "039", "attachment; filename=../file10.txt", "file10.txt" }, - { "040", "attachment; filename=..\\file11.txt", "file11.txt" }, - { "041", "attachment; filename=foo/../../file12.txt", "file12.txt" }, + { "030", "attachment; filename=\"foo/file1.txt\"", "file1.txt" }, + { "031", "attachment; filename=\"foo/bar/file2.txt\"", "file2.txt" }, + { "032", "attachment; filename=\"baz\\\\file3.txt\"", "file3.txt" }, + { "033", "attachment; filename=\"baz\\\\bar\\\\file4.txt\"", "file4.txt" }, + { "034", "attachment; filename=\"x/y\\\\file5.txt\"", "file5.txt" }, + { "035", "attachment; filename=\"x/y\\\\file6.txt\"", "file6.txt" }, + { "036", "attachment; filename=\"x/y\\\\z/file7.txt\"", "file7.txt" }, + { "037", "attachment; filename=\"x/y\\\\z/\\\\x/file8.txt\"", "file8.txt" }, + { "038", "attachment; filename=\"/root/file9.txt\"", "file9.txt" }, + { "039", "attachment; filename=\"../file10.txt\"", "file10.txt" }, + { "040", "attachment; filename=\"..\\\\file11.txt\"", "file11.txt" }, + { "041", "attachment; filename=\"foo/../../file12.txt\"", "file12.txt" }, }; @DataProvider(name = "positive") @@ -177,18 +177,24 @@ void test(String uriString, String contentDispositionValue, String expectedFilen CREATE, TRUNCATE_EXISTING, WRITE); HttpResponse response = client.send(request, bh); + Path body = response.body(); out.println("Got response: " + response); - out.println("Got body Path: " + response.body()); + out.println("Got body Path: " + body); String fileContents = new String(Files.readAllBytes(response.body()), UTF_8); out.println("Got body: " + fileContents); assertEquals(response.statusCode(),200); - assertEquals(response.body().getFileName().toString(), expectedFilename); + assertEquals(body.getFileName().toString(), expectedFilename); assertTrue(response.headers().firstValue("Content-Disposition").isPresent()); assertEquals(response.headers().firstValue("Content-Disposition").get(), contentDispositionValue); assertEquals(fileContents, "May the luck of the Irish be with you!"); + if (!body.toAbsolutePath().startsWith(tempDir.toAbsolutePath())) { + System.out.println("Tempdir = " + tempDir.toAbsolutePath()); + System.out.println("body = " + body.toAbsolutePath()); + throw new AssertionError("body in wrong location"); + } // additional checks unrelated to file download caseInsensitivityOfHeaders(request.headers()); caseInsensitivityOfHeaders(response.headers()); diff --git a/test/jdk/java/util/zip/TestExtraTime.java b/test/jdk/java/util/zip/TestExtraTime.java index a60e810df0f..0e68e764546 100644 --- a/test/jdk/java/util/zip/TestExtraTime.java +++ b/test/jdk/java/util/zip/TestExtraTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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,8 @@ */ import java.io.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -59,7 +61,14 @@ public static void main(String[] args) throws Throwable{ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); - for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) { + // A structurally valid extra data example + byte[] sampleExtra = new byte[Short.BYTES*3]; + ByteBuffer.wrap(sampleExtra).order(ByteOrder.LITTLE_ENDIAN) + .putShort((short) 123) // ID: 123 + .putShort((short) Short.BYTES) // Size: 2 + .putShort((short) 42); // Data: Two bytes + + for (byte[] extra : new byte[][] { null, sampleExtra}) { // ms-dos 1980 epoch problem test0(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra); diff --git a/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java b/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java index 6ef3ec5d8f6..b969ecfd04e 100644 --- a/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java +++ b/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -114,13 +114,13 @@ public static void main(String[] args) throws Exception { err.println("corrupted CENEXT 1"); bad = good.clone(); bad[cenpos+CENEXT]++; - checkZipException(bad, ".*bad header size.*"); + checkZipException(bad, ".*invalid zip64 extra data field size.*"); err.println("corrupted CENEXT 2"); bad = good.clone(); bad[cenpos+CENEXT] = (byte)0xfd; bad[cenpos+CENEXT+1] = (byte)0xfd; - checkZipException(bad, ".*bad header size.*"); + checkZipException(bad, ".*extra data field size too long.*"); err.println("corrupted CENCOM"); bad = good.clone(); diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java b/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java index 0552a752019..0b8eeaecf2b 100644 --- a/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -23,17 +23,24 @@ /* * @test - * @bug 8164879 + * @bug 8164879 8300285 * @library ../../ * @library /test/lib - * @summary Verify AES/GCM's limits set in the jdk.tls.keyLimits property + * @summary Verify AEAD TLS cipher suite limits set in the jdk.tls.keyLimits + * property * start a new handshake sequence to renegotiate the symmetric key with an * SSLSocket connection. This test verifies the handshake method was called * via debugging info. It does not verify the renegotiation was successful * as that is very hard. * - * @run main SSLEngineKeyLimit 0 server AES/GCM/NoPadding keyupdate 1050000 - * @run main SSLEngineKeyLimit 1 client AES/GCM/NoPadding keyupdate 2^22 + * @run main SSLEngineKeyLimit 0 server TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 1050000 + * @run main SSLEngineKeyLimit 1 client TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 2^22 + * @run main SSLEngineKeyLimit 0 server TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 1050000, ChaCha20-Poly1305 KeyUpdate 1050000 + * @run main SSLEngineKeyLimit 1 client TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 2^22, ChaCha20-Poly1305 KeyUpdate 2^22 */ /* @@ -86,7 +93,7 @@ public class SSLEngineKeyLimit { } /** - * args should have two values: server|client, + * args should have two values: server|client, cipher suite, * Prepending 'p' is for internal use only. */ public static void main(String args[]) throws Exception { @@ -105,7 +112,7 @@ public static void main(String args[]) throws Exception { File f = new File("keyusage."+ System.nanoTime()); PrintWriter p = new PrintWriter(f); p.write("jdk.tls.keyLimits="); - for (int i = 2; i < args.length; i++) { + for (int i = 3; i < args.length; i++) { p.write(" "+ args[i]); } p.close(); @@ -120,10 +127,13 @@ public static void main(String args[]) throws Exception { System.getProperty("test.java.opts")); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, - Utils.addTestJavaOpts("SSLEngineKeyLimit", "p", args[1])); + Utils.addTestJavaOpts("SSLEngineKeyLimit", "p", args[1], + args[2])); OutputAnalyzer output = ProcessTools.executeProcess(pb); try { + output.shouldContain(String.format( + "\"cipher suite\" : \"%s", args[2])); if (expectedFail) { output.shouldNotContain("KeyUpdate: write key updated"); output.shouldNotContain("KeyUpdate: read key updated"); @@ -171,9 +181,10 @@ public static void main(String args[]) throws Exception { cTos.clear(); sToc.clear(); - Thread ts = new Thread(serverwrite ? new Client() : new Server()); + Thread ts = new Thread(serverwrite ? new Client() : + new Server(args[2])); ts.start(); - (serverwrite ? new Server() : new Client()).run(); + (serverwrite ? new Server(args[2]) : new Client()).run(); ts.interrupt(); ts.join(); } @@ -417,11 +428,14 @@ SSLContext initContext() throws Exception { } static class Server extends SSLEngineKeyLimit implements Runnable { - Server() throws Exception { + Server(String cipherSuite) throws Exception { super(); eng = initContext().createSSLEngine(); eng.setUseClientMode(false); eng.setNeedClientAuth(true); + if (cipherSuite != null && cipherSuite.length() > 0) { + eng.setEnabledCipherSuites(new String[] { cipherSuite }); + } } public void run() { diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java index 3a31cd3e4a4..0785b2d995a 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -23,14 +23,24 @@ /* * @test - * @bug 8164879 + * @bug 8164879 8300285 * @library ../../ * @library /test/lib * @modules java.base/sun.security.util - * @summary Verify AES/GCM's limits set in the jdk.tls.keyLimits property - * @run main SSLSocketKeyLimit 0 server AES/GCM/NoPadding keyupdate 1000000 - * @run main SSLSocketKeyLimit 0 client AES/GCM/NoPadding keyupdate 1000000 - * @run main SSLSocketKeyLimit 1 client AES/GCM/NoPadding keyupdate 2^22 + * @summary Verify AEAD TLS cipher suite limits set in the jdk.tls.keyLimits + * property + * @run main SSLSocketKeyLimit 0 server TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 1000000 + * @run main SSLSocketKeyLimit 0 client TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 1000000 + * @run main SSLSocketKeyLimit 1 client TLS_AES_256_GCM_SHA384 + * AES/GCM/NoPadding keyupdate 2^22 + * @run main SSLSocketKeyLimit 0 server TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 1000000, ChaCha20-Poly1305 KeyUpdate 1000000 + * @run main SSLSocketKeyLimit 0 client TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 1000000, ChaCha20-Poly1305 KeyUpdate 1000000 + * @run main SSLSocketKeyLimit 1 client TLS_CHACHA20_POLY1305_SHA256 + * AES/GCM/NoPadding keyupdate 2^22, ChaCha20-Poly1305 KeyUpdate 2^22 */ /** @@ -96,7 +106,7 @@ SSLContext initContext() throws Exception { } /** - * args should have two values: server|client, + * args should have three values: server|client, cipher suite, * Prepending 'p' is for internal use only. */ public static void main(String args[]) throws Exception { @@ -110,7 +120,7 @@ public static void main(String args[]) throws Exception { File f = new File("keyusage."+ System.nanoTime()); PrintWriter p = new PrintWriter(f); p.write("jdk.tls.keyLimits="); - for (int i = 2; i < args.length; i++) { + for (int i = 3; i < args.length; i++) { p.write(" "+ args[i]); } p.close(); @@ -125,10 +135,13 @@ public static void main(String args[]) throws Exception { System.getProperty("test.java.opts")); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, - Utils.addTestJavaOpts("SSLSocketKeyLimit", "p", args[1])); + Utils.addTestJavaOpts("SSLSocketKeyLimit", "p", args[1], + args[2])); OutputAnalyzer output = ProcessTools.executeProcess(pb); try { + output.shouldContain(String.format( + "\"cipher suite\" : \"%s", args[2])); if (expectedFail) { output.shouldNotContain("KeyUpdate: write key updated"); output.shouldNotContain("KeyUpdate: read key updated"); @@ -150,7 +163,7 @@ public static void main(String args[]) throws Exception { return; } - if (args.length > 0 && args[0].compareToIgnoreCase("client") == 0) { + if (args.length > 0 && args[1].compareToIgnoreCase("client") == 0) { serverwrite = false; } @@ -162,7 +175,7 @@ public static void main(String args[]) throws Exception { System.setProperty("javax.net.ssl.keyStorePassword", passwd); Arrays.fill(data, (byte)0x0A); - Thread ts = new Thread(new Server()); + Thread ts = new Thread(new Server(args[2])); ts.start(); while (!serverReady) { @@ -200,7 +213,8 @@ void read(SSLSocket s) throws Exception { int len; byte i = 0; try { - System.out.println("Server: connected " + s.getSession().getCipherSuite()); + System.out.println("Server: connected " + + s.getSession().getCipherSuite()); in = s.getInputStream(); out = s.getOutputStream(); while (true) { @@ -212,7 +226,8 @@ void read(SSLSocket s) throws Exception { if (b == 0x0A || b == 0x0D) { continue; } - System.out.println("\nData invalid: " + new HexDumpEncoder().encode(buf)); + System.out.println("\nData invalid: " + + new HexDumpEncoder().encode(buf)); break; } @@ -237,11 +252,14 @@ void read(SSLSocket s) throws Exception { static class Server extends SSLSocketKeyLimit implements Runnable { private SSLServerSocketFactory ssf; private SSLServerSocket ss; - Server() { + Server(String cipherSuite) { super(); try { ssf = initContext().getServerSocketFactory(); ss = (SSLServerSocket) ssf.createServerSocket(serverPort); + if (cipherSuite != null && cipherSuite.length() > 0) { + ss.setEnabledCipherSuites(new String[] { cipherSuite }); + } serverPort = ss.getLocalPort(); } catch (Exception e) { System.out.println("server: " + e.getMessage());