changeset 13264:fde7fd2a2fd2 jdk8u192-b05

Merge
author aefimov
date Fri, 03 Aug 2018 19:50:58 +0100
parents 5d8ea4165d26 (current diff) 676618f2eb22 (diff)
children bd0ccb0d6710 e222c45022e7
files .hgtags src/share/classes/sun/security/ssl/ClientHandshaker.java src/share/classes/sun/security/ssl/SSLEngineImpl.java src/share/classes/sun/security/ssl/SSLSocketImpl.java src/share/classes/sun/security/ssl/ServerHandshaker.java src/share/classes/sun/security/tools/keytool/Main.java src/share/classes/sun/security/util/SignatureFileVerifier.java src/windows/native/sun/security/mscapi/security.cpp src/windows/native/sun/windows/awt_Component.cpp test/sun/security/tools/jarsigner/warnings.sh
diffstat 50 files changed, 1749 insertions(+), 536 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Aug 01 03:36:32 2018 -0700
+++ b/.hgtags	Fri Aug 03 19:50:58 2018 +0100
@@ -857,6 +857,13 @@
 95df717479b19f5ea244afc67434827f2f851287 jdk8u162-b11
 ddae5cb11d6c04130b8002b852bc7f80e0c8bcd2 jdk8u162-b12
 8e40acfcc41a631f5922824712d4336742652eac jdk8u162-b31
+c00bdbbd9a77150f565298af9c305d7e6863eb59 jdk8u162-b32
+70a653814e61a5552312345308b85330fa8f27bc jdk8u162-b33
+f1f949ac13549c6fb3766279848539b124ad835e jdk8u162-b34
+b3de2b1e82fb2427cd40bb230aa26d9b7d8fb09c jdk8u162-b35
+e03fff22900242d92a97839a9c095bb106bdc68f jdk8u162-b36
+19696e8204b0e77e0f10af106c384b7ba6dd5bda jdk8u162-b37
+305c40e81a6fd59699036d4c35d8994f8501f116 jdk8u162-b38
 b6195815c4bbbf275f1aefd337d805eb66f2b5b8 jdk8u171-b00
 f1792a59f1fa20e47fe5d4561754012440564bec jdk8u171-b01
 cac020298633fc736f5e21afddf00145665ef0a7 jdk8u171-b02
@@ -875,6 +882,8 @@
 db8272cb8c99eea536a66c4c368c4bf2bf013a81 jdk8u172-b02
 bd24ee3a9a0494121fd1d96c308b9738f585001b jdk8u172-b03
 cf952b84daa1e74403a4d1df541c0ecca830717d jdk8u172-b04
+e7e27f446209924f66a4bf86738f3e5f2fbbef5f jdk8u181-b00
+a8746b41e23a1deda3d0f41ed2eca3d3a4cc74de jdk8u191-b00
 076daed81c0a851f6d13fac538834ac465cdc122 jdk8u172-b05
 94491d0dc59590535339a2ffae510166bb16f34c jdk8u172-b06
 7e9eeb74e84beb6d8a6f562441eb7dd0ab0befa9 jdk8u172-b07
@@ -885,6 +894,16 @@
 d902fae6241006af3c4cfc4ce82ebcb3efb9d725 jdk8u181-b01
 baac18e216fb47b4cfa04169b3c3de58d667de7c jdk8u181-b02
 d237c59d14e1c1fb1f750e9cdabcea6e711f4d34 jdk8u181-b03
+f3185b46a35b82727f39d52ac7fad7c4c78ddcdd jdk8u172-b31
+0939503b7477ba081484c54f26f177f9a66d92e4 jdk8u172-b32
+f4b138a6c95cf17f6138598fe04a90dfe1086bf4 jdk8u172-b33
+93b4d31ee70576a45a87607e2f5474d90ba31653 jdk8u172-b34
+6b4e239c74929b86b46113e92fe36d355157e235 jdk8u172-b35
+010852525831e0e88f622167d615438b82002e1f jdk8u172-b36
+9ac2466ffdbb1b9d9005b50aa633a5986617a002 jdk8u172-b37
+d902fae6241006af3c4cfc4ce82ebcb3efb9d725 jdk8u181-b01
+baac18e216fb47b4cfa04169b3c3de58d667de7c jdk8u181-b02
+d237c59d14e1c1fb1f750e9cdabcea6e711f4d34 jdk8u181-b03
 6eeca4fb7748e8bdca4afbd6785b04376b1d44cc jdk8u181-b04
 f34c24087b0e6f52391f491d6c3a608616d1db2c jdk8u181-b05
 076f5fd6258846fce7010a598de2c7583628bb1e jdk8u181-b06
@@ -895,6 +914,10 @@
 112f3576f12e24d5e35d8d31782698e7d9a8fa52 jdk8u181-b11
 22e01e7c5c39bfa3f5e2d18be76c7bf0dc71033a jdk8u181-b12
 0cb452d66676bc1b3824bea4a0c16ac76e58b070 jdk8u181-b13
+b01c6e5aa43c784fc66465b56227ddd9aa29eee6 jdk8u191-b01
+2db6890a956723ac347b573217d91bbbedbb0528 jdk8u191-b02
+89e2889d02d2f5dabdeda7f60cf80a8df3100eb4 jdk8u191-b03
+94e4769c6d69241f9eb7164a85fc91fc83faab5c jdk8u191-b04
 51b6cc7fbd98a87c6cdb5c70b7dbe25bb10e0dd7 jdk8u182-b00
 bead1ed7344f2911f5bed83639cf5160596561ef jdk8u192-b00
 444b4528c8ecdd39b5923820fa2ed6d583808b5e jdk8u192-b01
--- a/src/share/classes/com/sun/media/sound/DLSSoundbank.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/com/sun/media/sound/DLSSoundbank.java	Fri Aug 03 19:50:58 2018 +0100
@@ -548,7 +548,7 @@
         long count = riff.readUnsignedInt();
 
         if (size - 8 != 0)
-            riff.skipBytes(size - 8);
+            riff.skip(size - 8);
 
         for (int i = 0; i < count; i++) {
             DLSModulator modulator = new DLSModulator();
@@ -568,7 +568,7 @@
         long count = riff.readUnsignedInt();
 
         if (size - 8 != 0)
-            riff.skipBytes(size - 8);
+            riff.skip(size - 8);
 
         for (int i = 0; i < count; i++) {
             DLSModulator modulator = new DLSModulator();
@@ -661,7 +661,7 @@
         long loops = riff.readInt();
 
         if (size > 20)
-            riff.skipBytes(size - 20);
+            riff.skip(size - 20);
 
         for (int i = 0; i < loops; i++) {
             DLSSampleLoop loop = new DLSSampleLoop();
@@ -671,7 +671,7 @@
             loop.length = riff.readUnsignedInt();
             sampleOptions.loops.add(loop);
             if (size2 > 16)
-                riff.skipBytes(size2 - 16);
+                riff.skip(size2 - 16);
         }
     }
 
--- a/src/share/classes/com/sun/media/sound/RIFFReader.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/com/sun/media/sound/RIFFReader.java	Fri Aug 03 19:50:58 2018 +0100
@@ -172,49 +172,41 @@
         }
     }
 
-    public final long skipBytes(long n) throws IOException {
-        if (n < 0)
+    @Override
+    public long skip(final long n) throws IOException {
+        if (n <= 0 || avail == 0) {
             return 0;
-        long skipped = 0;
-        while (skipped != n) {
-            long s = skip(n - skipped);
-            if (s < 0)
-                break;
-            if (s == 0)
+        }
+        // will not skip more than
+        long remaining = Math.min(n, avail);
+        while (remaining > 0) {
+            // Some input streams like FileInputStream can return more bytes,
+            // when EOF is reached.
+            long ret = Math.min(stream.skip(remaining), remaining);
+            if (ret == 0) {
+                // EOF or not? we need to check.
                 Thread.yield();
-            skipped += s;
+                if (stream.read() == -1) {
+                    avail = 0;
+                    break;
+                }
+                ret = 1;
+            }
+            remaining -= ret;
+            avail -= ret;
+            filepointer += ret;
         }
-        return skipped;
+        return n - remaining;
     }
 
-    public long skip(long n) throws IOException {
-        if (avail == 0)
-            return -1;
-        if (n > avail) {
-            long len = stream.skip(avail);
-            if (len != -1)
-                filepointer += len;
-            avail = 0;
-            return len;
-        } else {
-            long ret = stream.skip(n);
-            if (ret == -1) {
-                avail = 0;
-                return -1;
-            }
-            avail -= ret;
-            filepointer += ret;
-            return ret;
-        }
-    }
-
+    @Override
     public int available() {
         return (int)avail;
     }
 
     public void finish() throws IOException {
         if (avail != 0) {
-            skipBytes(avail);
+            skip(avail);
         }
     }
 
@@ -337,6 +329,7 @@
         return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
     }
 
+    @Override
     public void close() throws IOException {
         finish();
         if (this == root)
--- a/src/share/classes/com/sun/naming/internal/VersionHelper12.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/com/sun/naming/internal/VersionHelper12.java	Fri Aug 03 19:50:58 2018 +0100
@@ -62,6 +62,25 @@
     }
 
     /**
+     * Determines whether classes may be loaded from an arbitrary URL code base.
+     */
+    private static final String TRUST_URL_CODEBASE_PROPERTY =
+            "com.sun.jndi.ldap.object.trustURLCodebase";
+    private static final String trustURLCodebase =
+            AccessController.doPrivileged(
+                new PrivilegedAction<String>() {
+                    public String run() {
+                        try {
+                        return System.getProperty(TRUST_URL_CODEBASE_PROPERTY,
+                            "false");
+                        } catch (SecurityException e) {
+                        return "false";
+                        }
+                    }
+                }
+            );
+
+    /**
      * Package private.
      *
      * This internal method is used with Thread Context Class Loader (TCCL),
@@ -79,12 +98,15 @@
      */
     public Class<?> loadClass(String className, String codebase)
             throws ClassNotFoundException, MalformedURLException {
+        if ("true".equalsIgnoreCase(trustURLCodebase)) {
+            ClassLoader parent = getContextClassLoader();
+            ClassLoader cl =
+                    URLClassLoader.newInstance(getUrlArray(codebase), parent);
 
-        ClassLoader parent = getContextClassLoader();
-        ClassLoader cl =
-                 URLClassLoader.newInstance(getUrlArray(codebase), parent);
-
-        return loadClass(className, cl);
+            return loadClass(className, cl);
+        } else {
+            return null;
+        }
     }
 
     String getJndiProperty(final int i) {
--- a/src/share/classes/java/net/InetAddress.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/net/InetAddress.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2018, 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
@@ -37,6 +37,7 @@
 import java.io.ObjectStreamException;
 import java.io.ObjectStreamField;
 import java.io.IOException;
+import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.ObjectInputStream.GetField;
 import java.io.ObjectOutputStream;
@@ -1602,8 +1603,11 @@
         }
         GetField gf = s.readFields();
         String host = (String)gf.get("hostName", null);
-        int address= gf.get("address", 0);
-        int family= gf.get("family", 0);
+        int address = gf.get("address", 0);
+        int family = gf.get("family", 0);
+        if (family != IPv4 && family != IPv6) {
+            throw new InvalidObjectException("invalid address family type: " + family);
+        }
         InetAddressHolder h = new InetAddressHolder(host, address, family);
         UNSAFE.putObject(this, FIELDS_OFFSET, h);
     }
--- a/src/share/classes/java/net/NetworkInterface.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/net/NetworkInterface.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -319,8 +319,20 @@
         if (addr == null) {
             throw new NullPointerException();
         }
-        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
-            throw new IllegalArgumentException ("invalid address type");
+        if (addr instanceof Inet4Address) {
+            Inet4Address inet4Address = (Inet4Address) addr;
+            if (inet4Address.holder.family != InetAddress.IPv4) {
+                throw new IllegalArgumentException("invalid family type: "
+                        + inet4Address.holder.family);
+            }
+        } else if (addr instanceof Inet6Address) {
+            Inet6Address inet6Address = (Inet6Address) addr;
+            if (inet6Address.holder.family != InetAddress.IPv6) {
+                throw new IllegalArgumentException("invalid family type: "
+                        + inet6Address.holder.family);
+            }
+        } else {
+            throw new IllegalArgumentException("invalid address type: " + addr);
         }
         return getByInetAddress0(addr);
     }
--- a/src/share/classes/java/net/URLClassLoader.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/net/URLClassLoader.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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.misc.Resource;
+import sun.misc.SharedSecrets;
 import sun.misc.URLClassPath;
 import sun.net.www.ParseUtil;
 import sun.security.util.SecurityConstants;
@@ -486,13 +487,13 @@
     protected Package definePackage(String name, Manifest man, URL url)
         throws IllegalArgumentException
     {
-        String path = name.replace('.', '/').concat("/");
         String specTitle = null, specVersion = null, specVendor = null;
         String implTitle = null, implVersion = null, implVendor = null;
         String sealed = null;
         URL sealBase = null;
 
-        Attributes attr = man.getAttributes(path);
+        Attributes attr = SharedSecrets.javaUtilJarAccess()
+                .getTrustedAttributes(man, name.replace('.', '/').concat("/"));
         if (attr != null) {
             specTitle   = attr.getValue(Name.SPECIFICATION_TITLE);
             specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
@@ -536,10 +537,12 @@
     /*
      * Returns true if the specified package name is sealed according to the
      * given manifest.
+     *
+     * @throws SecurityException if the package name is untrusted in the manifest
      */
     private boolean isSealed(String name, Manifest man) {
-        String path = name.replace('.', '/').concat("/");
-        Attributes attr = man.getAttributes(path);
+        Attributes attr = SharedSecrets.javaUtilJarAccess()
+                .getTrustedAttributes(man, name.replace('.', '/').concat("/"));
         String sealed = null;
         if (attr != null) {
             sealed = attr.getValue(Name.SEALED);
--- a/src/share/classes/java/util/jar/JarFile.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/util/jar/JarFile.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -191,10 +191,10 @@
             if (manEntry != null) {
                 if (verify) {
                     byte[] b = getBytes(manEntry);
-                    man = new Manifest(new ByteArrayInputStream(b));
                     if (!jvInitialized) {
                         jv = new JarVerifier(b);
                     }
+                    man = new Manifest(jv, new ByteArrayInputStream(b));
                 } else {
                     man = new Manifest(super.getInputStream(manEntry));
                 }
--- a/src/share/classes/java/util/jar/JarVerifier.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/util/jar/JarVerifier.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -879,4 +879,24 @@
     static CodeSource getUnsignedCS(URL url) {
         return new VerifierCodeSource(null, url, (java.security.cert.Certificate[]) null);
     }
+
+    /**
+     * Returns whether the name is trusted. Used by
+     * {@link Manifest#getTrustedAttributes(String)}.
+     */
+    boolean isTrustedManifestEntry(String name) {
+        // How many signers? MANIFEST.MF is always verified
+        CodeSigner[] forMan = verifiedSigners.get(JarFile.MANIFEST_NAME);
+        if (forMan == null) {
+            return true;
+        }
+        // Check sigFileSigners first, because we are mainly dealing with
+        // non-file entries which will stay in sigFileSigners forever.
+        CodeSigner[] forName = sigFileSigners.get(name);
+        if (forName == null) {
+            forName = verifiedSigners.get(name);
+        }
+        // Returns trusted if all signers sign the entry
+        return forName != null && forName.length == forMan.length;
+    }
 }
--- a/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -60,4 +60,9 @@
     public List<Object> getManifestDigests(JarFile jar) {
         return jar.getManifestDigests();
     }
+
+    public Attributes getTrustedAttributes(Manifest man, String name) {
+        return man.getTrustedAttributes(name);
+    }
+
 }
--- a/src/share/classes/java/util/jar/Manifest.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/java/util/jar/Manifest.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -48,15 +48,19 @@
  */
 public class Manifest implements Cloneable {
     // manifest main attributes
-    private Attributes attr = new Attributes();
+    private final Attributes attr = new Attributes();
 
     // manifest entries
-    private Map<String, Attributes> entries = new HashMap<>();
+    private final Map<String, Attributes> entries = new HashMap<>();
+
+    // associated JarVerifier, not null when called by JarFile::getManifest.
+    private final JarVerifier jv;
 
     /**
      * Constructs a new, empty Manifest.
      */
     public Manifest() {
+        jv = null;
     }
 
     /**
@@ -66,7 +70,16 @@
      * @throws IOException if an I/O error has occurred
      */
     public Manifest(InputStream is) throws IOException {
+        this(null, is);
+    }
+
+    /**
+     * Constructs a new Manifest from the specified input stream
+     * and associates it with a JarVerifier.
+     */
+    Manifest(JarVerifier jv, InputStream is) throws IOException {
         read(is);
+        this.jv = jv;
     }
 
     /**
@@ -77,6 +90,7 @@
     public Manifest(Manifest man) {
         attr.putAll(man.getMainAttributes());
         entries.putAll(man.getEntries());
+        jv = man.jv;
     }
 
     /**
@@ -127,6 +141,23 @@
     }
 
     /**
+     * Returns the Attributes for the specified entry name, if trusted.
+     *
+     * @param name entry name
+     * @return returns the same result as {@link #getAttributes(String)}
+     * @throws SecurityException if the associated jar is signed but this entry
+     *      has been modified after signing (i.e. the section in the manifest
+     *      does not exist in SF files of all signers).
+     */
+    Attributes getTrustedAttributes(String name) {
+        Attributes result = getAttributes(name);
+        if (result != null && jv != null && ! jv.isTrustedManifestEntry(name)) {
+            throw new SecurityException("Untrusted manifest entry: " + name);
+        }
+        return result;
+    }
+
+    /**
      * Clears the main Attributes as well as the entries in this Manifest.
      */
     public void clear() {
--- a/src/share/classes/javax/crypto/Cipher.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/javax/crypto/Cipher.java	Fri Aug 03 19:50:58 2018 +0100
@@ -2703,7 +2703,7 @@
 
         // Input sanity check
         if ((src == null) || (offset < 0) || (len < 0)
-                || ((len + offset) > src.length)) {
+                || (len > (src.length - offset))) {
             throw new IllegalArgumentException("Bad arguments");
         }
 
--- a/src/share/classes/javax/crypto/CipherInputStream.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/javax/crypto/CipherInputStream.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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,13 @@
  * that are not thrown by its ancestor classes.  In particular, the
  * <code>skip</code> method skips, and the <code>available</code>
  * method counts only data that have been processed by the encapsulated Cipher.
+ * This class may catch BadPaddingException and other exceptions thrown by
+ * failed integrity checks during decryption. These exceptions are not
+ * re-thrown, so the client may not be informed that integrity checks
+ * failed. Because of this behavior, this class may not be suitable
+ * for use with decryption in an authenticated mode of operation (e.g. GCM).
+ * Applications that require authenticated encryption can use the Cipher API
+ * directly as an alternative to using this class.
  *
  * <p> It is crucial for a programmer using this class not to use
  * methods that are not defined or overriden in this class (such as a
--- a/src/share/classes/javax/crypto/spec/GCMParameterSpec.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/javax/crypto/spec/GCMParameterSpec.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -120,7 +120,7 @@
 
         // Input sanity check
         if ((src == null) ||(len < 0) || (offset < 0)
-                || ((len + offset) > src.length)) {
+                || (len > (src.length - offset))) {
             throw new IllegalArgumentException("Invalid buffer arguments");
         }
 
--- a/src/share/classes/sun/misc/JavaUtilJarAccess.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/misc/JavaUtilJarAccess.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -30,8 +30,10 @@
 import java.security.CodeSource;
 import java.util.Enumeration;
 import java.util.List;
+import java.util.jar.Attributes;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+import java.util.jar.Manifest;
 
 public interface JavaUtilJarAccess {
     public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException;
@@ -41,4 +43,5 @@
     public Enumeration<JarEntry> entries2(JarFile jar);
     public void setEagerValidation(JarFile jar, boolean eager);
     public List<Object> getManifestDigests(JarFile jar);
+    public Attributes getTrustedAttributes(Manifest man, String name);
 }
--- a/src/share/classes/sun/misc/URLClassPath.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/misc/URLClassPath.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -37,6 +37,7 @@
 import java.util.jar.Attributes.Name;
 import java.net.JarURLConnection;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLConnection;
@@ -69,6 +70,8 @@
     private static final boolean DEBUG_LOOKUP_CACHE;
     private static final boolean DISABLE_JAR_CHECKING;
     private static final boolean DISABLE_ACC_CHECKING;
+    private static final boolean DISABLE_CP_URL_CHECK;
+    private static final boolean DEBUG_CP_URL_CHECK;
 
     static {
         JAVA_VERSION = java.security.AccessController.doPrivileged(
@@ -84,6 +87,13 @@
         p = AccessController.doPrivileged(
             new GetPropertyAction("jdk.net.URLClassPath.disableRestrictedPermissions"));
         DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
+
+        // This property will be removed in a later release
+        p = AccessController.doPrivileged(
+            new GetPropertyAction("jdk.net.URLClassPath.disableClassPathURLCheck"));
+
+        DISABLE_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false;
+        DEBUG_CP_URL_CHECK = "debug".equals(p);
     }
 
     /* The original search path of URLs. */
@@ -1217,11 +1227,51 @@
             int i = 0;
             while (st.hasMoreTokens()) {
                 String path = st.nextToken();
-                urls[i] = new URL(base, path);
-                i++;
+                URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path);
+                if (url != null) {
+                    urls[i] = url;
+                    i++;
+                }
+            }
+            if (i == 0) {
+                urls = null;
+            } else if (i != urls.length) {
+                // Truncate nulls from end of array
+                urls = Arrays.copyOf(urls, i);
             }
             return urls;
         }
+
+        /*
+         * Return a URL for the given path resolved against the base URL, or
+         * null if the resulting URL is invalid.
+         */
+        static URL safeResolve(URL base, String path) {
+            String child = path.replace(File.separatorChar, '/');
+            try {
+                if (!URI.create(child).isAbsolute()) {
+                    URL url = new URL(base, child);
+                    if (base.getProtocol().equalsIgnoreCase("file")) {
+                        return url;
+                    } else {
+                        String bp = base.getPath();
+                        String urlp = url.getPath();
+                        int pos = bp.lastIndexOf('/');
+                        if (pos == -1) {
+                            pos = bp.length() - 1;
+                        }
+                        if (urlp.regionMatches(0, bp, 0, pos + 1)
+                            && urlp.indexOf("..", pos) == -1) {
+                            return url;
+                        }
+                    }
+                }
+            } catch (MalformedURLException | IllegalArgumentException e) {}
+            if (DEBUG_CP_URL_CHECK) {
+                System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
+            }
+            return null;
+        }
     }
 
     /*
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2018, 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
@@ -2686,6 +2686,8 @@
             // doesn't know about proxy.
             useProxyResponseCode = true;
         } else {
+            final URL prevURL = url;
+
             // maintain previous headers, just change the name
             // of the file we're getting
             url = locUrl;
@@ -2714,6 +2716,14 @@
                 poster = null;
                 if (!checkReuseConnection())
                     connect();
+
+                if (!sameDestination(prevURL, url)) {
+                    // Ensures pre-redirect user-set cookie will not be reset.
+                    // CookieHandler, if any, will be queried to determine
+                    // cookies for redirected URL, if any.
+                    userCookies = null;
+                    userCookies2 = null;
+                }
             } else {
                 if (!checkReuseConnection())
                     connect();
@@ -2736,11 +2746,52 @@
                     }
                     requests.set("Host", host);
                 }
+
+                if (!sameDestination(prevURL, url)) {
+                    // Redirecting to a different destination will drop any
+                    // security-sensitive headers, regardless of whether
+                    // they are user-set or not. CookieHandler, if any, will be
+                    // queried to determine cookies for redirected URL, if any.
+                    userCookies = null;
+                    userCookies2 = null;
+                    requests.remove("Cookie");
+                    requests.remove("Cookie2");
+                    requests.remove("Authorization");
+
+                    // check for preemptive authorization
+                    AuthenticationInfo sauth =
+                            AuthenticationInfo.getServerAuth(url);
+                    if (sauth != null && sauth.supportsPreemptiveAuthorization() ) {
+                        // Sets "Authorization"
+                        requests.setIfNotSet(sauth.getHeaderName(), sauth.getHeaderValue(url,method));
+                        currentServerCredentials = sauth;
+                    }
+                }
             }
         }
         return true;
     }
 
+    /* Returns true iff the given URLs have the same host and effective port. */
+    private static boolean sameDestination(URL firstURL, URL secondURL) {
+        assert firstURL.getProtocol().equalsIgnoreCase(secondURL.getProtocol()):
+               "protocols not equal: " + firstURL +  " - " + secondURL;
+
+        if (!firstURL.getHost().equalsIgnoreCase(secondURL.getHost()))
+            return false;
+
+        int firstPort = firstURL.getPort();
+        if (firstPort == -1)
+            firstPort = firstURL.getDefaultPort();
+        int secondPort = secondURL.getPort();
+        if (secondPort == -1)
+            secondPort = secondURL.getDefaultPort();
+        if (firstPort != secondPort)
+            return false;
+
+        return true;
+    }
+
     /* dummy byte buffer for reading off socket prior to closing */
     byte[] cdata = new byte [128];
 
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, 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
@@ -719,7 +719,8 @@
         session = new SSLSessionImpl(protocolVersion, cipherSuite,
                             getLocalSupportedSignAlgs(),
                             mesg.sessionId, getHostSE(), getPortSE(),
-                            (extendedMasterSecretExt != null));
+                            (extendedMasterSecretExt != null),
+                            getEndpointIdentificationAlgorithmSE());
         session.setRequestedServerNames(requestedServerNames);
         setHandshakeSessionSE(session);
         if (debug != null && Debug.isOn("handshake")) {
@@ -1391,6 +1392,24 @@
                 }
             }
 
+            // ensure that the endpoint identification algorithm matches the
+            // one in the session
+            String identityAlg = getEndpointIdentificationAlgorithmSE();
+            if (session != null && identityAlg != null) {
+
+                String sessionIdentityAlg =
+                    session.getEndpointIdentificationAlgorithm();
+                if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
+
+                    if (debug != null && Debug.isOn("session")) {
+                        System.out.println("%% can't resume, endpoint id" +
+                            " algorithm does not match, requested: " +
+                            identityAlg + ", cached: " + sessionIdentityAlg);
+                    }
+                    session = null;
+                }
+            }
+
             if (session != null) {
                 if (debug != null) {
                     if (Debug.isOn("handshake") || Debug.isOn("session")) {
--- a/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, 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
@@ -115,6 +115,10 @@
     private Principal peerPrincipal;
     private Principal localPrincipal;
 
+    // The endpoint identification algorithm used to check certificates
+    // in this session.
+    private final String              endpointIdentificationAlgorithm;
+
     /*
      * Is the session currently re-established with a session-resumption
      * abbreviated initial handshake?
@@ -146,7 +150,7 @@
      */
     private SSLSessionImpl() {
         this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
-            new SessionId(false, null), null, -1, false);
+            new SessionId(false, null), null, -1, false, null);
     }
 
     /*
@@ -157,10 +161,10 @@
     SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
             Collection<SignatureAndHashAlgorithm> algorithms,
             SecureRandom generator, String host, int port,
-            boolean useExtendedMasterSecret) {
+            boolean useExtendedMasterSecret, String endpointIdAlgorithm) {
         this(protocolVersion, cipherSuite, algorithms,
              new SessionId(defaultRejoinable, generator), host, port,
-             useExtendedMasterSecret);
+             useExtendedMasterSecret, endpointIdAlgorithm);
     }
 
     /*
@@ -169,7 +173,8 @@
     SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
             Collection<SignatureAndHashAlgorithm> algorithms,
             SessionId id, String host, int port,
-            boolean useExtendedMasterSecret) {
+            boolean useExtendedMasterSecret,
+            String endpointIdAlgorithm){
         this.protocolVersion = protocolVersion;
         sessionId = id;
         peerCerts = null;
@@ -182,6 +187,7 @@
         localSupportedSignAlgs =
             SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
         this.useExtendedMasterSecret = useExtendedMasterSecret;
+        this.endpointIdentificationAlgorithm = endpointIdAlgorithm;
 
         if (debug != null && Debug.isOn("session")) {
             System.out.println("%% Initialized:  " + this);
@@ -247,6 +253,10 @@
         localPrincipal = principal;
     }
 
+    String getEndpointIdentificationAlgorithm() {
+        return this.endpointIdentificationAlgorithm;
+    }
+
     /**
      * Returns true iff this session may be resumed ... sessions are
      * usually resumable.  Security policies may suggest otherwise,
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, 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
@@ -698,6 +698,25 @@
                     }
                 }
 
+                // ensure that the endpoint identification algorithm matches the
+                // one in the session
+                String identityAlg = getEndpointIdentificationAlgorithmSE();
+                if (resumingSession && identityAlg != null) {
+
+                    String sessionIdentityAlg =
+                    previous.getEndpointIdentificationAlgorithm();
+                    if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
+
+                        if (debug != null && Debug.isOn("session")) {
+                            System.out.println("%% can't resume, endpoint id"
+                                + " algorithm does not match, requested: " +
+                                identityAlg + ", cached: " +
+                                sessionIdentityAlg);
+                        }
+                        resumingSession = false;
+                    }
+                }
+
                 if (resumingSession) {
                     CipherSuite suite = previous.getSuite();
                     // verify that the ciphersuite from the cached session
@@ -769,7 +788,8 @@
                         sslContext.getSecureRandom(),
                         getHostAddressSE(), getPortSE(),
                         (requestedToUseEMS &&
-                                (protocolVersion.v >= ProtocolVersion.TLS10.v)));
+                                (protocolVersion.v >= ProtocolVersion.TLS10.v)),
+                        getEndpointIdentificationAlgorithmSE());
 
             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
                 if (peerSupportedSignAlgs != null) {
--- a/src/share/classes/sun/security/tools/KeyStoreUtil.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/tools/KeyStoreUtil.java	Fri Aug 03 19:50:58 2018 +0100
@@ -35,6 +35,7 @@
 
 import java.security.KeyStore;
 
+import java.security.cert.X509Certificate;
 import java.text.Collator;
 
 import java.util.Locale;
@@ -59,6 +60,25 @@
     };
 
     /**
+     * Returns true if the certificate is self-signed, false otherwise.
+     */
+    public static boolean isSelfSigned(X509Certificate cert) {
+        return signedBy(cert, cert);
+    }
+
+    public static boolean signedBy(X509Certificate end, X509Certificate ca) {
+        if (!ca.getSubjectX500Principal().equals(end.getIssuerX500Principal())) {
+            return false;
+        }
+        try {
+            end.verify(ca.getPublicKey());
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
      * Returns true if KeyStore has a password. This is true except for
      * MSCAPI KeyStores
      */
--- a/src/share/classes/sun/security/tools/jarsigner/Main.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/tools/jarsigner/Main.java	Fri Aug 03 19:50:58 2018 +0100
@@ -26,6 +26,8 @@
 package sun.security.tools.jarsigner;
 
 import java.io.*;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.PKIXBuilderParameters;
 import java.util.*;
 import java.util.zip.*;
 import java.util.jar.*;
@@ -46,11 +48,9 @@
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.security.cert.CertPath;
-import java.security.cert.CertPathValidator;
 import java.security.cert.CertificateExpiredException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.PKIXParameters;
 import java.security.cert.TrustAnchor;
 import java.util.Map.Entry;
 import sun.security.pkcs.PKCS7;
@@ -58,6 +58,8 @@
 import sun.security.timestamp.TimestampToken;
 import sun.security.tools.KeyStoreUtil;
 import sun.security.tools.PathList;
+import sun.security.validator.Validator;
+import sun.security.validator.ValidatorException;
 import sun.security.x509.*;
 import sun.security.util.*;
 import java.util.Base64;
@@ -173,22 +175,34 @@
     private boolean noTimestamp = false;
     private Date expireDate = new Date(0L);     // used in noTimestamp warning
 
-    // Severe warnings
+    // Severe warnings.
+
+    // jarsigner used to check signer cert chain validity and key usages
+    // itself and set various warnings. Later CertPath validation is
+    // added but chainNotValidated is only flagged when no other existing
+    // warnings are set. TSA cert chain check is added separately and
+    // only tsaChainNotValidated is set, i.e. has no affect on hasExpiredCert,
+    // notYetValidCert, or any badXyzUsage.
+
+    private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg
     private boolean hasExpiredCert = false;
     private boolean notYetValidCert = false;
     private boolean chainNotValidated = false;
+    private boolean tsaChainNotValidated = false;
     private boolean notSignedByAlias = false;
     private boolean aliasNotInStore = false;
     private boolean hasUnsignedEntry = false;
     private boolean badKeyUsage = false;
     private boolean badExtendedKeyUsage = false;
     private boolean badNetscapeCertType = false;
+    private boolean signerSelfSigned = false;
+
+    private Throwable chainNotValidatedReason = null;
+    private Throwable tsaChainNotValidatedReason = null;
 
     private boolean seeWeak = false;
 
-    CertificateFactory certificateFactory;
-    CertPathValidator validator;
-    PKIXParameters pkixParameters;
+    PKIXBuilderParameters pkixParameters;
 
     public void run(String args[]) {
         try {
@@ -275,7 +289,8 @@
 
         if (strict) {
             int exitCode = 0;
-            if (chainNotValidated || hasExpiredCert || notYetValidCert) {
+            if (weakAlg != 0 || chainNotValidated
+                    || hasExpiredCert || notYetValidCert || signerSelfSigned) {
                 exitCode |= 4;
             }
             if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType) {
@@ -287,6 +302,9 @@
             if (notSignedByAlias || aliasNotInStore) {
                 exitCode |= 32;
             }
+            if (tsaChainNotValidated) {
+                exitCode |= 64;
+            }
             if (exitCode != 0) {
                 System.exit(exitCode);
             }
@@ -807,6 +825,9 @@
                 System.out.println(rb.getString("no.manifest."));
             }
 
+            // If there is a time stamp block inside the PKCS7 block file
+            boolean hasTimestampBlock = false;
+
             // Even if the verbose option is not specified, all out strings
             // must be generated so seeWeak can be updated.
             if (!digestMap.isEmpty()
@@ -835,6 +856,7 @@
                             PublicKey key = signer.getPublicKey();
                             PKCS7 tsToken = si.getTsToken();
                             if (tsToken != null) {
+                                hasTimestampBlock = true;
                                 SignerInfo tsSi = tsToken.getSignerInfos()[0];
                                 X509Certificate tsSigner = tsSi.getCertificate(tsToken);
                                 byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
@@ -890,6 +912,12 @@
             }
             System.out.println();
 
+            // If signer is a trusted cert or private entry in user's own
+            // keystore, it can be self-signed.
+            if (!aliasNotInStore) {
+                signerSelfSigned = false;
+            }
+
             if (!anySigned) {
                 if (seeWeak) {
                     if (verbose != null) {
@@ -910,8 +938,8 @@
                 boolean errorAppeared = false;
                 if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
                         notYetValidCert || chainNotValidated || hasExpiredCert ||
-                        hasUnsignedEntry ||
-                        aliasNotInStore || notSignedByAlias) {
+                        hasUnsignedEntry || signerSelfSigned || (weakAlg != 0) ||
+                        aliasNotInStore || notSignedByAlias || tsaChainNotValidated) {
 
                     if (strict) {
                         System.out.println(rb.getString("jar.verified.with.signer.errors."));
@@ -925,6 +953,12 @@
                         warningAppeared = true;
                     }
 
+                    if (weakAlg != 0) {
+                        // In fact, jarsigner verification did not catch this
+                        // since it has not read the JarFile content itself.
+                        // Everything is done with JarFile API.
+                    }
+
                     if (badKeyUsage) {
                         System.out.println(
                             rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
@@ -954,8 +988,15 @@
                     }
 
                     if (chainNotValidated) {
-                        System.out.println(
-                                rb.getString("This.jar.contains.entries.whose.certificate.chain.is.not.validated."));
+                        System.out.println(String.format(
+                                rb.getString("This.jar.contains.entries.whose.certificate.chain.is.invalid.reason.1"),
+                                chainNotValidatedReason.getLocalizedMessage()));
+                    }
+
+                    if (tsaChainNotValidated) {
+                        System.out.println(String.format(
+                                rb.getString("This.jar.contains.entries.whose.tsa.certificate.chain.is.invalid.reason.1"),
+                                tsaChainNotValidatedReason.getLocalizedMessage()));
                     }
 
                     if (notSignedByAlias) {
@@ -966,6 +1007,11 @@
                     if (aliasNotInStore) {
                         System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore."));
                     }
+
+                    if (signerSelfSigned) {
+                        System.out.println(rb.getString(
+                                "This.jar.contains.entries.whose.signer.certificate.is.self.signed."));
+                    }
                 } else {
                     System.out.println(rb.getString("jar.verified."));
                 }
@@ -980,8 +1026,15 @@
                                 "This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
                     }
                     if (noTimestamp) {
-                        System.out.println(
-                                String.format(rb.getString("no.timestamp.verifying"), expireDate));
+                        if (hasTimestampBlock) {
+                            // JarSigner API has not seen the timestamp,
+                            // might have ignored it due to weak alg, etc.
+                            System.out.println(
+                                    String.format(rb.getString("bad.timestamp.verifying"), expireDate));
+                        } else {
+                            System.out.println(
+                                    String.format(rb.getString("no.timestamp.verifying"), expireDate));
+                        }
                     }
                 }
                 if (warningAppeared || errorAppeared) {
@@ -1032,16 +1085,23 @@
     private static MessageFormat expiredTimeForm = null;
     private static MessageFormat expiringTimeForm = null;
 
-    /*
-     * Display some details about a certificate:
+    /**
+     * Returns a string about a certificate:
      *
      * [<tab>] <cert-type> [", " <subject-DN>] [" (" <keystore-entry-alias> ")"]
      * [<validity-period> | <expiry-warning>]
+     * [<key-usage-warning>]
      *
-     * Note: no newline character at the end
+     * Note: no newline character at the end.
+     *
+     * When isTsCert is true, this method sets global flags like hasExpiredCert,
+     * notYetValidCert, badKeyUsage, badExtendedKeyUsage, badNetscapeCertType.
+     *
+     * @param isTsCert true if c is in the TSA cert chain, false otherwise.
+     * @param checkUsage true to check code signer keyUsage
      */
-    String printCert(String tab, Certificate c, boolean checkValidityPeriod,
-        Date timestamp, boolean checkUsage) {
+    String printCert(boolean isTsCert, String tab, Certificate c,
+        Date timestamp, boolean checkUsage) throws Exception {
 
         StringBuilder certStr = new StringBuilder();
         String space = rb.getString("SPACE");
@@ -1061,7 +1121,7 @@
             certStr.append(space).append(alias);
         }
 
-        if (checkValidityPeriod && x509Cert != null) {
+        if (x509Cert != null) {
 
             certStr.append("\n").append(tab).append("[");
             Date notAfter = x509Cert.getNotAfter();
@@ -1074,7 +1134,7 @@
                     x509Cert.checkValidity();
                     // test if cert will expire within six months
                     if (notAfter.getTime() < System.currentTimeMillis() + SIX_MONTHS) {
-                        hasExpiringCert = true;
+                        if (!isTsCert) hasExpiringCert = true;
                         if (expiringTimeForm == null) {
                             expiringTimeForm = new MessageFormat(
                                 rb.getString("certificate.will.expire.on"));
@@ -1095,7 +1155,7 @@
                     certStr.append(validityTimeForm.format(source));
                 }
             } catch (CertificateExpiredException cee) {
-                hasExpiredCert = true;
+                if (!isTsCert) hasExpiredCert = true;
 
                 if (expiredTimeForm == null) {
                     expiredTimeForm = new MessageFormat(
@@ -1105,7 +1165,7 @@
                 certStr.append(expiredTimeForm.format(source));
 
             } catch (CertificateNotYetValidException cnyve) {
-                notYetValidCert = true;
+                if (!isTsCert) notYetValidCert = true;
 
                 if (notYetTimeForm == null) {
                     notYetTimeForm = new MessageFormat(
@@ -1218,7 +1278,25 @@
     }
 
     void signJar(String jarName, String alias, String[] args)
-        throws Exception {
+            throws Exception {
+
+        DisabledAlgorithmConstraints dac =
+                new DisabledAlgorithmConstraints(
+                        DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
+
+        if (digestalg != null && !dac.permits(
+                Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) {
+            weakAlg |= 1;
+        }
+        if (tSADigestAlg != null && !dac.permits(
+                Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) {
+            weakAlg |= 4;
+        }
+        if (sigalg != null && !dac.permits(
+                Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) {
+            weakAlg |= 2;
+        }
+
         boolean aliasUsed = false;
         X509Certificate tsaCert = null;
 
@@ -1494,7 +1572,7 @@
                             tsaURI);
                     }
                     System.out.println(rb.getString("TSA.certificate.") +
-                        printCert("", tsaCert, false, null, false));
+                            printCert(true, "", tsaCert, null, false));
                 }
                 if (signingMechanism != null) {
                     System.out.println(
@@ -1557,6 +1635,30 @@
             }
         }
 
+        // The JarSigner API always accepts the timestamp received.
+        // We need to extract the certs from the signed jar to
+        // validate it.
+        if (!noTimestamp) {
+            try (JarFile check = new JarFile(signedJarFile)) {
+                PKCS7 p7 = new PKCS7(check.getInputStream(check.getEntry(
+                        "META-INF/" + sigfile + "." + privateKey.getAlgorithm())));
+                SignerInfo si = p7.getSignerInfos()[0];
+                PKCS7 tsToken = si.getTsToken();
+                SignerInfo tsSi = tsToken.getSignerInfos()[0];
+                try {
+                    validateCertChain(Validator.VAR_TSA_SERVER,
+                            tsSi.getCertificateChain(tsToken), null);
+                } catch (Exception e) {
+                    tsaChainNotValidated = true;
+                    tsaChainNotValidatedReason = e;
+                }
+            } catch (Exception e) {
+                if (debug) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
         // no IOException thrown in the follow try clause, so disable
         // the try clause.
         // try {
@@ -1586,8 +1688,10 @@
             }
 
             boolean warningAppeared = false;
-            if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
-                    notYetValidCert || chainNotValidated || hasExpiredCert) {
+            if (weakAlg != 0 || badKeyUsage || badExtendedKeyUsage
+                    || badNetscapeCertType || notYetValidCert
+                    || chainNotValidated || tsaChainNotValidated
+                    || hasExpiredCert || signerSelfSigned) {
                 if (strict) {
                     System.out.println(rb.getString("jar.signed.with.signer.errors."));
                     System.out.println();
@@ -1623,8 +1727,37 @@
                 }
 
                 if (chainNotValidated) {
+                    System.out.println(String.format(
+                            rb.getString("The.signer.s.certificate.chain.is.invalid.reason.1"),
+                            chainNotValidatedReason.getLocalizedMessage()));
+                }
+
+                if (tsaChainNotValidated) {
+                    System.out.println(String.format(
+                            rb.getString("The.tsa.certificate.chain.is.invalid.reason.1"),
+                            tsaChainNotValidatedReason.getLocalizedMessage()));
+                }
+
+                if (signerSelfSigned) {
                     System.out.println(
-                            rb.getString("The.signer.s.certificate.chain.is.not.validated."));
+                            rb.getString("The.signer.s.certificate.is.self.signed."));
+                }
+
+                if ((weakAlg & 1) == 1) {
+                    System.out.println(String.format(
+                            rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
+                            digestalg, "-digestalg"));
+                }
+
+                if ((weakAlg & 2) == 2) {
+                    System.out.println(String.format(
+                            rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
+                            sigalg, "-sigalg"));
+                }
+                if ((weakAlg & 4) == 4) {
+                    System.out.println(String.format(
+                            rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
+                            tSADigestAlg, "-tsadigestalg"));
                 }
             } else {
                 System.out.println(rb.getString("jar.signed."));
@@ -1700,18 +1833,18 @@
     /**
      * Returns a string of singer info, with a newline at the end
      */
-    private String signerInfo(CodeSigner signer, String tab) {
+    private String signerInfo(CodeSigner signer, String tab) throws Exception {
         if (cacheForSignerInfo.containsKey(signer)) {
             return cacheForSignerInfo.get(signer);
         }
-        StringBuffer s = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         List<? extends Certificate> certs = signer.getSignerCertPath().getCertificates();
         // display the signature timestamp, if present
         Date timestamp;
         Timestamp ts = signer.getTimestamp();
         if (ts != null) {
-            s.append(printTimestamp(tab, ts));
-            s.append('\n');
+            sb.append(printTimestamp(tab, ts));
+            sb.append('\n');
             timestamp = ts.getTimestamp();
         } else {
             timestamp = null;
@@ -1720,28 +1853,41 @@
         // display the certificate(s). The first one is end-entity cert and
         // its KeyUsage should be checked.
         boolean first = true;
+        sb.append(tab).append(rb.getString("...Signer")).append('\n');
         for (Certificate c : certs) {
-            s.append(printCert(tab, c, true, timestamp, first));
-            s.append('\n');
+            sb.append(printCert(false, tab, c, timestamp, first));
+            sb.append('\n');
             first = false;
         }
         try {
-            validateCertChain(certs);
+            validateCertChain(Validator.VAR_CODE_SIGNING, certs, ts);
         } catch (Exception e) {
-            if (debug) {
-                e.printStackTrace();
+            chainNotValidated = true;
+            chainNotValidatedReason = e;
+            sb.append(tab).append(rb.getString(".Invalid.certificate.chain."))
+                    .append(e.getLocalizedMessage()).append("]\n");
+        }
+        if (ts != null) {
+            sb.append(tab).append(rb.getString("...TSA")).append('\n');
+            for (Certificate c : ts.getSignerCertPath().getCertificates()) {
+                sb.append(printCert(true, tab, c, timestamp, false));
+                sb.append('\n');
             }
-            if (e.getCause() != null &&
-                    (e.getCause() instanceof CertificateExpiredException ||
-                     e.getCause() instanceof CertificateNotYetValidException)) {
-                // No more warning, we alreay have hasExpiredCert or notYetValidCert
-            } else {
-                chainNotValidated = true;
-                s.append(tab + rb.getString(".CertPath.not.validated.") +
-                        e.getLocalizedMessage() + "]\n");   // TODO
+            try {
+                validateCertChain(Validator.VAR_TSA_SERVER,
+                        ts.getSignerCertPath().getCertificates(), null);
+            } catch (Exception e) {
+                tsaChainNotValidated = true;
+                tsaChainNotValidatedReason = e;
+                sb.append(tab).append(rb.getString(".Invalid.TSA.certificate.chain."))
+                        .append(e.getLocalizedMessage()).append("]\n");
             }
         }
-        String result = s.toString();
+        if (certs.size() == 1
+                && KeyStoreUtil.isSelfSigned((X509Certificate)certs.get(0))) {
+            signerSelfSigned = true;
+        }
+        String result = sb.toString();
         cacheForSignerInfo.put(signer, result);
         return result;
     }
@@ -1793,9 +1939,6 @@
         }
 
         try {
-
-            certificateFactory = CertificateFactory.getInstance("X.509");
-            validator = CertPathValidator.getInstance("PKIX");
             Set<TrustAnchor> tas = new HashSet<>();
             try {
                 KeyStore caks = KeyStoreUtil.getCacertsKeyStore();
@@ -1871,7 +2014,7 @@
                 }
             } finally {
                 try {
-                    pkixParameters = new PKIXParameters(tas);
+                    pkixParameters = new PKIXBuilderParameters(tas, null);
                     pkixParameters.setRevocationEnabled(false);
                 } catch (InvalidAlgorithmParameterException ex) {
                     // Only if tas is empty
@@ -1987,7 +2130,7 @@
         }
     }
 
-    void getAliasInfo(String alias) {
+    void getAliasInfo(String alias) throws Exception {
 
         Key key = null;
 
@@ -2033,21 +2176,18 @@
 
             // We don't meant to print anything, the next call
             // checks validity and keyUsage etc
-            printCert("", certChain[0], true, null, true);
+            printCert(false, "", certChain[0], null, true);
 
             try {
-                validateCertChain(Arrays.asList(certChain));
+                validateCertChain(Validator.VAR_CODE_SIGNING,
+                        Arrays.asList(certChain), null);
             } catch (Exception e) {
-                if (debug) {
-                    e.printStackTrace();
-                }
-                if (e.getCause() != null &&
-                        (e.getCause() instanceof CertificateExpiredException ||
-                        e.getCause() instanceof CertificateNotYetValidException)) {
-                    // No more warning, we alreay have hasExpiredCert or notYetValidCert
-                } else {
-                    chainNotValidated = true;
-                }
+                chainNotValidated = true;
+                chainNotValidatedReason = e;
+            }
+
+            if (KeyStoreUtil.isSelfSigned(certChain[0])) {
+                signerSelfSigned = true;
             }
 
             try {
@@ -2101,19 +2241,55 @@
         System.exit(1);
     }
 
-    void validateCertChain(List<? extends Certificate> certs) throws Exception {
-        int cpLen = 0;
-        out: for (; cpLen<certs.size(); cpLen++) {
-            for (TrustAnchor ta: pkixParameters.getTrustAnchors()) {
-                if (ta.getTrustedCert().equals(certs.get(cpLen))) {
-                    break out;
+    /**
+     * Validates a cert chain.
+     *
+     * @param parameter this might be a timestamp
+     */
+    void validateCertChain(String variant, List<? extends Certificate> certs,
+                           Object parameter)
+            throws Exception {
+        try {
+            Validator.getInstance(Validator.TYPE_PKIX,
+                    variant,
+                    pkixParameters)
+                    .validate(certs.toArray(new X509Certificate[certs.size()]),
+                            null, parameter);
+        } catch (Exception e) {
+            if (debug) {
+                e.printStackTrace();
+            }
+
+            // Exception might be dismissed if another warning flag
+            // is already set by printCert. This is only done for
+            // code signing certs.
+
+            if (variant.equals(Validator.VAR_CODE_SIGNING) &&
+                    e instanceof ValidatorException) {
+                // Throw cause if it's CertPathValidatorException,
+                if (e.getCause() != null &&
+                        e.getCause() instanceof CertPathValidatorException) {
+                    e = (Exception) e.getCause();
+                    Throwable t = e.getCause();
+                    if ((t instanceof CertificateExpiredException &&
+                                hasExpiredCert) ||
+                            (t instanceof CertificateNotYetValidException &&
+                                    notYetValidCert)) {
+                        // we already have hasExpiredCert and notYetValidCert
+                        return;
+                    }
+                }
+                if (e instanceof ValidatorException) {
+                    ValidatorException ve = (ValidatorException)e;
+                    if (ve.getErrorType() == ValidatorException.T_EE_EXTENSIONS &&
+                            (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType)) {
+                        // We already have badKeyUsage, badExtendedKeyUsage
+                        // and badNetscapeCertType
+                        return;
+                    }
                 }
             }
-        }
-        if (cpLen > 0) {
-            CertPath cp = certificateFactory.generateCertPath(
-                    (cpLen == certs.size())? certs: certs.subList(0, cpLen));
-            validator.validate(cp, pkixParameters);
+            throw e;
         }
     }
 
--- a/src/share/classes/sun/security/tools/jarsigner/Resources.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/tools/jarsigner/Resources.java	Fri Aug 03 19:50:58 2018 +0100
@@ -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
@@ -199,7 +199,8 @@
         {"certificate.is.not.valid.until",
                 "certificate is not valid until {0}"},
         {"certificate.will.expire.on", "certificate will expire on {0}"},
-        {".CertPath.not.validated.", "[CertPath not validated: "},
+        {".Invalid.certificate.chain.", "[Invalid certificate chain: "},
+        {".Invalid.TSA.certificate.chain.", "[Invalid TSA certificate chain: "},
         {"requesting.a.signature.timestamp",
                 "requesting a signature timestamp"},
         {"TSA.location.", "TSA location: "},
@@ -216,6 +217,8 @@
         {"entry.was.signed.on", "entry was signed on {0}"},
         {"Warning.", "Warning: "},
         {"Error.", "Error: "},
+        {"...Signer", ">>> Signer"},
+        {"...TSA", ">>> TSA"},
         {"This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked.",
                 "This jar contains unsigned entries which have not been integrity-checked. "},
         {"This.jar.contains.entries.whose.signer.certificate.has.expired.",
@@ -224,6 +227,8 @@
                 "This jar contains entries whose signer certificate will expire within six months. "},
         {"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid.",
                 "This jar contains entries whose signer certificate is not yet valid. "},
+        {"This.jar.contains.entries.whose.signer.certificate.is.self.signed.",
+                "This jar contains entries whose signer certificate is self-signed."},
         {"Re.run.with.the.verbose.option.for.more.details.",
                 "Re-run with the -verbose option for more details."},
         {"Re.run.with.the.verbose.and.certs.options.for.more.details.",
@@ -248,14 +253,24 @@
                  "This jar contains entries whose signer certificate's NetscapeCertType extension doesn't allow code signing."},
         {".{0}.extension.does.not.support.code.signing.",
                  "[{0} extension does not support code signing]"},
-        {"The.signer.s.certificate.chain.is.not.validated.",
-                "The signer's certificate chain is not validated."},
-        {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.",
-                 "This jar contains entries whose certificate chain is not validated."},
+        {"The.signer.s.certificate.chain.is.invalid.reason.1",
+                "The signer's certificate chain is invalid. Reason: %s"},
+        {"The.tsa.certificate.chain.is.invalid.reason.1",
+                "The TSA certificate chain is invalid. Reason: %s"},
+        {"The.signer.s.certificate.is.self.signed.",
+                "The signer's certificate is self-signed."},
+        {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
+                "The %1$s algorithm specified for the %2$s option is considered a security risk."},
+        {"This.jar.contains.entries.whose.certificate.chain.is.invalid.reason.1",
+                 "This jar contains entries whose certificate chain is invalid. Reason: %s"},
+        {"This.jar.contains.entries.whose.tsa.certificate.chain.is.invalid.reason.1",
+                "This jar contains entries whose TSA certificate chain is invalid. Reason: %s"},
         {"no.timestamp.signing",
                 "No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
         {"no.timestamp.verifying",
                 "This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
+        {"bad.timestamp.verifying",
+                "This jar contains signatures that include an invalid timestamp. Without a valid timestamp, users may not be able to validate this jar after any of the signer certificates expire (as early as %1$tY-%1$tm-%1$td).\nRerun jarsigner with -J-Djava.security.debug=jar for more information."},
         {"Unknown.password.type.", "Unknown password type: "},
         {"Cannot.find.environment.variable.",
                 "Cannot find environment variable: "},
--- a/src/share/classes/sun/security/tools/keytool/Main.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/tools/keytool/Main.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1352,7 +1352,7 @@
         for (Certificate ca: keyStore.getCertificateChain(alias)) {
             if (ca instanceof X509Certificate) {
                 X509Certificate xca = (X509Certificate)ca;
-                if (!isSelfSigned(xca)) {
+                if (!KeyStoreUtil.isSelfSigned(xca)) {
                     dumpCert(xca, out);
                 }
             }
@@ -2869,7 +2869,7 @@
 
         // if certificate is self-signed, make sure it verifies
         boolean selfSigned = false;
-        if (isSelfSigned(cert)) {
+        if (KeyStoreUtil.isSelfSigned(cert)) {
             cert.verify(cert.getPublicKey());
             selfSigned = true;
         }
@@ -3173,25 +3173,6 @@
     }
 
     /**
-     * Returns true if the certificate is self-signed, false otherwise.
-     */
-    private boolean isSelfSigned(X509Certificate cert) {
-        return signedBy(cert, cert);
-    }
-
-    private boolean signedBy(X509Certificate end, X509Certificate ca) {
-        if (!ca.getSubjectDN().equals(end.getIssuerDN())) {
-            return false;
-        }
-        try {
-            end.verify(ca.getPublicKey());
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
      * Locates a signer for a given certificate from a given keystore and
      * returns the signer's certificate.
      * @param cert the certificate whose signer is searched, not null
@@ -3531,7 +3512,7 @@
             // find a cert in the reply who signs thisCert
             int j;
             for (j=i; j<replyCerts.length; j++) {
-                if (signedBy(thisCert, (X509Certificate)replyCerts[j])) {
+                if (KeyStoreUtil.signedBy(thisCert, (X509Certificate)replyCerts[j])) {
                     tmpCert = replyCerts[i];
                     replyCerts[i] = replyCerts[j];
                     replyCerts[j] = tmpCert;
@@ -3689,7 +3670,7 @@
     private boolean buildChain(Pair<String,X509Certificate> certToVerify,
             Vector<Pair<String,X509Certificate>> chain,
             Hashtable<Principal, Vector<Pair<String,X509Certificate>>> certs) {
-        if (isSelfSigned(certToVerify.snd)) {
+        if (KeyStoreUtil.isSelfSigned(certToVerify.snd)) {
             // reached self-signed root cert;
             // no verification needed because it's trusted.
             chain.addElement(certToVerify);
--- a/src/share/classes/sun/security/util/SignatureFileVerifier.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java	Fri Aug 03 19:50:58 2018 +0100
@@ -719,7 +719,8 @@
             if (signers == null) {
                 signers = new ArrayList<>();
             }
-            // Append the new code signer
+            // Append the new code signer. If timestamp is invalid, this
+            // jar will be treated as unsigned.
             signers.add(new CodeSigner(certChain, info.getTimestamp()));
 
             if (debug != null) {
--- a/src/solaris/native/java/net/NetworkInterface.c	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/solaris/native/java/net/NetworkInterface.c	Fri Aug 03 19:50:58 2018 +0100
@@ -335,10 +335,18 @@
     jobject obj = NULL;
     jboolean match = JNI_FALSE;
 #if defined(AF_INET6)
-    int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6;
+    int family = getInetAddress_family(env, iaObj);
     JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+
+    if (family == IPv4) {
+        family = AF_INET;
+    } else if (family == IPv6) {
+        family = AF_INET6;
+    } else {
+        return NULL; // Invalid family
+    }
 #else
-    int family =  AF_INET;
+    int family = AF_INET;
 #endif
     ifs = enumInterfaces(env);
     if (ifs == NULL) {
@@ -357,7 +365,9 @@
                     int address1 = htonl(
                         ((struct sockaddr_in *)addrP->addr)->sin_addr.s_addr);
                     int address2 = getInetAddress_addr(env, iaObj);
-                    JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+                    if ((*env)->ExceptionCheck(env)) {
+                        goto cleanup;
+                    }
                     if (address1 == address2) {
                         match = JNI_TRUE;
                         break;
@@ -402,6 +412,7 @@
         obj = createNetworkInterface(env, curr);
     }
 
+cleanup:
     // release the interface list
     freeif(ifs);
 
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -677,7 +677,7 @@
         }
 
         try {
-            return invoke(new Callable<File[]>() {
+                File[] files = invoke(new Callable<File[]>() {
                 public File[] call() throws InterruptedException {
                     if (!isDirectory()) {
                         return null;
@@ -732,6 +732,9 @@
                         : list.toArray(new ShellFolder[list.size()]);
                 }
             }, InterruptedException.class);
+
+            return Win32ShellFolderManager2.checkFiles(files);
+
         } catch (InterruptedException e) {
             return new File[0];
         }
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -379,21 +379,30 @@
         return null;
     }
 
-    private File checkFile(File file) {
+    private static File checkFile(File file) {
         SecurityManager sm = System.getSecurityManager();
         return (sm == null || file == null) ? file : checkFile(file, sm);
     }
 
-    private File checkFile(File file, SecurityManager sm) {
+    private static File checkFile(File file, SecurityManager sm) {
         try {
             sm.checkRead(file.getPath());
+
+            if (file instanceof Win32ShellFolder2) {
+                Win32ShellFolder2 f = (Win32ShellFolder2)file;
+                if (f.isLink()) {
+                    Win32ShellFolder2 link = (Win32ShellFolder2)f.getLinkLocation();
+                    if (link != null)
+                        sm.checkRead(link.getPath());
+                }
+            }
             return file;
         } catch (SecurityException se) {
             return null;
         }
     }
 
-    private File[] checkFiles(File[] files) {
+    static File[] checkFiles(File[] files) {
         SecurityManager sm = System.getSecurityManager();
         if (sm == null || files == null || files.length == 0) {
             return files;
@@ -401,7 +410,7 @@
         return checkFiles(Arrays.stream(files), sm);
     }
 
-    private File[] checkFiles(List<File> files) {
+    private static File[] checkFiles(List<File> files) {
         SecurityManager sm = System.getSecurityManager();
         if (sm == null || files.isEmpty()) {
             return files.toArray(new File[files.size()]);
@@ -409,7 +418,7 @@
         return checkFiles(files.stream(), sm);
     }
 
-    private File[] checkFiles(Stream<File> filesStream, SecurityManager sm) {
+    private static File[] checkFiles(Stream<File> filesStream, SecurityManager sm) {
         return filesStream.filter((file) -> checkFile(file, sm) != null)
                 .toArray(File[]::new);
     }
--- a/src/windows/native/java/net/NetworkInterface.c	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/windows/native/java/net/NetworkInterface.c	Fri Aug 03 19:50:58 2018 +0100
@@ -287,6 +287,7 @@
             if (curr->name == NULL || curr->displayName == NULL) {
                 if (curr->name) free(curr->name);
                 if (curr->displayName) free(curr->displayName);
+                free(curr);
                 curr = NULL;
             }
         }
@@ -593,7 +594,10 @@
             /* default ctor will set family to AF_INET */
 
             setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
-            JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+            if ((*env)->ExceptionCheck(env)) {
+                free_netaddr(netaddrP);
+                return NULL;
+            }
             if (addrs->mask != -1) {
               ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
               if (ibObj == NULL) {
@@ -607,7 +611,10 @@
                 return NULL;
               }
               setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
-              JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+              if ((*env)->ExceptionCheck(env)) {
+                  free_netaddr(netaddrP);
+                  return NULL;
+              }
               (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
               (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
               (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
@@ -618,6 +625,7 @@
             if (iaObj) {
                 int ret = setInet6Address_ipaddress(env, iaObj,  (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
                 if (ret == JNI_FALSE) {
+                    free_netaddr(netaddrP);
                     return NULL;
                 }
 
--- a/src/windows/native/java/net/NetworkInterface_winXP.c	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/windows/native/java/net/NetworkInterface_winXP.c	Fri Aug 03 19:50:58 2018 +0100
@@ -488,8 +488,9 @@
     jobjectArray addrArr, bindsArr, childArr;
     netaddr *addrs;
     jint addr_index;
-    int netaddrCount=ifs->naddrs;
-    netaddr *netaddrP=ifs->addrs;
+    int netaddrCount = ifs->naddrs;
+    netaddr *netaddrP = ifs->addrs;
+    netaddr *netaddrPToFree = NULL;
     jint bind_index;
 
     /*
@@ -520,21 +521,23 @@
      * Note that 0 is a valid number of addresses.
      */
     if (netaddrCount < 0) {
-        netaddrCount = enumAddresses_win(env, ifs, &netaddrP);
+        netaddrCount = enumAddresses_win(env, ifs, &netaddrPToFree);
         if (netaddrCount == -1) {
             return NULL;
         }
+        netaddrP = netaddrPToFree;
     }
 
     addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
     if (addrArr == NULL) {
+        free_netaddr(netaddrPToFree);
         return NULL;
     }
 
     bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
     if (bindsArr == NULL) {
-      free_netaddr(netaddrP);
-      return NULL;
+        free_netaddr(netaddrPToFree);
+        return NULL;
     }
 
     addrs = netaddrP;
@@ -546,26 +549,32 @@
         if (addrs->addr.him.sa_family == AF_INET) {
             iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
             if (iaObj == NULL) {
+                free_netaddr(netaddrPToFree);
                 return NULL;
             }
             /* default ctor will set family to AF_INET */
 
             setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
-
-            JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+            if ((*env)->ExceptionCheck(env)) {
+                free_netaddr(netaddrPToFree);
+                return NULL;
+            }
             ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
             if (ibObj == NULL) {
-              free_netaddr(netaddrP);
-              return NULL;
+                free_netaddr(netaddrPToFree);
+                return NULL;
             }
             (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
             ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
             if (ia2Obj == NULL) {
-              free_netaddr(netaddrP);
-              return NULL;
+                free_netaddr(netaddrPToFree);
+                return NULL;
             }
             setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
-            JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+            if ((*env)->ExceptionCheck(env)) {
+                free_netaddr(netaddrPToFree);
+                return NULL;
+            }
             (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
             (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
             (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
@@ -574,10 +583,12 @@
             int ret;
             iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
             if (iaObj == NULL) {
+                free_netaddr(netaddrPToFree);
                 return NULL;
             }
             ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
             if (ret == JNI_FALSE) {
+                free_netaddr(netaddrPToFree);
                 return NULL;
             }
             scope = addrs->addr.him6.sin6_scope_id;
@@ -587,8 +598,8 @@
             }
             ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
             if (ibObj == NULL) {
-              free_netaddr(netaddrP);
-              return NULL;
+                free_netaddr(netaddrPToFree);
+                return NULL;
             }
             (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
             (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
@@ -601,6 +612,8 @@
     (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
     (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
 
+    free_netaddr(netaddrPToFree);
+
     /*
      * Windows doesn't have virtual interfaces, so child array
      * is always empty.
@@ -640,7 +653,7 @@
     }
 
     /* if found create a NetworkInterface */
-    if (curr != NULL) {;
+    if (curr != NULL) {
         netifObj = createNetworkInterfaceXP(env, curr);
     }
 
@@ -767,6 +780,7 @@
     /* allocate a NetworkInterface array */
     netIFArr = (*env)->NewObjectArray(env, count, cls, NULL);
     if (netIFArr == NULL) {
+        free_netif(ifList);
         return NULL;
     }
 
@@ -781,6 +795,7 @@
 
         netifObj = createNetworkInterfaceXP(env, curr);
         if (netifObj == NULL) {
+            free_netif(ifList);
             return NULL;
         }
 
--- a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c	Fri Aug 03 19:50:58 2018 +0100
@@ -445,7 +445,6 @@
                         "Protocol family not supported");
         return;
     }
-    JNU_CHECK_EXCEPTION(env);
     if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
         return;
--- a/src/windows/native/sun/security/mscapi/security.cpp	Wed Aug 01 03:36:32 2018 -0700
+++ b/src/windows/native/sun/security/mscapi/security.cpp	Fri Aug 03 19:50:58 2018 +0100
@@ -183,7 +183,6 @@
 {
 
     HCRYPTPROV hCryptProv = NULL;
-    BYTE*      pbData = NULL;
     jbyte*     reseedBytes = NULL;
     jbyte*     seedBytes = NULL;
     jbyteArray result = NULL;
@@ -227,28 +226,17 @@
 
             result = NULL;
 
-        } else if (length > 0) {
+        } else {
 
-            pbData = new (env) BYTE[length];
-            if (pbData == NULL) {
-                __leave;
+            if (length > 0) {
+                seed = env->NewByteArray(length);
+                if (seed == NULL) {
+                    __leave;
+                }
+            } else {
+                length = env->GetArrayLength(seed);
             }
 
-            if (::CryptGenRandom(
-                hCryptProv,
-                length,
-                pbData) == FALSE) {
-
-                ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
-                __leave;
-            }
-
-            result = env->NewByteArray(length);
-            env->SetByteArrayRegion(result, 0, length, (jbyte*) pbData);
-
-        } else { // length == 0
-
-            length = env->GetArrayLength(seed);
             if ((seedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
                 __leave;
             }
@@ -273,9 +261,6 @@
         if (reseedBytes)
             env->ReleaseByteArrayElements(seed, reseedBytes, JNI_ABORT);
 
-        if (pbData)
-            delete [] pbData;
-
         if (seedBytes)
             env->ReleaseByteArrayElements(seed, seedBytes, 0); // update orig
 
--- a/test/javax/sound/midi/Gervill/RiffReaderWriter/Skip.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/javax/sound/midi/Gervill/RiffReaderWriter/Skip.java	Fri Aug 03 19:50:58 2018 +0100
@@ -27,9 +27,8 @@
 import java.io.File;
 import java.io.FileInputStream;
 
-import javax.sound.sampled.*;
-
-import com.sun.media.sound.*;
+import com.sun.media.sound.RIFFReader;
+import com.sun.media.sound.RIFFWriter;
 
 public class Skip {
 
@@ -40,6 +39,11 @@
     }
 
     public static void main(String[] args) throws Exception {
+        test(false);
+        test(true);
+    }
+
+    private static void test(boolean customStream) throws Exception {
         RIFFWriter writer = null;
         RIFFReader reader = null;
         File tempfile = File.createTempFile("test",".riff");
@@ -51,7 +55,17 @@
             chunk.write((byte)44);
             writer.close();
             writer = null;
-            FileInputStream fis = new FileInputStream(tempfile);
+            final FileInputStream fis;
+            if (customStream) {
+                fis = new FileInputStream(tempfile);
+            } else {
+                fis = new FileInputStream(tempfile) {
+                    @Override
+                    public long skip(long n) {
+                        return 0;
+                    }
+                };
+            }
             reader = new RIFFReader(fis);
             RIFFReader readchunk = reader.nextChunk();
             reader.skip(1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/InMemoryJavaCompiler.java	Fri Aug 03 19:50:58 2018 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2013, 2018, 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.
+ */
+
+package jdk.testlibrary;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.net.URI;
+import java.util.Arrays;
+
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.FileObject;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+/**
+ * {@code InMemoryJavaCompiler} can be used for compiling a {@link
+ * CharSequence} to a {@code byte[]}.
+ *
+ * The compiler will not use the file system at all, instead using a {@link
+ * ByteArrayOutputStream} for storing the byte code. For the source code, any
+ * kind of {@link CharSequence} can be used, e.g. {@link String}, {@link
+ * StringBuffer} or {@link StringBuilder}.
+ *
+ * The {@code InMemoryCompiler} can easily be used together with a {@code
+ * ByteClassLoader} to easily compile and load source code in a {@link String}:
+ *
+ * <pre>
+ * {@code
+ * import com.oracle.java.testlibrary.InMemoryJavaCompiler;
+ * import com.oracle.java.testlibrary.ByteClassLoader;
+ *
+ * class Example {
+ *     public static void main(String[] args) {
+ *         String className = "Foo";
+ *         String sourceCode = "public class " + className + " {" +
+ *                             "    public void bar() {" +
+ *                             "        System.out.println("Hello from bar!");" +
+ *                             "    }" +
+ *                             "}";
+ *         byte[] byteCode = InMemoryJavaCompiler.compile(className, sourceCode);
+ *         Class fooClass = ByteClassLoader.load(className, byteCode);
+ *     }
+ * }
+ * }
+ * </pre>
+ */
+public class InMemoryJavaCompiler {
+    private static class MemoryJavaFileObject extends SimpleJavaFileObject {
+        private final String className;
+        private final CharSequence sourceCode;
+        private final ByteArrayOutputStream byteCode;
+
+        public MemoryJavaFileObject(String className, CharSequence sourceCode) {
+            super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
+            this.className = className;
+            this.sourceCode = sourceCode;
+            this.byteCode = new ByteArrayOutputStream();
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return sourceCode;
+        }
+
+        @Override
+        public OutputStream openOutputStream() throws IOException {
+            return byteCode;
+        }
+
+        public byte[] getByteCode() {
+            return byteCode.toByteArray();
+        }
+
+        public String getClassName() {
+            return className;
+        }
+    }
+
+    private static class FileManagerWrapper extends ForwardingJavaFileManager {
+        private MemoryJavaFileObject file;
+
+        public FileManagerWrapper(MemoryJavaFileObject file) {
+            super(getCompiler().getStandardFileManager(null, null, null));
+            this.file = file;
+        }
+
+        @Override
+        public JavaFileObject getJavaFileForOutput(Location location, String className,
+                                                   Kind kind, FileObject sibling)
+            throws IOException {
+            if (!file.getClassName().equals(className)) {
+                throw new IOException("Expected class with name " + file.getClassName() +
+                                      ", but got " + className);
+            }
+            return file;
+        }
+    }
+
+    /**
+     * Compiles the class with the given name and source code.
+     *
+     * @param className The name of the class
+     * @param sourceCode The source code for the class with name {@code className}
+     * @throws RuntimeException if the compilation did not succeed
+     * @return The resulting byte code from the compilation
+     */
+    public static byte[] compile(String className, CharSequence sourceCode) {
+        MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode);
+        CompilationTask task = getCompilationTask(file);
+
+        if(!task.call()) {
+            throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode);
+        }
+
+        return file.getByteCode();
+    }
+
+    private static JavaCompiler getCompiler() {
+        return ToolProvider.getSystemJavaCompiler();
+    }
+
+    private static CompilationTask getCompilationTask(MemoryJavaFileObject file) {
+        return getCompiler().getTask(null, new FileManagerWrapper(file), null, null, null, Arrays.asList(file));
+    }
+}
--- a/test/lib/testlibrary/jdk/testlibrary/JarUtils.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/JarUtils.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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,16 +23,21 @@
 
 package jdk.testlibrary;
 
+import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -45,6 +50,72 @@
 public final class JarUtils {
 
     /**
+     * Creates a JAR file.
+     *
+     * Equivalent to {@code jar cfm <jarfile> <manifest> -C <dir> file...}
+     *
+     * The input files are resolved against the given directory. Any input
+     * files that are directories are processed recursively.
+     */
+    public static void createJarFile(Path jarfile, Manifest man, Path dir, Path... file)
+        throws IOException
+    {
+        // create the target directory
+        Path parent = jarfile.getParent();
+        if (parent != null)
+            Files.createDirectories(parent);
+
+        List<Path> entries = new ArrayList<>();
+        for (Path entry : file) {
+            Files.find(dir.resolve(entry), Integer.MAX_VALUE,
+                        (p, attrs) -> attrs.isRegularFile())
+                    .map(e -> dir.relativize(e))
+                    .forEach(entries::add);
+        }
+
+        try (OutputStream out = Files.newOutputStream(jarfile);
+             JarOutputStream jos = new JarOutputStream(out))
+        {
+            if (man != null) {
+                JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
+                jos.putNextEntry(je);
+                man.write(jos);
+                jos.closeEntry();
+            }
+
+            for (Path entry : entries) {
+                String name = toJarEntryName(entry);
+                jos.putNextEntry(new JarEntry(name));
+                Files.copy(dir.resolve(entry), jos);
+                jos.closeEntry();
+            }
+        }
+    }
+
+   /**
+     * Creates a JAR file.
+     *
+     * Equivalent to {@code jar cf <jarfile>  -C <dir> file...}
+     *
+     * The input files are resolved against the given directory. Any input
+     * files that are directories are processed recursively.
+     */
+    public static void createJarFile(Path jarfile, Path dir, Path... file)
+        throws IOException
+    {
+        createJarFile(jarfile, null, dir, file);
+    }
+
+    /**
+     * Creates a JAR file from the contents of a directory.
+     *
+     * Equivalent to {@code jar cf <jarfile> -C <dir> .}
+     */
+    public static void createJarFile(Path jarfile, Path dir) throws IOException {
+        createJarFile(jarfile, dir, Paths.get("."));
+    }
+
+    /**
      * Create jar file with specified files. If a specified file does not exist,
      * a new jar entry will be created with the file name itself as the content.
      */
@@ -126,6 +197,11 @@
         changes = new HashMap<>(changes);
 
         System.out.printf("Creating %s from %s...\n", dest, src);
+
+        if (dest.equals(src)) {
+            throw new IOException("src and dest cannot be the same");
+        }
+
         try (JarOutputStream jos = new JarOutputStream(
                 new FileOutputStream(dest))) {
 
@@ -153,6 +229,24 @@
         System.out.println();
     }
 
+    /**
+     * Update the Manifest inside a jar.
+     *
+     * @param src the original jar file name
+     * @param dest the new jar file name
+     * @param man the Manifest
+     *
+     * @throws IOException
+     */
+    public static void updateManifest(String src, String dest, Manifest man)
+            throws IOException {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        man.write(bout);
+        Map<String, Object> map = new HashMap<>();
+        map.put(JarFile.MANIFEST_NAME, bout.toByteArray());
+        updateJar(src, dest, map);
+    }
+
     private static void updateEntry(JarOutputStream jos, String name, Object content)
            throws IOException {
         if (content instanceof Boolean) {
@@ -172,4 +266,14 @@
             }
         }
     }
+
+    /**
+     * Map a file path to the equivalent name in a JAR file
+     */
+    private static String toJarEntryName(Path file) {
+        Path normalized = file.normalize();
+        return normalized.subpath(0, normalized.getNameCount())  // drop root
+                .toString()
+                .replace(File.separatorChar, '/');
+    }
 }
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java	Fri Aug 03 19:50:58 2018 +0100
@@ -39,7 +39,7 @@
 
     private final String stdout;
     private final String stderr;
-    private final int exitValue;
+    private final int exitValue;    // useless now. output contains exit value.
 
     /**
      * Create an OutputAnalyzer, a utility class for verifying output and exit
--- a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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,6 +25,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
@@ -353,9 +354,31 @@
      * @return The output from the process.
      */
     public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
+        return executeProcess(pb, null);
+    }
+
+    /**
+     * Executes a process, pipe some text into its STDIN, waits for it
+     * to finish and returns the process output. The process will have exited
+     * before this method returns.
+     * @param pb The ProcessBuilder to execute.
+     * @param input The text to pipe into STDIN. Can be null.
+     * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+     */
+    public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input)
+            throws Throwable {
         OutputAnalyzer output = null;
+        Process p = null;
         try {
-            output = new OutputAnalyzer(pb.start());
+            p = pb.start();
+            if (input != null) {
+                try (OutputStream os = p.getOutputStream();
+                        PrintStream ps = new PrintStream(os)) {
+                    ps.print(input);
+                    ps.flush();
+                }
+            }
+            output = new OutputAnalyzer(p);
             return output;
         } catch (Throwable t) {
             System.out.println("executeProcess() failed: " + t);
--- a/test/lib/testlibrary/jdk/testlibrary/SecurityTools.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/lib/testlibrary/jdk/testlibrary/SecurityTools.java	Fri Aug 03 19:50:58 2018 +0100
@@ -49,10 +49,7 @@
                 launcher.addToolArg(arg);
             }
         }
-        String[] cmds = launcher.getCommand();
-        String cmdLine = Arrays.stream(cmds).collect(Collectors.joining(" "));
-        System.out.println("Command line: [" + cmdLine + "]");
-        return new ProcessBuilder(cmds);
+        return new ProcessBuilder(launcher.getCommand());
     }
 
     // keytool
@@ -69,7 +66,7 @@
         pb.redirectInput(ProcessBuilder.Redirect.from(new File(RESPONSE_FILE)));
 
         try {
-            return ProcessTools.executeProcess(pb);
+            return execute(pb);
         } catch (Throwable t) {
             throw new RuntimeException("keytool failure: " + t);
         } finally {
@@ -101,11 +98,20 @@
 
     public static OutputAnalyzer jarsigner(List<String> args)
             throws Exception {
+        return execute(getProcessBuilder("jarsigner", args));
+    }
+
+    private static OutputAnalyzer execute(ProcessBuilder pb) throws Exception {
         try {
-            return ProcessTools.executeProcess(
-                getProcessBuilder("jarsigner", args));
+            OutputAnalyzer oa = ProcessTools.executeCommand(pb);
+            System.out.println("Exit value: " + oa.getExitValue());
+            return oa;
         } catch (Throwable t) {
-            throw new RuntimeException("jarsigner error: " + t);
+            if (t instanceof Exception) {
+                throw (Exception) t;
+            } else {
+                throw new Exception(t);
+            }
         }
     }
 
Binary file test/lib/testlibrary/jdk/testlibrary/testkeys has changed
--- a/test/sun/rmi/transport/tcp/DisableRMIOverHttp/DisableRMIOverHTTPTest.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/DisableRMIOverHTTPTest.java	Fri Aug 03 19:50:58 2018 +0100
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8193833
+ * @bug 8158963
  *
  * @summary Disable RMI over HTTP by default
  *
--- a/test/sun/security/tools/jarsigner/TimestampCheck.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/TimestampCheck.java	Fri Aug 03 19:50:58 2018 +0100
@@ -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
@@ -22,6 +22,8 @@
  */
 
 import com.sun.net.httpserver.*;
+
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -36,16 +38,18 @@
 import java.security.PrivateKey;
 import java.security.Signature;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.List;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
 import sun.misc.IOUtils;
-import jdk.testlibrary.*;
+import jdk.testlibrary.SecurityTools;
+import jdk.testlibrary.OutputAnalyzer;
 import jdk.testlibrary.JarUtils;
 import sun.security.pkcs.ContentInfo;
 import sun.security.pkcs.PKCS7;
@@ -58,9 +62,12 @@
 import sun.security.x509.AlgorithmId;
 import sun.security.x509.X500Name;
 
+import jdk.testlibrary.Utils;
+
 /*
  * @test
  * @bug 6543842 6543440 6939248 8009636 8024302 8163304 8169911 8169688 8171121
+ *      8180289
  * @summary checking response of timestamp
  * @modules java.base/sun.security.pkcs
  *          java.base/sun.security.timestamp
@@ -68,7 +75,7 @@
  *          java.base/sun.security.util
  *          java.base/sun.security.tools.keytool
  * @library /lib/testlibrary
- * @run main/timeout=600 TimestampCheck
+ * @run main/othervm/timeout=600 TimestampCheck
  */
 public class TimestampCheck {
 
@@ -114,12 +121,12 @@
          */
         byte[] sign(byte[] input, String path) throws Exception {
             DerValue value = new DerValue(input);
-            System.err.println("\nIncoming Request\n===================");
-            System.err.println("Version: " + value.data.getInteger());
+            System.out.println("\nIncoming Request\n===================");
+            System.out.println("Version: " + value.data.getInteger());
             DerValue messageImprint = value.data.getDerValue();
             AlgorithmId aid = AlgorithmId.parse(
                     messageImprint.data.getDerValue());
-            System.err.println("AlgorithmId: " + aid);
+            System.out.println("AlgorithmId: " + aid);
 
             ObjectIdentifier policyId = new ObjectIdentifier(defaultPolicyId);
             BigInteger nonce = null;
@@ -127,25 +134,24 @@
                 DerValue v = value.data.getDerValue();
                 if (v.tag == DerValue.tag_Integer) {
                     nonce = v.getBigInteger();
-                    System.err.println("nonce: " + nonce);
+                    System.out.println("nonce: " + nonce);
                 } else if (v.tag == DerValue.tag_Boolean) {
-                    System.err.println("certReq: " + v.getBoolean());
+                    System.out.println("certReq: " + v.getBoolean());
                 } else if (v.tag == DerValue.tag_ObjectId) {
                     policyId = v.getOID();
-                    System.err.println("PolicyID: " + policyId);
+                    System.out.println("PolicyID: " + policyId);
                 }
             }
 
-            System.err.println("\nResponse\n===================");
+            System.out.println("\nResponse\n===================");
             FileInputStream is = new FileInputStream(keystore);
             KeyStore ks = KeyStore.getInstance("JCEKS");
             ks.load(is, "changeit".toCharArray());
             is.close();
 
-            String alias = "ts";
-            if (path.startsWith("bad") || path.equals("weak")) {
-                alias = "ts" + path;
-            }
+            // If path starts with "ts", use the TSA it points to.
+            // Otherwise, always use "ts".
+            String alias = path.startsWith("ts") ? path : "ts";
 
             if (path.equals("diffpolicy")) {
                 policyId = new ObjectIdentifier(defaultPolicyId);
@@ -192,8 +198,11 @@
 
             tst.putInteger(1);
 
-            Calendar cal = Calendar.getInstance();
-            tst.putGeneralizedTime(cal.getTime());
+            Instant instant = Instant.now();
+            if (path.equals("tsold")) {
+                instant = instant.minus(20, ChronoUnit.DAYS);
+            }
+            tst.putGeneralizedTime(Date.from(instant));
 
             if (path.equals("diffnonce")) {
                 tst.putInteger(1234);
@@ -220,10 +229,10 @@
                     "1.2.840.113549.1.9.16.1.4"),
                     new DerValue(tstInfo2.toByteArray()));
 
-            System.err.println("Signing...");
-            System.err.println(new X500Name(signer
+            System.out.println("Signing...");
+            System.out.println(new X500Name(signer
                     .getIssuerX500Principal().getName()));
-            System.err.println(signer.getSerialNumber());
+            System.out.println(signer.getSerialNumber());
 
             SignerInfo signerInfo = new SignerInfo(
                     new X500Name(signer.getIssuerX500Principal().getName()),
@@ -296,24 +305,52 @@
 
         prepare();
 
-        try (Handler tsa = Handler.init(0, "tsks");) {
+        try (Handler tsa = Handler.init(0, "ks");) {
             tsa.start();
             int port = tsa.getPort();
 
             host = "http://localhost:" + port + "/";
 
             if (args.length == 0) {         // Run this test
-                sign("none")
+
+                sign("normal")
+                        .shouldNotContain("Warning")
+                        .shouldHaveExitValue(0);
+
+                verify("normal.jar")
+                        .shouldNotContain("Warning")
+                        .shouldHaveExitValue(0);
+
+                // Simulate signing at a previous date:
+                // 1. tsold will create a timestamp of 20 days ago.
+                // 2. oldsigner expired 10 days ago.
+                // jarsigner will show a warning at signing.
+                signVerbose("tsold", "unsigned.jar", "tsold.jar", "oldsigner")
+                        .shouldHaveExitValue(4);
+
+                // It verifies perfectly.
+                verify("tsold.jar", "-verbose", "-certs")
+                        .shouldNotContain("Warning")
+                        .shouldHaveExitValue(0);
+
+                signVerbose(null, "unsigned.jar", "none.jar", "signer")
                         .shouldContain("is not timestamped")
                         .shouldHaveExitValue(0);
 
-                sign("badku")
-                        .shouldHaveExitValue(0);
+                signVerbose(null, "unsigned.jar", "badku.jar", "badku")
+                        .shouldHaveExitValue(8);
                 checkBadKU("badku.jar");
 
-                sign("normal")
-                        .shouldNotContain("is not timestamped")
-                        .shouldHaveExitValue(0);
+                // 8180289: unvalidated TSA cert chain
+                sign("tsnoca")
+                        .shouldContain("TSA certificate chain is invalid")
+                        .shouldHaveExitValue(64);
+
+                verify("tsnoca.jar", "-verbose", "-certs")
+                        .shouldHaveExitValue(64)
+                        .shouldContain("jar verified")
+                        .shouldContain("Invalid TSA certificate chain")
+                        .shouldContain("TSA certificate chain is invalid");
 
                 sign("nononce")
                         .shouldHaveExitValue(1);
@@ -325,11 +362,11 @@
                         .shouldHaveExitValue(1);
                 sign("fullchain")
                         .shouldHaveExitValue(0);   // Success, 6543440 solved.
-                sign("bad1")
+                sign("tsbad1")
                         .shouldHaveExitValue(1);
-                sign("bad2")
+                sign("tsbad2")
                         .shouldHaveExitValue(1);
-                sign("bad3")
+                sign("tsbad3")
                         .shouldHaveExitValue(1);
                 sign("nocert")
                         .shouldHaveExitValue(1);
@@ -341,119 +378,171 @@
                 sign("diffpolicy", "-tsapolicyid", "1.2.3")
                         .shouldHaveExitValue(1);
 
-                sign("tsaalg", "-tsadigestalg", "SHA")
+                sign("sha1alg", "-tsadigestalg", "SHA")
                         .shouldHaveExitValue(0);
-                checkTimestamp("tsaalg.jar", defaultPolicyId, "SHA-1");
+                checkTimestamp("sha1alg.jar", defaultPolicyId, "SHA-1");
 
-                sign("weak", "-digestalg", "MD5",
+                sign("tsweak", "-digestalg", "MD5",
                                 "-sigalg", "MD5withRSA", "-tsadigestalg", "MD5")
-                        .shouldHaveExitValue(0);
-                checkWeak("weak.jar");
+                        .shouldHaveExitValue(68);
+                checkWeak("tsweak.jar");
+
+                signVerbose("tsweak", "unsigned.jar", "tsweak2.jar", "signer")
+                        .shouldHaveExitValue(64)
+                        .shouldContain("TSA certificate chain is invalid");
 
-                signWithAliasAndTsa("halfWeak", "old.jar", "old", "-digestalg", "MD5")
-                        .shouldHaveExitValue(0);
+                // Weak timestamp is an error and jar treated unsigned
+                verify("tsweak2.jar", "-verbose")
+                        .shouldHaveExitValue(16)
+                        .shouldContain("treated as unsigned")
+                        .shouldMatch("Timestamp.*512.*weak");
+
+                signVerbose("normal", "unsigned.jar", "halfWeak.jar", "signer",
+                        "-digestalg", "MD5")
+                        .shouldHaveExitValue(4);
                 checkHalfWeak("halfWeak.jar");
 
                 // sign with DSA key
-                signWithAliasAndTsa("sign1", "old.jar", "dsakey")
+                signVerbose("normal", "unsigned.jar", "sign1.jar", "dsakey")
                         .shouldHaveExitValue(0);
                 // sign with RSAkeysize < 1024
-                signWithAliasAndTsa("sign2", "sign1.jar", "weakkeysize")
-                        .shouldHaveExitValue(0);
+                signVerbose("normal", "sign1.jar", "sign2.jar", "weakkeysize")
+                        .shouldHaveExitValue(4);
                 checkMultiple("sign2.jar");
 
                 // When .SF or .RSA is missing or invalid
                 checkMissingOrInvalidFiles("normal.jar");
+
+                if (Files.exists(Paths.get("ts2.cert"))) {
+                    checkInvalidTsaCertKeyUsage();
+                }
             } else {                        // Run as a standalone server
-                System.err.println("Press Enter to quit server");
+                System.out.println("Press Enter to quit server");
                 System.in.read();
             }
         }
     }
 
+    private static void checkInvalidTsaCertKeyUsage() throws Exception {
+
+        // Hack: Rewrite the TSA cert inside normal.jar into ts2.jar.
+
+        // Both the cert and the serial number must be rewritten.
+        byte[] tsCert = Files.readAllBytes(Paths.get("ts.cert"));
+        byte[] ts2Cert = Files.readAllBytes(Paths.get("ts2.cert"));
+        byte[] tsSerial = getCert(tsCert)
+                .getSerialNumber().toByteArray();
+        byte[] ts2Serial = getCert(ts2Cert)
+                .getSerialNumber().toByteArray();
+
+        byte[] oldBlock;
+        try (JarFile normal = new JarFile("normal.jar")) {
+            oldBlock = Utils.readAllBytes(normal.getInputStream(
+                    normal.getJarEntry("META-INF/SIGNER.RSA")));
+        }
+
+        JarUtils.updateJar("normal.jar", "ts2.jar",
+                mapOf("META-INF/SIGNER.RSA",
+                        updateBytes(updateBytes(oldBlock, tsCert, ts2Cert),
+                                tsSerial, ts2Serial)));
+
+        verify("ts2.jar", "-verbose", "-certs")
+                .shouldHaveExitValue(64)
+                .shouldContain("jar verified")
+                .shouldContain("Invalid TSA certificate chain: Extended key usage does not permit use for TSA server");
+    }
+
+    public static X509Certificate getCert(byte[] data)
+            throws CertificateException, IOException {
+        return (X509Certificate)
+                CertificateFactory.getInstance("X.509")
+                        .generateCertificate(new ByteArrayInputStream(data));
+    }
+
+    private static byte[] updateBytes(byte[] old, byte[] from, byte[] to) {
+        int pos = 0;
+        while (true) {
+            if (pos + from.length > old.length) {
+                return null;
+            }
+            if (Arrays.equals(Arrays.copyOfRange(old, pos, pos+from.length), from)) {
+                byte[] result = old.clone();
+                System.arraycopy(to, 0, result, pos, from.length);
+                return result;
+            }
+            pos++;
+        }
+    }
+
     private static void checkMissingOrInvalidFiles(String s)
             throws Throwable {
-        JarUtils.updateJar(s, "1.jar", "-", "META-INF/OLD.SF");
+
+        JarUtils.updateJar(s, "1.jar", mapOf("META-INF/SIGNER.SF", Boolean.FALSE));
         verify("1.jar", "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
-                .shouldContain("Missing signature-related file META-INF/OLD.SF");
-        JarUtils.updateJar(s, "2.jar", "-", "META-INF/OLD.RSA");
+                .shouldContain("Missing signature-related file META-INF/SIGNER.SF");
+        JarUtils.updateJar(s, "2.jar", mapOf("META-INF/SIGNER.RSA", Boolean.FALSE));
         verify("2.jar", "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
-                .shouldContain("Missing block file for signature-related file META-INF/OLD.SF");
-        JarUtils.updateJar(s, "3.jar", "META-INF/OLD.SF");
+                .shouldContain("Missing block file for signature-related file META-INF/SIGNER.SF");
+        JarUtils.updateJar(s, "3.jar", mapOf("META-INF/SIGNER.SF", "dummy"));
         verify("3.jar", "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
-                .shouldContain("Unparsable signature-related file META-INF/OLD.SF");
-        JarUtils.updateJar(s, "4.jar", "META-INF/OLD.RSA");
+                .shouldContain("Unparsable signature-related file META-INF/SIGNER.SF");
+        JarUtils.updateJar(s, "4.jar", mapOf("META-INF/SIGNER.RSA", "dummy"));
         verify("4.jar", "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
-                .shouldContain("Unparsable signature-related file META-INF/OLD.RSA");
+                .shouldContain("Unparsable signature-related file META-INF/SIGNER.RSA");
     }
 
     static OutputAnalyzer jarsigner(List<String> extra)
-            throws Throwable {
-        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
-                .addVMArg("-Duser.language=en")
-                .addVMArg("-Duser.country=US")
-                .addToolArg("-keystore")
-                .addToolArg("tsks")
-                .addToolArg("-storepass")
-                .addToolArg("changeit");
-        for (String s : extra) {
-            if (s.startsWith("-J")) {
-                launcher.addVMArg(s.substring(2));
-            } else {
-                launcher.addToolArg(s);
-            }
-        }
-        System.err.println("COMMAND: ");
-        for (String cmd : launcher.getCommand()) {
-            System.err.print(cmd + " ");
-        }
-        System.err.println();
-        return ProcessTools.executeCommand(launcher.getCommand());
+            throws Exception {
+        List<String> args = new ArrayList<>(
+                listOf("-keystore", "ks", "-storepass", "changeit"));
+        args.addAll(extra);
+        return SecurityTools.jarsigner(args);
     }
 
     static OutputAnalyzer verify(String file, String... extra)
-            throws Throwable {
+            throws Exception {
         List<String> args = new ArrayList<>();
         args.add("-verify");
+        args.add("-strict");
         args.add(file);
         args.addAll(Arrays.asList(extra));
         return jarsigner(args);
     }
 
-    static void checkBadKU(String file) throws Throwable {
+    static void checkBadKU(String file) throws Exception {
         System.err.println("BadKU: " + file);
         verify(file)
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
                 .shouldContain("re-run jarsigner with debug enabled");
         verify(file, "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("Signed by")
                 .shouldContain("treated as unsigned")
                 .shouldContain("re-run jarsigner with debug enabled");
         verify(file, "-J-Djava.security.debug=jar")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("SignatureException: Key usage restricted")
                 .shouldContain("treated as unsigned")
                 .shouldContain("re-run jarsigner with debug enabled");
     }
 
-    static void checkWeak(String file) throws Throwable {
+    static void checkWeak(String file) throws Exception {
         verify(file)
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
                 .shouldMatch("weak algorithm that is now disabled.")
                 .shouldMatch("Re-run jarsigner with the -verbose option for more details");
         verify(file, "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
                 .shouldMatch("weak algorithm that is now disabled by")
                 .shouldMatch("Digest algorithm: .*weak")
@@ -462,18 +551,18 @@
                 .shouldNotMatch("Timestamp signature algorithm: .*weak.*weak")
                 .shouldMatch("Timestamp signature algorithm: .*key.*weak");
         verify(file, "-J-Djava.security.debug=jar")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldMatch("SignatureException:.*disabled");
     }
 
-    static void checkHalfWeak(String file) throws Throwable {
+    static void checkHalfWeak(String file) throws Exception {
         verify(file)
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
                 .shouldMatch("weak algorithm that is now disabled.")
                 .shouldMatch("Re-run jarsigner with the -verbose option for more details");
         verify(file, "-verbose")
-                .shouldHaveExitValue(0)
+                .shouldHaveExitValue(16)
                 .shouldContain("treated as unsigned")
                 .shouldMatch("weak algorithm that is now disabled by")
                 .shouldMatch("Digest algorithm: .*weak")
@@ -483,7 +572,7 @@
                 .shouldNotMatch("Timestamp signature algorithm: .*key.*weak");
      }
 
-    static void checkMultiple(String file) throws Throwable {
+    static void checkMultiple(String file) throws Exception {
         verify(file)
                 .shouldHaveExitValue(0)
                 .shouldContain("jar verified");
@@ -500,7 +589,7 @@
     static void checkTimestamp(String file, String policyId, String digestAlg)
             throws Exception {
         try (JarFile jf = new JarFile(file)) {
-            JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
+            JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
             try (InputStream is = jf.getInputStream(je)) {
                 byte[] content = IOUtils.readFully(is, -1, true);
                 PKCS7 p7 = new PKCS7(content);
@@ -526,26 +615,38 @@
     static int which = 0;
 
     /**
+     * Sign with a TSA path. Always use alias "signer" to sign "unsigned.jar".
+     * The signed jar name is always path.jar.
+     *
      * @param extra more args given to jarsigner
      */
     static OutputAnalyzer sign(String path, String... extra)
-            throws Throwable {
-        String alias = path.equals("badku") ? "badku" : "old";
-        return signWithAliasAndTsa(path, "old.jar", alias, extra);
+            throws Exception {
+        return signVerbose(
+                path,
+                "unsigned.jar",
+                path + ".jar",
+                "signer",
+                extra);
     }
 
-    static OutputAnalyzer signWithAliasAndTsa (String path, String jar,
-            String alias, String...extra) throws Throwable {
+    static OutputAnalyzer signVerbose(
+            String path,    // TSA URL path
+            String oldJar,
+            String newJar,
+            String alias,   // signer
+            String...extra) throws Exception {
         which++;
-        System.err.println("\n>> Test #" + which + ": " + Arrays.toString(extra));
+        System.out.println("\n>> Test #" + which);
         List<String> args = new ArrayList<>();
-        args.add("-J-Djava.security.egd=file:/dev/./urandom");
+        args.add("-strict");
+        args.add("-verbose");
         args.add("-debug");
         args.add("-signedjar");
-        args.add(path + ".jar");
-        args.add(jar);
+        args.add(newJar);
+        args.add(oldJar);
         args.add(alias);
-        if (!path.equals("none") && !path.equals("badku")) {
+        if (path != null) {
             args.add("-tsa");
             args.add(host + path);
          }
@@ -554,24 +655,54 @@
     }
 
     static void prepare() throws Exception {
-        jdk.testlibrary.JarUtils.createJar("old.jar", "A");
-        Files.deleteIfExists(Paths.get("tsks"));
-        keytool("-alias ca -genkeypair -ext bc -dname CN=CA");
-        keytool("-alias old -genkeypair -dname CN=old");
+        JarUtils.createJar("unsigned.jar", "A");
+        Files.deleteIfExists(Paths.get("ks"));
+        keytool("-alias signer -genkeypair -ext bc -dname CN=signer");
+        keytool("-alias oldsigner -genkeypair -dname CN=oldsigner");
         keytool("-alias dsakey -genkeypair -keyalg DSA -dname CN=dsakey");
         keytool("-alias weakkeysize -genkeypair -keysize 512 -dname CN=weakkeysize");
         keytool("-alias badku -genkeypair -dname CN=badku");
         keytool("-alias ts -genkeypair -dname CN=ts");
-        keytool("-alias tsweak -genkeypair -keysize 512 -dname CN=tsbad1");
+        keytool("-alias tsold -genkeypair -dname CN=tsold");
+        keytool("-alias tsweak -genkeypair -keysize 512 -dname CN=tsweak");
         keytool("-alias tsbad1 -genkeypair -dname CN=tsbad1");
         keytool("-alias tsbad2 -genkeypair -dname CN=tsbad2");
         keytool("-alias tsbad3 -genkeypair -dname CN=tsbad3");
+        keytool("-alias tsnoca -genkeypair -dname CN=tsnoca");
 
-        gencert("old");
+        // tsnoca's issuer will be removed from keystore later
+        keytool("-alias ca -genkeypair -ext bc -dname CN=CA");
+        gencert("tsnoca", "-ext eku:critical=ts");
+        keytool("-delete -alias ca");
+        keytool("-alias ca -genkeypair -ext bc -dname CN=CA -startdate -40d");
+
+        gencert("signer");
+        gencert("oldsigner", "-startdate -30d -validity 20");
         gencert("dsakey");
         gencert("weakkeysize");
         gencert("badku", "-ext ku:critical=keyAgreement");
         gencert("ts", "-ext eku:critical=ts");
+
+
+        for (int i = 0; i < 5; i++) {
+            // Issue another cert for "ts" with a different EKU.
+            // Length might be different because serial number is
+            // random. Try several times until a cert with the same
+            // length is generated so we can substitute ts.cert
+            // embedded in the PKCS7 block with ts2.cert.
+            // If cannot create one, related test will be ignored.
+            keytool("-gencert -alias ca -infile ts.req -outfile ts2.cert " +
+                    "-ext eku:critical=1.3.6.1.5.5.7.3.9");
+            if (Files.size(Paths.get("ts.cert")) != Files.size(Paths.get("ts2.cert"))) {
+                Files.delete(Paths.get("ts2.cert"));
+                System.out.println("Warning: cannot create same length");
+            } else {
+                break;
+            }
+        }
+
+        gencert("tsold", "-ext eku:critical=ts -startdate -40d -validity 45");
+
         gencert("tsweak", "-ext eku:critical=ts");
         gencert("tsbad1");
         gencert("tsbad2", "-ext eku=ts");
@@ -590,8 +721,16 @@
     }
 
     static void keytool(String cmd) throws Exception {
-        cmd = "-keystore tsks -storepass changeit -keypass changeit " +
+        cmd = "-keystore ks -storepass changeit -keypass changeit " +
                 "-keyalg rsa -validity 200 " + cmd;
         sun.security.tools.keytool.Main.main(cmd.split(" "));
     }
+
+    static <K,V> Map<K,V> mapOf(K k1, V v1) {
+        return Collections.singletonMap(k1, v1);
+    }
+
+    static <E> List<E> listOf(E... elements) {
+        return Arrays.asList(elements);
+    }
 }
--- a/test/sun/security/tools/jarsigner/TsacertOptionTest.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/TsacertOptionTest.java	Fri Aug 03 19:50:58 2018 +0100
@@ -46,6 +46,7 @@
             + ".txt";
     private static final String PASSWORD = "changeit";
     private static final String KEYSTORE = "ks.jks";
+    private static final String CA_KEY_ALIAS = "ca";
     private static final String SIGNING_KEY_ALIAS = "sign_alias";
     private static final String TSA_KEY_ALIAS = "ts";
     private static final String KEY_ALG = "RSA";
@@ -73,20 +74,52 @@
 
         // look for free network port for TSA service
         int port = jdk.testlibrary.Utils.getFreePort();
-        String host = jdk.testlibrary.Utils.getHostname();
+        String host = "127.0.0.1";
         String tsaUrl = "http://" + host + ":" + port;
 
         // create key pair for jar signing
         ProcessTools.executeCommand(KEYTOOL,
                 "-genkey",
+                "-alias", CA_KEY_ALIAS,
+                "-keyalg", KEY_ALG,
+                "-keysize", Integer.toString(KEY_SIZE),
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                "-dname", "CN=CA",
+                "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+        ProcessTools.executeCommand(KEYTOOL,
+                "-genkey",
                 "-alias", SIGNING_KEY_ALIAS,
                 "-keyalg", KEY_ALG,
                 "-keysize", Integer.toString(KEY_SIZE),
                 "-keystore", KEYSTORE,
                 "-storepass", PASSWORD,
                 "-keypass", PASSWORD,
-                "-dname", "CN=Test",
-                "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+                "-dname", "CN=Test").shouldHaveExitValue(0);
+        ProcessTools.executeCommand(KEYTOOL,
+                "-certreq",
+                "-alias", SIGNING_KEY_ALIAS,
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                "-file", "certreq").shouldHaveExitValue(0);
+        ProcessTools.executeCommand(KEYTOOL,
+                "-gencert",
+                "-alias", CA_KEY_ALIAS,
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                "-validity", Integer.toString(VALIDITY),
+                "-infile", "certreq",
+                "-outfile", "cert").shouldHaveExitValue(0);
+        ProcessTools.executeCommand(KEYTOOL,
+                "-importcert",
+                "-alias", SIGNING_KEY_ALIAS,
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                "-file", "cert").shouldHaveExitValue(0);
 
         // create key pair for TSA service
         // SubjectInfoAccess extension contains URL to TSA service
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/tools/jarsigner/Warning.java	Fri Aug 03 19:50:58 2018 +0100
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2015, 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
+ * 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.
+ */
+
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.JarUtils;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+/**
+ * @test
+ * @bug 8024302 8026037 8130132
+ * @summary warnings, errors and -strict
+ * @library /lib/testlibrary
+ */
+public class Warning {
+
+    public static void main(String[] args) throws Throwable {
+
+        Files.deleteIfExists(Paths.get("ks"));
+
+        newCert("ca", "-validity 365000");
+
+        recreateJar();
+
+        newCert("a");
+        run("jarsigner", "a.jar a")
+                .shouldContain("is self-signed");
+        run("jarsigner", "a.jar a -strict")
+                .shouldContain("is self-signed")
+                .shouldHaveExitValue(4);
+        // Trusted entry can be self-signed without a warning
+        run("jarsigner", "-verify a.jar")
+                .shouldNotContain("is self-signed")
+                .shouldNotContain("not signed by alias in this keystore");
+        run("keytool", "-delete -alias a");
+        // otherwise a warning will be shown
+        run("jarsigner", "-verify a.jar")
+                .shouldContain("is self-signed")
+                .shouldContain("not signed by alias in this keystore");
+
+        recreateJar();
+
+        newCert("b");
+        issueCert("b");
+        run("jarsigner", "a.jar b")
+                .shouldNotContain("is self-signed");
+        run("jarsigner", "-verify a.jar")
+                .shouldNotContain("is self-signed");
+
+        run("jarsigner", "a.jar b -digestalg MD5")
+                .shouldContain("-digestalg option is considered a security risk.");
+        run("jarsigner", "a.jar b -digestalg MD5 -strict")
+                .shouldHaveExitValue(4)
+                .shouldContain("-digestalg option is considered a security risk.");
+        run("jarsigner", "a.jar b -sigalg MD5withRSA")
+                .shouldContain("-sigalg option is considered a security risk");
+
+        issueCert("b", "-sigalg MD5withRSA");
+        run("jarsigner", "a.jar b")
+                .shouldMatch("chain is invalid. Reason:.*MD5withRSA");
+
+        recreateJar();
+
+        newCert("c", "-keysize 512");
+        issueCert("c");
+        run("jarsigner", "a.jar c")
+                .shouldContain("chain is invalid. " +
+                        "Reason: Algorithm constraints check failed");
+
+        recreateJar();
+
+        newCert("s1"); issueCert("s1", "-startdate 2000/01/01 -validity 36525");
+        run("jarsigner", "a.jar s1")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp").shouldContain("2100-01-01")
+                .shouldNotContain("with signer errors");
+        run("jarsigner", "a.jar s1 -strict")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp").shouldContain("2100-01-01")
+                .shouldNotContain("with signer errors");
+        run("jarsigner", "a.jar s1 -verify")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp").shouldContain("2100-01-01")
+                .shouldNotContain("with signer errors");
+        run("jarsigner", "a.jar s1 -verify -strict")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp").shouldContain("2100-01-01")
+                .shouldNotContain("with signer errors");
+
+        recreateJar();
+
+        newCert("s2"); issueCert("s2", "-validity 100");
+        run("jarsigner", "a.jar s2")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp")
+                .shouldContain("will expire")
+                .shouldNotContain("with signer errors");
+        run("jarsigner", "a.jar s2 -strict")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp")
+                .shouldContain("will expire")
+                .shouldNotContain("with signer errors");
+        run("jarsigner", "a.jar s2 -verify")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp")
+                .shouldContain("will expire")
+                .shouldNotContain("with signer errors");
+        run("jarsigner", "a.jar s2 -verify -strict")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("Error:")
+                .shouldContain("timestamp")
+                .shouldContain("will expire")
+                .shouldNotContain("with signer errors");
+
+        recreateJar();
+
+        newCert("s3"); issueCert("s3", "-startdate -200d -validity 100");
+        run("jarsigner", "a.jar s3")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldContain("has expired")
+                .shouldNotContain("with signer errors")
+                .shouldNotContain("Error:");
+        run("jarsigner", "a.jar s3 -strict")
+                .shouldHaveExitValue(4)
+                .shouldContain("with signer errors")
+                .shouldMatch("(?s).*Error:.*has expired.*Warning:.*");
+        run("jarsigner", "a.jar s3 -verify")
+                .shouldHaveExitValue(0)
+                .shouldContain("Warning:")
+                .shouldNotContain("with signer errors")
+                .shouldNotContain("Error:");
+        run("jarsigner", "a.jar s3 -verify -strict")
+                .shouldHaveExitValue(4)
+                .shouldContain("with signer errors")
+                .shouldMatch("(?s).*Error:.*has expired.*Warning:.*");
+    }
+
+    // Creates a new jar without signature
+    static void recreateJar() throws Exception {
+        JarUtils.createJar("a.jar", "ks");
+    }
+
+    // Creates a self-signed cert for alias with zero or more -genkey options
+    static void newCert(String alias, String... more) throws Throwable {
+        String args = "-genkeypair -alias " + alias + " -dname CN=" + alias;
+        for (String s: more) {
+            args += " " + s;
+        }
+        run("keytool", args).shouldHaveExitValue(0);
+    }
+
+    // Asks ca to issue a cert to alias with zero or more -gencert options
+    static void issueCert(String alias, String...more) throws Throwable {
+        String req = run("keytool", "-certreq -alias " + alias)
+                .shouldHaveExitValue(0).getStdout();
+        String args = "-gencert -alias ca -rfc";
+        for (String s: more) {
+            args += " " + s;
+        }
+        String cert = run("keytool", args, req)
+                .shouldHaveExitValue(0).getStdout();
+        run("keytool", "-import -alias " + alias, cert).shouldHaveExitValue(0);
+    }
+
+    // Runs a java tool with command line arguments
+    static OutputAnalyzer run(String command, String args)
+            throws Throwable {
+        return run(command, args, null);
+    }
+
+    // Runs a java tool with command line arguments and an optional input block
+    static OutputAnalyzer run(String command, String args, String input)
+            throws Throwable {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(command);
+        launcher.addVMArg("-Duser.language=en").addVMArg("-Duser.country=US");
+        switch (command) {
+            case "keytool":
+                for (String s: new String[] {
+                        "-keystore", "ks", "-storepass", "changeit",
+                        "-storetype", "jks",
+                        "-keypass", "changeit", "-keyalg", "rsa", "-debug"}) {
+                    launcher.addToolArg(s);
+                }
+                break;
+            case "jarsigner":
+                for (String s: new String[] {
+                        "-keystore", "ks", "-storepass", "changeit",
+                        "-storetype", "jks"}) {
+                    launcher.addToolArg(s);
+                }
+                break;
+        }
+        for (String arg: args.split(" ")) {
+            launcher.addToolArg(arg);
+        }
+        String[] cmd = launcher.getCommand();
+        ProcessBuilder pb = new ProcessBuilder(cmd);
+        OutputAnalyzer out = ProcessTools.executeProcess(pb, input);
+        System.out.println("======================");
+        System.out.println(Arrays.toString(cmd));
+        String msg = " stdout: [" + out.getStdout() + "];\n"
+                + " stderr: [" + out.getStderr() + "]\n"
+                + " exitValue = " + out.getExitValue() + "\n";
+        System.out.println(msg);
+        return out;
+    }
+}
+
--- a/test/sun/security/tools/jarsigner/checkusage.sh	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/checkusage.sh	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 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
@@ -91,7 +91,7 @@
 #[ $RESULT = 0 ] || exit 2
 
 # Test 3: When no keystore is specified, the error is only
-# "chain not validated"
+# "chain invalid"
 
 $JARSIGNER -strict -verify a.jar
 RESULT=$?
@@ -99,7 +99,7 @@
 #[ $RESULT = 4 ] || exit 3
 
 # Test 4: When unrelated keystore is specified, the error is
-# "chain not validated" and "not alias in keystore"
+# "chain invalid" and "not alias in keystore"
 
 $JARSIGNER -keystore unrelated.jks -strict -verify a.jar
 RESULT=$?
--- a/test/sun/security/tools/jarsigner/concise_jarsigner.sh	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/concise_jarsigner.sh	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2014, 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
@@ -22,10 +22,10 @@
 #
 
 # @test
-# @bug 6802846
+# @bug 6802846 8172529
 # @summary jarsigner needs enhanced cert validation(options)
 #
-# @run shell concise_jarsigner.sh
+# @run shell/timeout=240 concise_jarsigner.sh
 #
 
 if [ "${TESTJAVA}" = "" ] ; then
@@ -47,12 +47,15 @@
 # Choose 1024-bit RSA to make sure it runs fine and fast on all platforms. In
 # fact, every keyalg/keysize combination is OK for this test.
 
-KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore js.jks -keyalg rsa -keysize 1024"
-JAR=$TESTJAVA${FS}bin${FS}jar
-JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
-JAVAC=$TESTJAVA${FS}bin${FS}javac
+TESTTOOLVMOPTS="$TESTTOOLVMOPTS -J-Duser.language=en -J-Duser.country=US"
 
-rm js.jks
+KS=js.ks
+KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS -keyalg rsa -keysize 1024"
+JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}"
+JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -debug"
+JAVAC="$TESTJAVA${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}"
+
+rm $KS
 
 echo class A1 {} > A1.java
 echo class A2 {} > A2.java
@@ -68,14 +71,14 @@
 # First part: output format
 # ==========================================================
 
-$KT -genkeypair -alias a1 -dname CN=a1 -validity 365
-$KT -genkeypair -alias a2 -dname CN=a2 -validity 365
+$KT -genkeypair -alias a1 -dname CN=a1 -validity 366
+$KT -genkeypair -alias a2 -dname CN=a2 -validity 366
 
 # a.jar includes 8 unsigned, 2 signed by a1 and a2, 2 signed by a3
 $JAR cvf a.jar A1.class A2.class
-$JARSIGNER -keystore js.jks -storepass changeit a.jar a1
+$JARSIGNER -keystore $KS -storepass changeit a.jar a1
 $JAR uvf a.jar A3.class A4.class
-$JARSIGNER -keystore js.jks -storepass changeit a.jar a2
+$JARSIGNER -keystore $KS -storepass changeit a.jar a2
 $JAR uvf a.jar A5.class A6.class
 
 # Verify OK
@@ -87,15 +90,15 @@
 [ $? = 20 ] || exit $LINENO
 
 # 16(hasUnsignedEntry)
-$JARSIGNER -verify a.jar -strict -keystore js.jks
+$JARSIGNER -verify a.jar -strict -keystore $KS -storepass changeit
 [ $? = 16 ] || exit $LINENO
 
 # 16(hasUnsignedEntry)+32(notSignedByAlias)
-$JARSIGNER -verify a.jar a1 -strict -keystore js.jks
+$JARSIGNER -verify a.jar a1 -strict -keystore $KS -storepass changeit
 [ $? = 48 ] || exit $LINENO
 
 # 16(hasUnsignedEntry)
-$JARSIGNER -verify a.jar a1 a2 -strict -keystore js.jks
+$JARSIGNER -verify a.jar a1 a2 -strict -keystore $KS -storepass changeit
 [ $? = 16 ] || exit $LINENO
 
 # 12 entries all together
@@ -135,43 +138,52 @@
 [ $LINES = 4 ] || exit $LINENO
 
 # ==========================================================
-# Second part: exit code 2, 4, 8
+# Second part: exit code 2, 4, 8.
 # 16 and 32 already covered in the first part
 # ==========================================================
 
-$KT -genkeypair -alias expired -dname CN=expired -startdate -10m
-$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid -startdate +1m
-$KT -genkeypair -alias badku -dname CN=badku -ext KU=cRLSign -validity 365
-$KT -genkeypair -alias badeku -dname CN=badeku -ext EKU=sa -validity 365
-$KT -genkeypair -alias goodku -dname CN=goodku -ext KU=dig -validity 365
-$KT -genkeypair -alias goodeku -dname CN=goodeku -ext EKU=codesign -validity 365
+$KT -genkeypair -alias ca -dname CN=ca -ext bc -validity 365
+$KT -genkeypair -alias expired -dname CN=expired
+$KT -certreq -alias expired | $KT -gencert -alias ca -startdate -10m | $KT -import -alias expired
+$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid
+$KT -certreq -alias notyetvalid | $KT -gencert -alias ca -startdate +1m | $KT -import -alias notyetvalid
+$KT -genkeypair -alias badku -dname CN=badku
+$KT -certreq -alias badku | $KT -gencert -alias ca -ext KU=cRLSign -validity 365 | $KT -import -alias badku
+$KT -genkeypair -alias badeku -dname CN=badeku
+$KT -certreq -alias badeku | $KT -gencert -alias ca -ext EKU=sa -validity 365 | $KT -import -alias badeku
+$KT -genkeypair -alias goodku -dname CN=goodku
+$KT -certreq -alias goodku | $KT -gencert -alias ca -ext KU=dig -validity 365 | $KT -import -alias goodku
+$KT -genkeypair -alias goodeku -dname CN=goodeku
+$KT -certreq -alias goodeku | $KT -gencert -alias ca -ext EKU=codesign -validity 365 | $KT -import -alias goodeku
 
-# badchain signed by ca, but ca is removed later
-$KT -genkeypair -alias badchain -dname CN=badchain -validity 365
-$KT -genkeypair -alias ca -dname CN=ca -ext bc -validity 365
-$KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \
-        $KT -importcert -alias badchain
-$KT -delete -alias ca
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar expired
+[ $? = 4 ] || exit $LINENO
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar expired
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar notyetvalid
 [ $? = 4 ] || exit $LINENO
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar notyetvalid
-[ $? = 4 ] || exit $LINENO
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar badku
+[ $? = 8 ] || exit $LINENO
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar badku
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar badeku
 [ $? = 8 ] || exit $LINENO
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar badeku
-[ $? = 8 ] || exit $LINENO
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar goodku
+[ $? = 0 ] || exit $LINENO
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar goodku
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar goodeku
 [ $? = 0 ] || exit $LINENO
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar goodeku
-[ $? = 0 ] || exit $LINENO
+# badchain signed by ca1, but ca1 is removed later
+$KT -genkeypair -alias badchain -dname CN=badchain -validity 365
+$KT -genkeypair -alias ca1 -dname CN=ca1 -ext bc -validity 365
+$KT -certreq -alias badchain | $KT -gencert -alias ca1 -validity 365 | \
+        $KT -importcert -alias badchain
+# save ca1.cert for easy replay
+$KT -exportcert -file ca1.cert -alias ca1
+$KT -delete -alias ca1
 
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar badchain
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar badchain
 [ $? = 4 ] || exit $LINENO
 
 $JARSIGNER -verify a.jar
@@ -181,23 +193,55 @@
 # Third part: -certchain test
 # ==========================================================
 
-# altchain signed by ca2, but ca2 is removed later
+# altchain signed by ca2
 $KT -genkeypair -alias altchain -dname CN=altchain -validity 365
 $KT -genkeypair -alias ca2 -dname CN=ca2 -ext bc -validity 365
 $KT -certreq -alias altchain | $KT -gencert -alias ca2 -validity 365 -rfc > certchain
 $KT -exportcert -alias ca2 -rfc >> certchain
-$KT -delete -alias ca2
 
-# Now altchain is still self-signed
-$JARSIGNER -strict -keystore js.jks -storepass changeit a.jar altchain
+# Self-signed cert does not work
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar altchain
+[ $? = 4 ] || exit $LINENO
+
+# -certchain works
+$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
 [ $? = 0 ] || exit $LINENO
 
-# If -certchain is used, then it's bad
-$JARSIGNER -strict -keystore js.jks -storepass changeit -certchain certchain a.jar altchain
+# if ca2 is removed, -certchain still work because altchain is a self-signed entry and
+# it is trusted by jarsigner
+# save ca2.cert for easy replay
+$KT -exportcert -file ca2.cert -alias ca2
+$KT -delete -alias ca2
+$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
+[ $? = 0 ] || exit $LINENO
+
+# if cert is imported, -certchain won't work because this certificate entry is not trusted
+$KT -importcert -file certchain -alias altchain -noprompt
+$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
 [ $? = 4 ] || exit $LINENO
 
 $JARSIGNER -verify a.jar
 [ $? = 0 ] || exit $LINENO
 
+# ==========================================================
+# 8172529
+# ==========================================================
+
+$KT -genkeypair -alias ee -dname CN=ee
+$KT -genkeypair -alias caone -dname CN=caone
+$KT -genkeypair -alias catwo -dname CN=catwo
+
+$KT -certreq -alias ee | $KT -gencert -alias catwo -rfc > ee.cert
+$KT -certreq -alias catwo | $KT -gencert -alias caone -sigalg MD5withRSA -rfc > catwo.cert
+
+# This certchain contains a cross-signed weak catwo.cert
+cat ee.cert catwo.cert | $KT -importcert -alias ee
+
+$JAR cvf a.jar A1.class
+$JARSIGNER -strict -keystore $KS -storepass changeit a.jar ee
+[ $? = 0 ] || exit $LINENO
+$JARSIGNER -strict -keystore $KS -storepass changeit -verify a.jar
+[ $? = 0 ] || exit $LINENO
+
 echo OK
 exit 0
--- a/test/sun/security/tools/jarsigner/ec.sh	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/ec.sh	Fri Aug 03 19:50:58 2018 +0100
@@ -53,11 +53,20 @@
 echo A > A
 $JAR cvf $JFILE A
 
-$KT -alias a -dname CN=a -keyalg ec -genkey -validity 300 || exit 11
-$KT -alias b -dname CN=b -keyalg ec -genkey -validity 300 || exit 12
+$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11
+
+$KT -alias a -dname CN=a -keyalg ec -genkey || exit 11
+$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111
+
+$KT -alias b -dname CN=b -keyalg ec -genkey || exit 12
+$KT -alias b -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias b || exit 121
+
 # Ensure that key length is sufficient for the intended hash (SHA512withECDSA)
-$KT -alias c -dname CN=c -keyalg ec -genkey -validity 300 -keysize 521 || exit 13
+$KT -alias c -dname CN=c -keyalg ec -genkey -keysize 521 || exit 13
+$KT -alias c -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias c || exit 131
+
 $KT -alias x -dname CN=x -keyalg ec -genkey -validity 300 || exit 14
+$KT -alias x -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias x || exit 141
 
 $JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 21
 $JARSIGNER -keystore $KS -storepass changeit $JFILE b -debug -strict -sigalg SHA1withECDSA || exit 22
--- a/test/sun/security/tools/jarsigner/onlymanifest.sh	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/onlymanifest.sh	Fri Aug 03 19:50:58 2018 +0100
@@ -57,12 +57,14 @@
 echo "Key: Value" > manifest
 $JAR cvfm $JFILE manifest
 
-$KT -alias a -dname CN=a -genkey -validity 300 || exit 1
-$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 2
+$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1
+$KT -alias a -dname CN=a -genkey -validity 300 || exit 2
+$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3
+$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4
 $JARSIGNER -keystore $KS -storepass changeit -verify $JFILE a -debug -strict \
-        > onlymanifest.out || exit 3
+        > onlymanifest.out || exit 5
 
-grep unsigned onlymanifest.out && exit 4
+grep unsigned onlymanifest.out && exit 6
 
 exit 0
 
--- a/test/sun/security/tools/jarsigner/warnings.sh	Wed Aug 01 03:36:32 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-#
-# Copyright (c) 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.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 8024302
-# @bug 8026037
-# @summary Clarify jar verifications
-#
-
-if [ "${TESTJAVA}" = "" ] ; then
-  JAVAC_CMD=`which javac`
-  TESTJAVA=`dirname $JAVAC_CMD`/..
-fi
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  Windows_* )
-    FS="\\"
-    ;;
-  * )
-    FS="/"
-    ;;
-esac
-
-KS=warnings.jks
-JFILE=warnings.jar
-
-KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \
-        -keystore $KS"
-JAR=$TESTJAVA${FS}bin${FS}jar
-JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit"
-
-rm $KS 2> /dev/null
-
-LANG=C
-export LANG
-
-echo 12345 > file
-
-ERR=""
-
-# Normal signer expiring on 2100-01-01
-$KT -alias s1 -dname CN=s1 -genkey -startdate 2000/01/01 -validity 36525 || ERR="$ERR keytool s1,"
-# Cert expiring soon, informational warning
-$KT -alias s2 -dname CN=s2 -genkey -validity 100 || ERR="$ERR keytool s2,"
-# Cert expired, severe warning
-$KT -alias s3 -dname CN=s3 -genkey -startdate -200d -validity 100 || ERR="$ERR keytool s3,"
-
-# noTimestamp is informatiional warning and includes a date
-$JAR cvf $JFILE file
-$JARSIGNER $JFILE s1 > output1 || ERR="$ERR jarsigner s1,"
-$JARSIGNER -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict,"
-$JARSIGNER -verify $JFILE s1 >> output1 || ERR="$ERR jarsigner s1,"
-$JARSIGNER -verify -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict,"
-
-cat output1 | grep Warning || ERR="$ERR s1 warning,"
-cat output1 | grep Error && ERR="$ERR s1 error,"
-cat output1 | grep timestamp | grep 2100-01-01 || ERR="$ERR s1 timestamp,"
-cat output1 | grep "with signer errors" && ERR="$ERR s1 err,"
-
-# hasExpiringCert is informatiional warning
-$JAR cvf $JFILE file
-$JARSIGNER $JFILE s2 > output2 || ERR="$ERR jarsigner s2,"
-$JARSIGNER -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict,"
-$JARSIGNER -verify $JFILE s2 >> output2 || ERR="$ERR jarsigner s2,"
-$JARSIGNER -verify -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict,"
-
-cat output2 | grep Warning || ERR="$ERR s2 warning,"
-cat output2 | grep Error && ERR="$ERR s2 error,"
-cat output2 | grep timestamp || ERR="$ERR s2 timestamp,"
-cat output2 | grep "will expire" || ERR="$ERR s2 expiring,"
-cat output2 | grep "with signer errors" && ERR="$ERR s2 err,"
-
-# hasExpiredCert is severe warning
-$JAR cvf $JFILE file
-$JARSIGNER $JFILE s3 > output3 || ERR="$ERR jarsigner s3,"
-$JARSIGNER -strict $JFILE s3 > output3s && ERR="$ERR jarsigner s3 strict,"
-$JARSIGNER -verify $JFILE s3 >> output3 || ERR="$ERR jarsigner s3,"
-$JARSIGNER -verify -strict $JFILE s3 >> output3s && ERR="$ERR jarsigner s3 strict,"
-
-# warning without -strict
-cat output3 | grep Warning || ERR="$ERR s3 warning,"
-cat output3 | grep Error && ERR="$ERR s3 error,"
-cat output3 | grep "with signer errors" && ERR="$ERR s3 err,"
-
-# error with -strict
-cat output3s | grep Warning || ERR="$ERR s3s warning,"
-cat output3s | grep Error || ERR="$ERR s3s error,"
-cat output3s | grep "with signer errors" || ERR="$ERR s3 err,"
-
-if [ "$ERR" = "" ]; then
-    exit 0
-else
-    echo "ERR is $ERR"
-    exit 1
-fi
-
-
--- a/test/sun/security/tools/jarsigner/warnings/Test.java	Wed Aug 01 03:36:32 2018 -0700
+++ b/test/sun/security/tools/jarsigner/warnings/Test.java	Fri Aug 03 19:50:58 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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 @@
 
     static final String CHAIN_NOT_VALIDATED_VERIFYING_WARNING
             = "This jar contains entries "
-            + "whose certificate chain is not validated.";
+            + "whose certificate chain is invalid.";
 
     static final String ALIAS_NOT_IN_STORE_VERIFYING_WARNING
             = "This jar contains signed entries "
@@ -95,7 +95,7 @@
             + "doesn't allow code signing.";
 
     static final String CHAIN_NOT_VALIDATED_SIGNING_WARNING
-            = "The signer's certificate chain is not validated.";
+            = "The signer's certificate chain is invalid.";
 
     static final String HAS_EXPIRING_CERT_SIGNING_WARNING
             = "The signer certificate will expire within six months.";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/tools/jarsigner/weaksize.sh	Fri Aug 03 19:50:58 2018 +0100
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2014, 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
+# 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
+# @bug 8044755
+# @summary Add a test for algorithm constraints check in jarsigner
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+  JAVAC_CMD=`which javac`
+  TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# The sigalg used is MD2withRSA, which is obsolete.
+
+KT="$TESTJAVA/bin/keytool ${TESTTOOLVMOPTS} -keystore ks
+    -storepass changeit -keypass changeit
+    -keyalg rsa -sigalg MD2withRSA -debug"
+JS="$TESTJAVA/bin/jarsigner ${TESTTOOLVMOPTS} -keystore ks
+    -storepass changeit -strict -debug"
+JAR="$TESTJAVA/bin/jar ${TESTTOOLVMOPTS}"
+
+rm ks 2> /dev/null
+
+$KT -genkeypair -alias ca -dname CN=CA -ext bc
+$KT -genkeypair -alias signer -dname CN=Signer
+
+$KT -certreq -alias signer | \
+        $KT -gencert -alias ca -ext ku=dS -rfc | \
+        $KT -importcert -alias signer
+
+$JAR cvf a.jar ks
+
+# We always trust a TrustedCertificateEntry
+$JS a.jar ca | grep "chain is invalid" && exit 1
+
+# An end-entity cert must follow algorithm constraints
+$JS a.jar signer | grep "chain is invalid" || exit 2
+
+exit 0