changeset 12730:0f0ef949a54a

Merge
author asaha
date Thu, 18 May 2017 14:30:18 -0700
parents ee1366b54370 90a2e2fa94e1
children 24364089455f
files .hgtags src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java src/share/classes/sun/security/util/CertConstraintParameters.java src/share/native/sun/awt/libpng/pngtest.c src/share/native/sun/awt/libpng/pngwio.c src/share/native/sun/awt/libpng/pngwrite.c src/share/native/sun/awt/libpng/pngwtran.c src/share/native/sun/awt/libpng/pngwutil.c
diffstat 66 files changed, 5571 insertions(+), 9974 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Apr 28 14:28:06 2017 -0700
+++ b/.hgtags	Thu May 18 14:30:18 2017 -0700
@@ -707,3 +707,6 @@
 e5e3c33f57367b2b23d5e05a77b41948e9d4a1b9 jdk8u141-b04
 b3e7354e6ae8567294ae664bf4a1a38a6c0bde9f jdk8u141-b05
 c49f918efc4e6e2b8a1e771dba0c8de8d636660c jdk8u141-b06
+9fd2a2019a5b7f35957c43c83eb00e1ae371a95e jdk8u141-b07
+64261149b033dd6f625ccf7b4aaf7452baec82ef jdk8u141-b08
+276269460238f84410a70ffe735db9cf78651b8f jdk8u141-b09
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu May 18 14:30:18 2017 -0700
@@ -252,13 +252,18 @@
         }
         AtomicLong ref = new AtomicLong();
         contentView.execute(viewPtr -> {
+            boolean hasOwnerPtr = false;
+
             if (owner != null) {
-                owner.execute(ownerPtr -> {
+                hasOwnerPtr = 0L != owner.executeGet(ownerPtr -> {
                     ref.set(nativeCreateNSWindow(viewPtr, ownerPtr, styleBits,
-                                                 bounds.x, bounds.y,
-                                                 bounds.width, bounds.height));
+                                                    bounds.x, bounds.y,
+                                                    bounds.width, bounds.height));
+                    return 1;
                 });
-            } else {
+            }
+
+            if (!hasOwnerPtr) {
                 ref.set(nativeCreateNSWindow(viewPtr, 0,
                                              styleBits, bounds.x, bounds.y,
                                              bounds.width, bounds.height));
--- a/src/share/classes/java/lang/reflect/WeakCache.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/java/lang/reflect/WeakCache.java	Thu May 18 14:30:18 2017 -0700
@@ -239,11 +239,11 @@
             // wrap value with CacheValue (WeakReference)
             CacheValue<V> cacheValue = new CacheValue<>(value);
 
+            // put into reverseMap
+            reverseMap.put(cacheValue, Boolean.TRUE);
+
             // try replacing us with CacheValue (this should always succeed)
-            if (valuesMap.replace(subKey, this, cacheValue)) {
-                // put also in reverseMap
-                reverseMap.put(cacheValue, Boolean.TRUE);
-            } else {
+            if (!valuesMap.replace(subKey, this, cacheValue)) {
                 throw new AssertionError("Should not reach here");
             }
 
--- a/src/share/classes/java/nio/Bits.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/java/nio/Bits.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -614,7 +614,8 @@
         String arch = AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("os.arch"));
         unaligned = arch.equals("i386") || arch.equals("x86")
-            || arch.equals("amd64") || arch.equals("x86_64");
+            || arch.equals("amd64") || arch.equals("x86_64")
+            || arch.equals("ppc64") || arch.equals("ppc64le");
         unalignedKnown = true;
         return unaligned;
     }
--- a/src/share/classes/sun/management/LazyCompositeData.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/management/LazyCompositeData.java	Thu May 18 14:30:18 2017 -0700
@@ -27,6 +27,7 @@
 
 import java.io.Serializable;
 import java.util.*;
+import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.CompositeType;
 import javax.management.openmbean.OpenType;
@@ -48,39 +49,48 @@
     private CompositeData compositeData;
 
     // Implementation of the CompositeData interface
+    @Override
     public boolean containsKey(String key) {
         return compositeData().containsKey(key);
     }
 
+    @Override
     public boolean containsValue(Object value) {
         return compositeData().containsValue(value);
     }
 
+    @Override
     public boolean equals(Object obj) {
         return compositeData().equals(obj);
     }
 
+    @Override
     public Object get(String key) {
         return compositeData().get(key);
     }
 
+    @Override
     public Object[] getAll(String[] keys) {
         return compositeData().getAll(keys);
     }
 
+    @Override
     public CompositeType getCompositeType() {
         return compositeData().getCompositeType();
     }
 
+    @Override
     public int hashCode() {
         return compositeData().hashCode();
     }
 
+    @Override
     public String toString() {
         /** FIXME: What should this be?? */
         return compositeData().toString();
     }
 
+    @Override
     public Collection<?> values() {
         return compositeData().values();
     }
@@ -126,27 +136,31 @@
         if (cd == null)
             throw new IllegalArgumentException("Null CompositeData");
 
-        return ((Boolean) cd.get(itemName)).booleanValue();
+        return ((Boolean) cd.get(itemName));
     }
 
     static long getLong(CompositeData cd, String itemName) {
         if (cd == null)
             throw new IllegalArgumentException("Null CompositeData");
 
-        return ((Long) cd.get(itemName)).longValue();
+        return ((Long) cd.get(itemName));
     }
 
     static int getInt(CompositeData cd, String itemName) {
         if (cd == null)
             throw new IllegalArgumentException("Null CompositeData");
 
-        return ((Integer) cd.get(itemName)).intValue();
+        return ((Integer) cd.get(itemName));
     }
 
     /**
      * Compares two CompositeTypes and returns true if
      * all items in type1 exist in type2 and their item types
      * are the same.
+     * @param type1 the base composite type
+     * @param type2 the checked composite type
+     * @return {@code true} if all items in type1 exist in type2 and their item
+     *         types are the same.
      */
     protected static boolean isTypeMatched(CompositeType type1, CompositeType type2) {
         if (type1 == type2) return true;
@@ -159,24 +173,9 @@
         if (!type2.keySet().containsAll(allItems))
             return false;
 
-        for (String item: allItems) {
-            OpenType<?> ot1 = type1.getType(item);
-            OpenType<?> ot2 = type2.getType(item);
-            if (ot1 instanceof CompositeType) {
-                if (! (ot2 instanceof CompositeType))
-                    return false;
-                if (!isTypeMatched((CompositeType) ot1, (CompositeType) ot2))
-                    return false;
-            } else if (ot1 instanceof TabularType) {
-                if (! (ot2 instanceof TabularType))
-                    return false;
-                if (!isTypeMatched((TabularType) ot1, (TabularType) ot2))
-                    return false;
-            } else if (!ot1.equals(ot2)) {
-                return false;
-            }
-        }
-        return true;
+        return allItems.stream().allMatch(
+            item -> isTypeMatched(type1.getType(item), type2.getType(item))
+        );
     }
 
     protected static boolean isTypeMatched(TabularType type1, TabularType type2) {
@@ -192,5 +191,41 @@
         return isTypeMatched(type1.getRowType(), type2.getRowType());
     }
 
+    protected static boolean isTypeMatched(ArrayType<?> type1, ArrayType<?> type2) {
+        if (type1 == type2) return true;
+
+        int dim1 = type1.getDimension();
+        int dim2 = type2.getDimension();
+
+        // check if the array dimensions are the same
+        if (dim1 != dim2)
+            return false;
+
+        return isTypeMatched(type1.getElementOpenType(), type2.getElementOpenType());
+    }
+
+    private static boolean isTypeMatched(OpenType<?> ot1, OpenType<?> ot2) {
+        if (ot1 instanceof CompositeType) {
+            if (! (ot2 instanceof CompositeType))
+                return false;
+            if (!isTypeMatched((CompositeType) ot1, (CompositeType) ot2))
+                return false;
+        } else if (ot1 instanceof TabularType) {
+            if (! (ot2 instanceof TabularType))
+                return false;
+            if (!isTypeMatched((TabularType) ot1, (TabularType) ot2))
+                return false;
+        } else if (ot1 instanceof ArrayType) {
+            if (! (ot2 instanceof ArrayType))
+                return false;
+            if (!isTypeMatched((ArrayType<?>) ot1, (ArrayType<?>) ot2)) {
+                return false;
+            }
+        } else if (!ot1.equals(ot2)) {
+            return false;
+        }
+        return true;
+    }
+
     private static final long serialVersionUID = -2190411934472666714L;
 }
--- a/src/share/classes/sun/security/pkcs/SignerInfo.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/pkcs/SignerInfo.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import java.security.Signature;
 import java.security.SignatureException;
 import java.security.Timestamp;
+import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertPath;
@@ -49,6 +50,7 @@
 
 import sun.misc.HexDumpEncoder;
 import sun.security.timestamp.TimestampToken;
+import sun.security.util.ConstraintsParameters;
 import sun.security.util.Debug;
 import sun.security.util.DerEncoder;
 import sun.security.util.DerInputStream;
@@ -209,7 +211,7 @@
 
     /**
      * DER encode this object onto an output stream.
-     * Implements the <code>DerEncoder</code> interface.
+     * Implements the {@code DerEncoder} interface.
      *
      * @param out
      * the output stream on which to write the DER encoding.
@@ -266,7 +268,7 @@
         if (userCert == null)
             return null;
 
-        ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
+        ArrayList<X509Certificate> certList = new ArrayList<>();
         certList.add(userCert);
 
         X509Certificate[] pkcsCerts = block.getCertificates();
@@ -321,6 +323,14 @@
                 data = content.getContentBytes();
             }
 
+            Timestamp timestamp = null;
+            try {
+                timestamp = getTimestamp();
+            } catch (Exception ignore) {
+            }
+
+            ConstraintsParameters cparams =
+                    new ConstraintsParameters(timestamp);
             String digestAlgname = getDigestAlgorithmId().getName();
 
             byte[] dataSigned;
@@ -347,11 +357,11 @@
                 if (messageDigest == null) // fail if there is no message digest
                     return null;
 
-                // check that algorithm is not restricted
-                if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
-                        digestAlgname, null)) {
-                    throw new SignatureException("Digest check failed. " +
-                            "Disabled algorithm used: " + digestAlgname);
+                // check that digest algorithm is not restricted
+                try {
+                    JAR_DISABLED_CHECK.permits(digestAlgname, cparams);
+                } catch (CertPathValidatorException e) {
+                    throw new SignatureException(e.getMessage(), e);
                 }
 
                 MessageDigest md = MessageDigest.getInstance(digestAlgname);
@@ -385,17 +395,18 @@
             String algname = AlgorithmId.makeSigAlg(
                     digestAlgname, encryptionAlgname);
 
-            // check that algorithm is not restricted
-            if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
-                throw new SignatureException("Signature check failed. " +
-                        "Disabled algorithm used: " + algname);
+            // check that jar signature algorithm is not restricted
+            try {
+                JAR_DISABLED_CHECK.permits(algname, cparams);
+            } catch (CertPathValidatorException e) {
+                throw new SignatureException(e.getMessage(), e);
             }
 
             X509Certificate cert = getCertificate(block);
-            PublicKey key = cert.getPublicKey();
             if (cert == null) {
                 return null;
             }
+            PublicKey key = cert.getPublicKey();
 
             // check if the public key is restricted
             if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
@@ -519,7 +530,7 @@
      * Extracts a timestamp from a PKCS7 SignerInfo.
      *
      * Examines the signer's unsigned attributes for a
-     * <tt>signatureTimestampToken</tt> attribute. If present,
+     * {@code signatureTimestampToken} attribute. If present,
      * then it is parsed to extract the date and time at which the
      * timestamp was generated.
      *
--- a/src/share/classes/sun/security/provider/ByteArrayAccess.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/ByteArrayAccess.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,7 +94,7 @@
         String arch = java.security.AccessController.doPrivileged
             (new sun.security.action.GetPropertyAction("os.arch", ""));
         return arch.equals("i386") || arch.equals("x86") || arch.equals("amd64")
-            || arch.equals("x86_64");
+            || arch.equals("x86_64") || arch.equals("ppc64") || arch.equals("ppc64le");
     }
 
     /**
--- a/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,11 @@
 
 import java.security.AlgorithmConstraints;
 import java.security.CryptoPrimitive;
+import java.security.Timestamp;
+import java.security.cert.CertPathValidator;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Date;
 import java.util.Set;
 import java.util.EnumSet;
 import java.math.BigInteger;
@@ -51,15 +54,16 @@
 import java.security.spec.DSAPublicKeySpec;
 
 import sun.security.util.AnchorCertificates;
-import sun.security.util.CertConstraintParameters;
+import sun.security.util.ConstraintsParameters;
 import sun.security.util.Debug;
 import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.validator.Validator;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
 import sun.security.x509.AlgorithmId;
 
 /**
- * A <code>PKIXCertPathChecker</code> implementation to check whether a
+ * A {@code PKIXCertPathChecker} implementation to check whether a
  * specified certificate contains the required algorithm constraints.
  * <p>
  * Certificate fields such as the subject public key, the signature
@@ -69,24 +73,27 @@
  * @see PKIXCertPathChecker
  * @see PKIXParameters
  */
-final public class AlgorithmChecker extends PKIXCertPathChecker {
+public final class AlgorithmChecker extends PKIXCertPathChecker {
     private static final Debug debug = Debug.getInstance("certpath");
 
     private final AlgorithmConstraints constraints;
     private final PublicKey trustedPubKey;
+    private final Date pkixdate;
     private PublicKey prevPubKey;
+    private final Timestamp jarTimestamp;
+    private final String variant;
 
-    private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
+    private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
 
-    private final static Set<CryptoPrimitive> KU_PRIMITIVE_SET =
+    private static final Set<CryptoPrimitive> KU_PRIMITIVE_SET =
         Collections.unmodifiableSet(EnumSet.of(
             CryptoPrimitive.SIGNATURE,
             CryptoPrimitive.KEY_ENCAPSULATION,
             CryptoPrimitive.PUBLIC_KEY_ENCRYPTION,
             CryptoPrimitive.KEY_AGREEMENT));
 
-    private final static DisabledAlgorithmConstraints
+    private static final DisabledAlgorithmConstraints
         certPathDefaultConstraints = new DisabledAlgorithmConstraints(
             DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
 
@@ -99,64 +106,99 @@
     private boolean trustedMatch = false;
 
     /**
-     * Create a new <code>AlgorithmChecker</code> with the algorithm
-     * constraints specified in security property
-     * "jdk.certpath.disabledAlgorithms".
+     * Create a new {@code AlgorithmChecker} with the given algorithm
+     * given {@code TrustAnchor} and {@code String} variant.
      *
      * @param anchor the trust anchor selected to validate the target
      *     certificate
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    public AlgorithmChecker(TrustAnchor anchor) {
-        this(anchor, certPathDefaultConstraints);
+    public AlgorithmChecker(TrustAnchor anchor, String variant) {
+        this(anchor, certPathDefaultConstraints, null, null, variant);
     }
 
     /**
-     * Create a new <code>AlgorithmChecker</code> with the
-     * given {@code AlgorithmConstraints}.
-     * <p>
-     * Note that this constructor will be used to check a certification
-     * path where the trust anchor is unknown, or a certificate list which may
-     * contain the trust anchor. This constructor is used by SunJSSE.
+     * Create a new {@code AlgorithmChecker} with the given
+     * {@code AlgorithmConstraints}, {@code Timestamp}, and {@code String}
+     * variant.
+     *
+     * Note that this constructor can initialize a variation of situations where
+     * the AlgorithmConstraints, Timestamp, or Variant maybe known.
      *
      * @param constraints the algorithm constraints (or null)
+     * @param jarTimestamp Timestamp passed for JAR timestamp constraint
+     *                     checking. Set to null if not applicable.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    public AlgorithmChecker(AlgorithmConstraints constraints) {
-        this.prevPubKey = null;
-        this.trustedPubKey = null;
-        this.constraints = constraints;
+    public AlgorithmChecker(AlgorithmConstraints constraints,
+            Timestamp jarTimestamp, String variant) {
+        this(null, constraints, null, jarTimestamp, variant);
     }
 
     /**
-     * Create a new <code>AlgorithmChecker</code> with the
-     * given <code>TrustAnchor</code> and <code>AlgorithmConstraints</code>.
+     * Create a new {@code AlgorithmChecker} with the
+     * given {@code TrustAnchor}, {@code AlgorithmConstraints},
+     * {@code Timestamp}, and {@code String} variant.
      *
      * @param anchor the trust anchor selected to validate the target
      *     certificate
      * @param constraints the algorithm constraints (or null)
-     *
-     * @throws IllegalArgumentException if the <code>anchor</code> is null
+     * @param pkixdate The date specified by the PKIXParameters date.  If the
+     *                 PKIXParameters is null, the current date is used.  This
+     *                 should be null when jar files are being checked.
+     * @param jarTimestamp Timestamp passed for JAR timestamp constraint
+     *                     checking. Set to null if not applicable.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
     public AlgorithmChecker(TrustAnchor anchor,
-            AlgorithmConstraints constraints) {
+            AlgorithmConstraints constraints, Date pkixdate,
+            Timestamp jarTimestamp, String variant) {
 
-        if (anchor == null) {
-            throw new IllegalArgumentException(
-                        "The trust anchor cannot be null");
+        if (anchor != null) {
+            if (anchor.getTrustedCert() != null) {
+                this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+                // Check for anchor certificate restrictions
+                trustedMatch = checkFingerprint(anchor.getTrustedCert());
+                if (trustedMatch && debug != null) {
+                    debug.println("trustedMatch = true");
+                }
+            } else {
+                this.trustedPubKey = anchor.getCAPublicKey();
+            }
+        } else {
+            this.trustedPubKey = null;
+            if (debug != null) {
+                debug.println("TrustAnchor is null, trustedMatch is false.");
+            }
         }
 
-        if (anchor.getTrustedCert() != null) {
-            this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
-            // Check for anchor certificate restrictions
-            trustedMatch = checkFingerprint(anchor.getTrustedCert());
-            if (trustedMatch && debug != null) {
-                debug.println("trustedMatch = true");
-            }
-        } else {
-            this.trustedPubKey = anchor.getCAPublicKey();
-        }
+        this.prevPubKey = this.trustedPubKey;
+        this.constraints = (constraints == null ? certPathDefaultConstraints :
+                constraints);
+        // If we are checking jar files, set pkixdate the same as the timestamp
+        // for certificate checking
+        this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
+                pkixdate);
+        this.jarTimestamp = jarTimestamp;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+    }
 
-        this.prevPubKey = trustedPubKey;
-        this.constraints = constraints;
+    /**
+     * Create a new {@code AlgorithmChecker} with the given {@code TrustAnchor},
+     * {@code PKIXParameter} date, and {@code varient}
+     *
+     * @param anchor the trust anchor selected to validate the target
+     *     certificate
+     * @param pkixdate Date the constraints are checked against. The value is
+     *             either the PKIXParameters date or null for the current date.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
+     */
+    public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) {
+        this(anchor, certPathDefaultConstraints, pkixdate, null, variant);
     }
 
     // Check this 'cert' for restrictions in the AnchorCertificates
@@ -217,6 +259,28 @@
                 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
         }
 
+        X509CertImpl x509Cert;
+        AlgorithmId algorithmId;
+        try {
+            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException(ce);
+        }
+
+        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+        PublicKey currPubKey = cert.getPublicKey();
+        String currSigAlg = ((X509Certificate)cert).getSigAlgName();
+
+        // Check the signature algorithm and parameters against constraints.
+        if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
+                currSigAlgParams)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on signature " +
+                            "algorithm: " + currSigAlg, null, null, -1,
+                    BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
         // Assume all key usage bits are set if key usage is not present
         Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
 
@@ -253,101 +317,74 @@
             }
         }
 
-        PublicKey currPubKey = cert.getPublicKey();
+        ConstraintsParameters cp =
+                new ConstraintsParameters((X509Certificate)cert,
+                        trustedMatch, pkixdate, jarTimestamp, variant);
 
+        // Check against local constraints if it is DisabledAlgorithmConstraints
         if (constraints instanceof DisabledAlgorithmConstraints) {
-            // Check against DisabledAlgorithmConstraints certpath constraints.
-            // permits() will throw exception on failure.
-            ((DisabledAlgorithmConstraints)constraints).permits(primitives,
-                new CertConstraintParameters((X509Certificate)cert,
-                        trustedMatch));
-            // If there is no previous key, set one and exit
-            if (prevPubKey == null) {
-                prevPubKey = currPubKey;
-                return;
+            ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp);
+            // DisabledAlgorithmsConstraints does not check primitives, so key
+            // additional key check.
+
+        } else {
+            // Perform the default constraints checking anyway.
+            certPathDefaultConstraints.permits(currSigAlg, cp);
+            // Call locally set constraints to check key with primitives.
+            if (!constraints.permits(primitives, currPubKey)) {
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on key " +
+                                currPubKey.getAlgorithm() + " with size of " +
+                                sun.security.util.KeyUtil.getKeySize(currPubKey) +
+                                "bits",
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
 
-        X509CertImpl x509Cert;
-        AlgorithmId algorithmId;
-        try {
-            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
-            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
-        String currSigAlg = x509Cert.getSigAlgName();
-
-        // If 'constraints' is not of DisabledAlgorithmConstraints, check all
-        // everything individually
-        if (!(constraints instanceof DisabledAlgorithmConstraints)) {
-            // Check the current signature algorithm
-            if (!constraints.permits(
-                    SIGNATURE_PRIMITIVE_SET,
-                    currSigAlg, currSigAlgParams)) {
-                throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on signature " +
-                                "algorithm: " + currSigAlg, null, null, -1,
-                        BasicReason.ALGORITHM_CONSTRAINED);
-            }
-
-        if (!constraints.permits(primitives, currPubKey)) {
-            throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on keysize: " +
-                                sun.security.util.KeyUtil.getKeySize(currPubKey),
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
+        // If there is no previous key, set one and exit
+        if (prevPubKey == null) {
+            prevPubKey = currPubKey;
+            return;
         }
 
         // Check with previous cert for signature algorithm and public key
-        if (prevPubKey != null) {
-                if (!constraints.permits(
-                        SIGNATURE_PRIMITIVE_SET,
-                        currSigAlg, prevPubKey, currSigAlgParams)) {
-                    throw new CertPathValidatorException(
+        if (!constraints.permits(
+                SIGNATURE_PRIMITIVE_SET,
+                currSigAlg, prevPubKey, currSigAlgParams)) {
+            throw new CertPathValidatorException(
                     "Algorithm constraints check failed on " +
                             "signature algorithm: " + currSigAlg,
-                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-                }
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
 
-            // Inherit key parameters from previous key
-            if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
-                // Inherit DSA parameters from previous key
-                if (!(prevPubKey instanceof DSAPublicKey)) {
-                    throw new CertPathValidatorException("Input key is not " +
+        // Inherit key parameters from previous key
+        if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
+            // Inherit DSA parameters from previous key
+            if (!(prevPubKey instanceof DSAPublicKey)) {
+                throw new CertPathValidatorException("Input key is not " +
                         "of a appropriate type for inheriting parameters");
-                }
+            }
 
-                DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
-                if (params == null) {
-                    throw new CertPathValidatorException(
+            DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
+            if (params == null) {
+                throw new CertPathValidatorException(
                         "Key parameters missing from public key.");
-                }
+            }
 
-                try {
-                    BigInteger y = ((DSAPublicKey)currPubKey).getY();
-                    KeyFactory kf = KeyFactory.getInstance("DSA");
-                    DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
-                                                       params.getP(),
-                                                       params.getQ(),
-                                                       params.getG());
-                    currPubKey = kf.generatePublic(ks);
-                } catch (GeneralSecurityException e) {
-                    throw new CertPathValidatorException("Unable to generate " +
+            try {
+                BigInteger y = ((DSAPublicKey)currPubKey).getY();
+                KeyFactory kf = KeyFactory.getInstance("DSA");
+                DSAPublicKeySpec ks = new DSAPublicKeySpec(y, params.getP(),
+                        params.getQ(), params.getG());
+                currPubKey = kf.generatePublic(ks);
+            } catch (GeneralSecurityException e) {
+                throw new CertPathValidatorException("Unable to generate " +
                         "key with inherited parameters: " + e.getMessage(), e);
-                }
             }
         }
 
         // reset the previous public key
         prevPubKey = currPubKey;
-
-        // check the extended key usage, ignore the check now
-        // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
-
-        // DO NOT remove any unresolved critical extensions
     }
 
     /**
@@ -387,8 +424,10 @@
      *
      * @param key the public key to verify the CRL signature
      * @param crl the target CRL
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    static void check(PublicKey key, X509CRL crl)
+    static void check(PublicKey key, X509CRL crl, String variant)
                         throws CertPathValidatorException {
 
         X509CRLImpl x509CRLImpl = null;
@@ -399,28 +438,24 @@
         }
 
         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
-        check(key, algorithmId);
+        check(key, algorithmId, variant);
     }
 
     /**
      * Check the signature algorithm with the specified public key.
      *
      * @param key the public key to verify the CRL signature
-     * @param crl the target CRL
+     * @param algorithmId signature algorithm Algorithm ID
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    static void check(PublicKey key, AlgorithmId algorithmId)
+    static void check(PublicKey key, AlgorithmId algorithmId, String variant)
                         throws CertPathValidatorException {
         String sigAlgName = algorithmId.getName();
         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 
-        if (!certPathDefaultConstraints.permits(
-                SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
-            throw new CertPathValidatorException(
-                "Algorithm constraints check failed on signature algorithm: " +
-                sigAlgName + " is disabled",
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
+        certPathDefaultConstraints.permits(new ConstraintsParameters(
+                sigAlgName, sigAlgParams, key, variant));
     }
-
 }
 
--- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 import java.util.*;
 
 import sun.security.util.Debug;
+import sun.security.validator.Validator;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.*;
 
@@ -66,6 +67,20 @@
      * an X509CRLSelector with certificateChecking set.
      */
     public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
+            boolean signFlag, PublicKey prevKey, String provider,
+            List<CertStore> certStores, boolean[] reasonsMask,
+            Set<TrustAnchor> trustAnchors, Date validity, String variant)
+            throws CertStoreException
+    {
+        return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
+                reasonsMask, trustAnchors, validity, variant);
+    }
+    /**
+     * Return the X509CRLs matching this selector. The selector must be
+     * an X509CRLSelector with certificateChecking set.
+     */
+    // Called by com.sun.deploy.security.RevocationChecker
+    public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
                                               boolean signFlag,
                                               PublicKey prevKey,
                                               String provider,
@@ -76,7 +91,7 @@
         throws CertStoreException
     {
         return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
-                       reasonsMask, trustAnchors, validity);
+                reasonsMask, trustAnchors, validity, Validator.VAR_GENERIC);
     }
 
     /**
@@ -91,7 +106,8 @@
                                               List<CertStore> certStores,
                                               boolean[] reasonsMask,
                                               Set<TrustAnchor> trustAnchors,
-                                              Date validity)
+                                              Date validity,
+                                              String variant)
         throws CertStoreException
     {
         X509Certificate cert = selector.getCertificateChecking();
@@ -120,7 +136,7 @@
                 DistributionPoint point = t.next();
                 Collection<X509CRL> crls = getCRLs(selector, certImpl,
                     point, reasonsMask, signFlag, prevKey, prevCert, provider,
-                    certStores, trustAnchors, validity);
+                    certStores, trustAnchors, validity, variant);
                 results.addAll(crls);
             }
             if (debug != null) {
@@ -145,7 +161,7 @@
         X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
         boolean signFlag, PublicKey prevKey, X509Certificate prevCert,
         String provider, List<CertStore> certStores,
-        Set<TrustAnchor> trustAnchors, Date validity)
+        Set<TrustAnchor> trustAnchors, Date validity, String variant)
             throws CertStoreException {
 
         // check for full name
@@ -208,7 +224,7 @@
                 selector.setIssuerNames(null);
                 if (selector.match(crl) && verifyCRL(certImpl, point, crl,
                         reasonsMask, signFlag, prevKey, prevCert, provider,
-                        trustAnchors, certStores, validity)) {
+                        trustAnchors, certStores, validity, variant)) {
                     crls.add(crl);
                 }
             } catch (IOException | CRLException e) {
@@ -317,7 +333,7 @@
         X509CRL crl, boolean[] reasonsMask, boolean signFlag,
         PublicKey prevKey, X509Certificate prevCert, String provider,
         Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
-        Date validity) throws CRLException, IOException {
+        Date validity, String variant) throws CRLException, IOException {
 
         if (debug != null) {
             debug.println("DistributionPointFetcher.verifyCRL: " +
@@ -443,7 +459,7 @@
                         }
                         if (indirectCRL) {
                             if (pointCrlIssuers.size() != 1) {
-                                // RFC 3280: there must be only 1 CRL issuer
+                                // RFC 5280: there must be only 1 CRL issuer
                                 // name when relativeName is present
                                 if (debug != null) {
                                     debug.println("must only be one CRL " +
@@ -664,7 +680,7 @@
 
         // check the crl signature algorithm
         try {
-            AlgorithmChecker.check(prevKey, crl);
+            AlgorithmChecker.check(prevKey, crl, variant);
         } catch (CertPathValidatorException cpve) {
             if (debug != null) {
                 debug.println("CRL signature algorithm check failed: " + cpve);
--- a/src/share/classes/sun/security/provider/certpath/OCSP.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/OCSP.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 import java.security.cert.CertPathValidatorException.BasicReason;
 import java.security.cert.CRLReason;
 import java.security.cert.Extension;
+import java.security.cert.TrustAnchor;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Collections;
@@ -42,14 +43,14 @@
 import java.util.List;
 import java.util.Map;
 
-import static sun.security.provider.certpath.OCSPResponse.*;
 import sun.security.action.GetIntegerAction;
 import sun.security.util.Debug;
-import sun.security.util.ObjectIdentifier;
+import sun.security.validator.Validator;
 import sun.security.x509.AccessDescription;
 import sun.security.x509.AuthorityInfoAccessExtension;
 import sun.security.x509.GeneralName;
 import sun.security.x509.GeneralNameInterface;
+import sun.security.x509.PKIXExtensions;
 import sun.security.x509.URIName;
 import sun.security.x509.X509CertImpl;
 
@@ -65,9 +66,6 @@
  */
 public final class OCSP {
 
-    static final ObjectIdentifier NONCE_EXTENSION_OID =
-        ObjectIdentifier.newInternal(new int[]{ 1, 3, 6, 1, 5, 5, 7, 48, 1, 2});
-
     private static final Debug debug = Debug.getInstance("certpath");
 
     private static final int DEFAULT_CONNECT_TIMEOUT = 15000;
@@ -97,42 +95,6 @@
 
     private OCSP() {}
 
-    /**
-     * Obtains the revocation status of a certificate using OCSP using the most
-     * common defaults. The OCSP responder URI is retrieved from the
-     * certificate's AIA extension. The OCSP responder certificate is assumed
-     * to be the issuer's certificate (or issued by the issuer CA).
-     *
-     * @param cert the certificate to be checked
-     * @param issuerCert the issuer certificate
-     * @return the RevocationStatus
-     * @throws IOException if there is an exception connecting to or
-     *    communicating with the OCSP responder
-     * @throws CertPathValidatorException if an exception occurs while
-     *    encoding the OCSP Request or validating the OCSP Response
-     */
-    public static RevocationStatus check(X509Certificate cert,
-                                         X509Certificate issuerCert)
-        throws IOException, CertPathValidatorException {
-        CertId certId = null;
-        URI responderURI = null;
-        try {
-            X509CertImpl certImpl = X509CertImpl.toImpl(cert);
-            responderURI = getResponderURI(certImpl);
-            if (responderURI == null) {
-                throw new CertPathValidatorException
-                    ("No OCSP Responder URI in certificate");
-            }
-            certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
-        } catch (CertificateException | IOException e) {
-            throw new CertPathValidatorException
-                ("Exception while encoding OCSPRequest", e);
-        }
-        OCSPResponse ocspResponse = check(Collections.singletonList(certId),
-            responderURI, issuerCert, null, null,
-            Collections.<Extension>emptyList());
-        return (RevocationStatus)ocspResponse.getSingleResponse(certId);
-    }
 
     /**
      * Obtains the revocation status of a certificate using OCSP.
@@ -149,6 +111,8 @@
      * @throws CertPathValidatorException if an exception occurs while
      *    encoding the OCSP Request or validating the OCSP Response
      */
+
+    // Called by com.sun.deploy.security.TrustDecider
     public static RevocationStatus check(X509Certificate cert,
                                          X509Certificate issuerCert,
                                          URI responderURI,
@@ -157,18 +121,27 @@
         throws IOException, CertPathValidatorException
     {
         return check(cert, issuerCert, responderURI, responderCert, date,
-                     Collections.<Extension>emptyList());
+                     Collections.<Extension>emptyList(), Validator.VAR_GENERIC);
     }
 
-    // Called by com.sun.deploy.security.TrustDecider
+
     public static RevocationStatus check(X509Certificate cert,
-                                         X509Certificate issuerCert,
-                                         URI responderURI,
-                                         X509Certificate responderCert,
-                                         Date date, List<Extension> extensions)
+            X509Certificate issuerCert, URI responderURI,
+            X509Certificate responderCert, Date date, List<Extension> extensions,
+            String variant)
         throws IOException, CertPathValidatorException
     {
-        CertId certId = null;
+        return check(cert, responderURI, null, issuerCert, responderCert, date,
+                extensions, variant);
+    }
+
+    public static RevocationStatus check(X509Certificate cert,
+            URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
+            X509Certificate responderCert, Date date,
+            List<Extension> extensions, String variant)
+            throws IOException, CertPathValidatorException
+    {
+        CertId certId;
         try {
             X509CertImpl certImpl = X509CertImpl.toImpl(cert);
             certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
@@ -177,19 +150,23 @@
                 ("Exception while encoding OCSPRequest", e);
         }
         OCSPResponse ocspResponse = check(Collections.singletonList(certId),
-            responderURI, issuerCert, responderCert, date, extensions);
+                responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
+                responderCert, date, extensions, variant);
         return (RevocationStatus) ocspResponse.getSingleResponse(certId);
     }
 
     /**
      * Checks the revocation status of a list of certificates using OCSP.
      *
-     * @param certs the CertIds to be checked
+     * @param certIds the CertIds to be checked
      * @param responderURI the URI of the OCSP responder
-     * @param issuerCert the issuer's certificate
+     * @param issuerInfo the issuer's certificate and/or subject and public key
      * @param responderCert the OCSP responder's certificate
      * @param date the time the validity of the OCSP responder's certificate
      *    should be checked against. If null, the current time is used.
+     * @param extensions zero or more OCSP extensions to be included in the
+     *    request.  If no extensions are requested, an empty {@code List} must
+     *    be used.  A {@code null} value is not allowed.
      * @return the OCSPResponse
      * @throws IOException if there is an exception connecting to or
      *    communicating with the OCSP responder
@@ -197,24 +174,59 @@
      *    encoding the OCSP Request or validating the OCSP Response
      */
     static OCSPResponse check(List<CertId> certIds, URI responderURI,
-                              X509Certificate issuerCert,
+                              OCSPResponse.IssuerInfo issuerInfo,
                               X509Certificate responderCert, Date date,
-                              List<Extension> extensions)
+                              List<Extension> extensions, String variant)
         throws IOException, CertPathValidatorException
     {
-        byte[] bytes = null;
-        OCSPRequest request = null;
+        byte[] nonce = null;
+        for (Extension ext : extensions) {
+            if (ext.getId().equals(PKIXExtensions.OCSPNonce_Id.toString())) {
+                nonce = ext.getValue();
+            }
+        }
+
+        OCSPResponse ocspResponse = null;
         try {
-            request = new OCSPRequest(certIds, extensions);
-            bytes = request.encodeBytes();
+            byte[] response = getOCSPBytes(certIds, responderURI, extensions);
+            ocspResponse = new OCSPResponse(response);
+
+            // verify the response
+            ocspResponse.verify(certIds, issuerInfo, responderCert, date,
+                    nonce, variant);
         } catch (IOException ioe) {
-            throw new CertPathValidatorException
-                ("Exception while encoding OCSPRequest", ioe);
+            throw new CertPathValidatorException(
+                "Unable to determine revocation status due to network error",
+                ioe, null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
         }
 
+        return ocspResponse;
+    }
+
+
+    /**
+     * Send an OCSP request, then read and return the OCSP response bytes.
+     *
+     * @param certIds the CertIds to be checked
+     * @param responderURI the URI of the OCSP responder
+     * @param extensions zero or more OCSP extensions to be included in the
+     *    request.  If no extensions are requested, an empty {@code List} must
+     *    be used.  A {@code null} value is not allowed.
+     *
+     * @return the OCSP response bytes
+     *
+     * @throws IOException if there is an exception connecting to or
+     *    communicating with the OCSP responder
+     */
+    public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
+            List<Extension> extensions) throws IOException {
+        OCSPRequest request = new OCSPRequest(certIds, extensions);
+        byte[] bytes = request.encodeBytes();
+
         InputStream in = null;
         OutputStream out = null;
         byte[] response = null;
+
         try {
             URL url = responderURI.toURL();
             if (debug != null) {
@@ -257,10 +269,6 @@
                 }
             }
             response = Arrays.copyOf(response, total);
-        } catch (IOException ioe) {
-            throw new CertPathValidatorException(
-                "Unable to determine revocation status due to network error",
-                ioe, null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
         } finally {
             if (in != null) {
                 try {
@@ -277,20 +285,7 @@
                 }
             }
         }
-
-        OCSPResponse ocspResponse = null;
-        try {
-            ocspResponse = new OCSPResponse(response);
-        } catch (IOException ioe) {
-            // response decoding exception
-            throw new CertPathValidatorException(ioe);
-        }
-
-        // verify the response
-        ocspResponse.verify(certIds, issuerCert, responderCert, date,
-            request.getNonce());
-
-        return ocspResponse;
+        return response;
     }
 
     /**
@@ -322,7 +317,7 @@
 
         List<AccessDescription> descriptions = aia.getAccessDescriptions();
         for (AccessDescription description : descriptions) {
-            if (description.getAccessMethod().equals((Object)
+            if (description.getAccessMethod().equals(
                 AccessDescription.Ad_OCSP_Id)) {
 
                 GeneralName generalName = description.getAccessLocation();
--- a/src/share/classes/sun/security/provider/certpath/OCSPRequest.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/OCSPRequest.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,11 @@
 
 import sun.misc.HexDumpEncoder;
 import sun.security.util.*;
+import sun.security.x509.PKIXExtensions;
 
 /**
  * This class can be used to generate an OCSP request and send it over
- * an outputstream. Currently we do not support signing requests
+ * an output stream. Currently we do not support signing requests.
  * The OCSP Request is specified in RFC 2560 and
  * the ASN.1 definition is as follows:
  * <pre>
@@ -118,7 +119,8 @@
             DerOutputStream extOut = new DerOutputStream();
             for (Extension ext : extensions) {
                 ext.encode(extOut);
-                if (ext.getId().equals(OCSP.NONCE_EXTENSION_OID.toString())) {
+                if (ext.getId().equals(
+                        PKIXExtensions.OCSPNonce_Id.toString())) {
                     nonce = ext.getValue();
                 }
             }
--- a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, 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
@@ -41,6 +41,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import javax.security.auth.x500.X500Principal;
 
 import sun.misc.HexDumpEncoder;
@@ -129,7 +130,7 @@
         SIG_REQUIRED,          // Must sign the request
         UNAUTHORIZED           // Request unauthorized
     };
-    private static ResponseStatus[] rsvalues = ResponseStatus.values();
+    private static final ResponseStatus[] rsvalues = ResponseStatus.values();
 
     private static final Debug debug = Debug.getInstance("certpath");
     private static final boolean dump = debug != null && Debug.isOn("ocsp");
@@ -173,7 +174,7 @@
     }
 
     // an array of all of the CRLReasons (used in SingleResponse)
-    private static CRLReason[] values = CRLReason.values();
+    private static final CRLReason[] values = CRLReason.values();
 
     private final ResponseStatus responseStatus;
     private final Map<CertId, SingleResponse> singleResponseMap;
@@ -183,13 +184,16 @@
     private final byte[] responseNonce;
     private List<X509CertImpl> certs;
     private X509CertImpl signerCert = null;
-    private X500Principal responderName = null;
-    private KeyIdentifier responderKeyId = null;
+    private final ResponderId respId;
+    private Date producedAtDate = null;
+    private final Map<String, java.security.cert.Extension> responseExtensions;
 
     /*
      * Create an OCSP response from its ASN.1 DER encoding.
+     *
+     * @param bytes The DER-encoded bytes for an OCSP response
      */
-    OCSPResponse(byte[] bytes) throws IOException {
+    public OCSPResponse(byte[] bytes) throws IOException {
         if (dump) {
             HexDumpEncoder hexEnc = new HexDumpEncoder();
             debug.println("OCSPResponse bytes...\n\n" +
@@ -221,6 +225,8 @@
             signature = null;
             tbsResponseData = null;
             responseNonce = null;
+            responseExtensions = Collections.emptyMap();
+            respId = null;
             return;
         }
 
@@ -289,27 +295,15 @@
         }
 
         // responderID
-        short tag = (byte)(seq.tag & 0x1f);
-        if (tag == NAME_TAG) {
-            responderName = new X500Principal(seq.getData().toByteArray());
-            if (debug != null) {
-                debug.println("Responder's name: " + responderName);
-            }
-        } else if (tag == KEY_TAG) {
-            responderKeyId = new KeyIdentifier(seq.getData().getOctetString());
-            if (debug != null) {
-                debug.println("Responder's key ID: " +
-                    Debug.toString(responderKeyId.getIdentifier()));
-            }
-        } else {
-            throw new IOException("Bad encoding in responderID element of " +
-                "OCSP response: expected ASN.1 context specific tag 0 or 1");
+        respId = new ResponderId(seq.toByteArray());
+        if (debug != null) {
+            debug.println("Responder ID: " + respId);
         }
 
         // producedAt
         seq = seqDerIn.getDerValue();
+        producedAtDate = seq.getGeneralizedTime();
         if (debug != null) {
-            Date producedAtDate = seq.getGeneralizedTime();
             debug.println("OCSP response produced at: " + producedAtDate);
         }
 
@@ -320,37 +314,29 @@
             debug.println("OCSP number of SingleResponses: "
                           + singleResponseDer.length);
         }
-        for (int i = 0; i < singleResponseDer.length; i++) {
-            SingleResponse singleResponse =
-                new SingleResponse(singleResponseDer[i]);
+        for (DerValue srDer : singleResponseDer) {
+            SingleResponse singleResponse = new SingleResponse(srDer);
             singleResponseMap.put(singleResponse.getCertId(), singleResponse);
         }
 
         // responseExtensions
-        byte[] nonce = null;
+        Map<String, java.security.cert.Extension> tmpExtMap = new HashMap<>();
         if (seqDerIn.available() > 0) {
             seq = seqDerIn.getDerValue();
             if (seq.isContextSpecific((byte)1)) {
-                DerValue[] responseExtDer = seq.data.getSequence(3);
-                for (int i = 0; i < responseExtDer.length; i++) {
-                    Extension ext = new Extension(responseExtDer[i]);
-                    if (debug != null) {
-                        debug.println("OCSP extension: " + ext);
-                    }
-                    // Only the NONCE extension is recognized
-                    if (ext.getExtensionId().equals((Object)
-                        OCSP.NONCE_EXTENSION_OID))
-                    {
-                        nonce = ext.getExtensionValue();
-                    } else if (ext.isCritical())  {
-                        throw new IOException(
-                            "Unsupported OCSP critical extension: " +
-                            ext.getExtensionId());
-                    }
-                }
+                tmpExtMap = parseExtensions(seq);
             }
         }
-        responseNonce = nonce;
+        responseExtensions = tmpExtMap;
+
+        // Attach the nonce value if found in the extension map
+        Extension nonceExt = (Extension)tmpExtMap.get(
+                PKIXExtensions.OCSPNonce_Id.toString());
+        responseNonce = (nonceExt != null) ?
+                nonceExt.getExtensionValue() : null;
+        if (debug != null && responseNonce != null) {
+            debug.println("Response nonce: " + Arrays.toString(responseNonce));
+        }
 
         // signatureAlgorithmId
         sigAlgId = AlgorithmId.parse(seqTmp[1]);
@@ -387,8 +373,9 @@
         }
     }
 
-    void verify(List<CertId> certIds, X509Certificate issuerCert,
-                X509Certificate responderCert, Date date, byte[] nonce)
+    void verify(List<CertId> certIds, IssuerInfo issuerInfo,
+            X509Certificate responderCert, Date date, byte[] nonce,
+            String variant)
         throws CertPathValidatorException
     {
         switch (responseStatus) {
@@ -428,7 +415,9 @@
             // Add the Issuing CA cert and/or Trusted Responder cert to the list
             // of certs from the OCSP response
             try {
-                certs.add(X509CertImpl.toImpl(issuerCert));
+                if (issuerInfo.getCertificate() != null) {
+                    certs.add(X509CertImpl.toImpl(issuerInfo.getCertificate()));
+                }
                 if (responderCert != null) {
                     certs.add(X509CertImpl.toImpl(responderCert));
                 }
@@ -437,20 +426,22 @@
                     "Invalid issuer or trusted responder certificate", ce);
             }
 
-            if (responderName != null) {
+            if (respId.getType() == ResponderId.Type.BY_NAME) {
+                X500Principal rName = respId.getResponderName();
                 for (X509CertImpl cert : certs) {
-                    if (cert.getSubjectX500Principal().equals(responderName)) {
+                    if (cert.getSubjectX500Principal().equals(rName)) {
                         signerCert = cert;
                         break;
                     }
                 }
-            } else if (responderKeyId != null) {
+            } else if (respId.getType() == ResponderId.Type.BY_KEY) {
+                KeyIdentifier ridKeyId = respId.getKeyIdentifier();
                 for (X509CertImpl cert : certs) {
                     // Match responder's key identifier against the cert's SKID
                     // This will match if the SKID is encoded using the 160-bit
                     // SHA-1 hash method as defined in RFC 5280.
                     KeyIdentifier certKeyId = cert.getSubjectKeyId();
-                    if (certKeyId != null && responderKeyId.equals(certKeyId)) {
+                    if (certKeyId != null && ridKeyId.equals(certKeyId)) {
                         signerCert = cert;
                         break;
                     } else {
@@ -464,7 +455,7 @@
                         } catch (IOException e) {
                             // ignore
                         }
-                        if (responderKeyId.equals(certKeyId)) {
+                        if (ridKeyId.equals(certKeyId)) {
                             signerCert = cert;
                             break;
                         }
@@ -476,7 +467,10 @@
         // Check whether the signer cert returned by the responder is trusted
         if (signerCert != null) {
             // Check if the response is signed by the issuing CA
-            if (signerCert.equals(issuerCert)) {
+            if (signerCert.getSubjectX500Principal().equals(
+                    issuerInfo.getName()) &&
+                    signerCert.getPublicKey().equals(
+                            issuerInfo.getPublicKey())) {
                 if (debug != null) {
                     debug.println("OCSP response is signed by the target's " +
                         "Issuing CA");
@@ -493,7 +487,7 @@
 
             // Check if the response is signed by an authorized responder
             } else if (signerCert.getIssuerX500Principal().equals(
-                       issuerCert.getSubjectX500Principal())) {
+                    issuerInfo.getName())) {
 
                 // Check for the OCSPSigning key purpose
                 try {
@@ -513,8 +507,9 @@
 
                 // Check algorithm constraints specified in security property
                 // "jdk.certpath.disabledAlgorithms".
-                AlgorithmChecker algChecker = new AlgorithmChecker(
-                                    new TrustAnchor(issuerCert, null));
+                AlgorithmChecker algChecker =
+                        new AlgorithmChecker(issuerInfo.getAnchor(), date,
+                                variant);
                 algChecker.init(false);
                 algChecker.check(signerCert, Collections.<String>emptySet());
 
@@ -552,7 +547,7 @@
 
                 // verify the signature
                 try {
-                    signerCert.verify(issuerCert.getPublicKey());
+                    signerCert.verify(issuerInfo.getPublicKey());
                     if (debug != null) {
                         debug.println("OCSP response is signed by an " +
                             "Authorized Responder");
@@ -574,7 +569,7 @@
         if (signerCert != null) {
             // Check algorithm constraints specified in security property
             // "jdk.certpath.disabledAlgorithms".
-            AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId);
+            AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant);
 
             if (!verifySignature(signerCert)) {
                 throw new CertPathValidatorException(
@@ -593,7 +588,6 @@
         }
 
         // Check freshness of OCSPResponse
-
         long now = (date == null) ? System.currentTimeMillis() : date.getTime();
         Date nowPlusSkew = new Date(now + MAX_CLOCK_SKEW);
         Date nowMinusSkew = new Date(now - MAX_CLOCK_SKEW);
@@ -604,16 +598,16 @@
                     until = " until " + sr.nextUpdate;
                 }
                 debug.println("OCSP response validity interval is from " +
-                              sr.thisUpdate + until);
+                        sr.thisUpdate + until);
                 debug.println("Checking validity of OCSP response on: " +
-                    new Date(now));
+                        new Date(now));
             }
 
             // Check that the test date is within the validity interval:
             //   [ thisUpdate - MAX_CLOCK_SKEW,
             //     MAX(thisUpdate, nextUpdate) + MAX_CLOCK_SKEW ]
             if (nowPlusSkew.before(sr.thisUpdate) ||
-                nowMinusSkew.after(
+                    nowMinusSkew.after(
                     sr.nextUpdate != null ? sr.nextUpdate : sr.thisUpdate))
             {
                 throw new CertPathValidatorException(
@@ -625,8 +619,10 @@
 
     /**
      * Returns the OCSP ResponseStatus.
+     *
+     * @return the {@code ResponseStatus} for this OCSP response
      */
-    ResponseStatus getResponseStatus() {
+    public ResponseStatus getResponseStatus() {
         return responseStatus;
     }
 
@@ -664,11 +660,27 @@
     /**
      * Returns the SingleResponse of the specified CertId, or null if
      * there is no response for that CertId.
+     *
+     * @param certId the {@code CertId} for a {@code SingleResponse} to be
+     * searched for in the OCSP response.
+     *
+     * @return the {@code SingleResponse} for the provided {@code CertId},
+     * or {@code null} if it is not found.
      */
-    SingleResponse getSingleResponse(CertId certId) {
+    public SingleResponse getSingleResponse(CertId certId) {
         return singleResponseMap.get(certId);
     }
 
+    /**
+     * Return a set of all CertIds in this {@code OCSPResponse}
+     *
+     * @return an unmodifiable set containing every {@code CertId} in this
+     *      response.
+     */
+    public Set<CertId> getCertIds() {
+        return Collections.unmodifiableSet(singleResponseMap.keySet());
+    }
+
     /*
      * Returns the certificate for the authority that signed the OCSP response.
      */
@@ -676,10 +688,86 @@
         return signerCert; // set in verify()
     }
 
+    /**
+     * Get the {@code ResponderId} from this {@code OCSPResponse}
+     *
+     * @return the {@code ResponderId} from this response or {@code null}
+     *      if no responder ID is in the body of the response (e.g. a
+     *      response with a status other than SUCCESS.
+     */
+    public ResponderId getResponderId() {
+        return respId;
+    }
+
+    /**
+     * Provide a String representation of an OCSPResponse
+     *
+     * @return a human-readable representation of the OCSPResponse
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("OCSP Response:\n");
+        sb.append("Response Status: ").append(responseStatus).append("\n");
+        sb.append("Responder ID: ").append(respId).append("\n");
+        sb.append("Produced at: ").append(producedAtDate).append("\n");
+        int count = singleResponseMap.size();
+        sb.append(count).append(count == 1 ?
+                " response:\n" : " responses:\n");
+        for (SingleResponse sr : singleResponseMap.values()) {
+            sb.append(sr).append("\n");
+        }
+        if (responseExtensions != null && responseExtensions.size() > 0) {
+            count = responseExtensions.size();
+            sb.append(count).append(count == 1 ?
+                    " extension:\n" : " extensions:\n");
+            for (String extId : responseExtensions.keySet()) {
+                sb.append(responseExtensions.get(extId)).append("\n");
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Build a String-Extension map from DER encoded data.
+     * @param derVal A {@code DerValue} object built from a SEQUENCE of
+     *      extensions
+     *
+     * @return a {@code Map} using the OID in string form as the keys.  If no
+     *      extensions are found or an empty SEQUENCE is passed in, then
+     *      an empty {@code Map} will be returned.
+     *
+     * @throws IOException if any decoding errors occur.
+     */
+    private static Map<String, java.security.cert.Extension>
+        parseExtensions(DerValue derVal) throws IOException {
+        DerValue[] extDer = derVal.data.getSequence(3);
+        Map<String, java.security.cert.Extension> extMap =
+                new HashMap<>(extDer.length);
+
+        for (DerValue extDerVal : extDer) {
+            Extension ext = new Extension(extDerVal);
+            if (debug != null) {
+                debug.println("Extension: " + ext);
+            }
+            // We don't support any extensions yet. Therefore, if it
+            // is critical we must throw an exception because we
+            // don't know how to process it.
+            if (ext.isCritical()) {
+                throw new IOException("Unsupported OCSP critical extension: " +
+                        ext.getExtensionId());
+            }
+            extMap.put(ext.getId(), ext);
+        }
+
+        return extMap;
+    }
+
     /*
      * A class representing a single OCSP response.
      */
-    final static class SingleResponse implements OCSP.RevocationStatus {
+    public static final class SingleResponse implements OCSP.RevocationStatus {
         private final CertId certId;
         private final CertStatus certStatus;
         private final Date thisUpdate;
@@ -724,7 +812,7 @@
                 }
             } else {
                 revocationTime = null;
-                revocationReason = CRLReason.UNSPECIFIED;
+                revocationReason = null;
                 if (tag == CERT_STATUS_GOOD) {
                     certStatus = CertStatus.GOOD;
                 } else if (tag == CERT_STATUS_UNKNOWN) {
@@ -735,77 +823,131 @@
             }
 
             thisUpdate = tmp.getGeneralizedTime();
+            if (debug != null) {
+                debug.println("thisUpdate: " + thisUpdate);
+            }
 
-            if (tmp.available() == 0)  {
-                // we are done
-                nextUpdate = null;
-            } else {
+            // Parse optional fields like nextUpdate and singleExtensions
+            Date tmpNextUpdate = null;
+            Map<String, java.security.cert.Extension> tmpMap = null;
+
+            // Check for the first optional item, it could be nextUpdate
+            // [CONTEXT 0] or singleExtensions [CONTEXT 1]
+            if (tmp.available() > 0) {
                 derVal = tmp.getDerValue();
-                tag = (byte)(derVal.tag & 0x1f);
-                if (tag == 0) {
-                    // next update
-                    nextUpdate = derVal.data.getGeneralizedTime();
 
-                    if (tmp.available() == 0)  {
-                        // we are done
+                // nextUpdate processing
+                if (derVal.isContextSpecific((byte)0)) {
+                    tmpNextUpdate = derVal.data.getGeneralizedTime();
+                    if (debug != null) {
+                        debug.println("nextUpdate: " + tmpNextUpdate);
+                    }
+
+                    // If more data exists in the singleResponse, it
+                    // can only be singleExtensions.  Get this DER value
+                    // for processing in the next block
+                    derVal = tmp.available() > 0 ? tmp.getDerValue() : null;
+                }
+
+                // singleExtensions processing
+                if (derVal != null) {
+                    if (derVal.isContextSpecific((byte)1)) {
+                        tmpMap = parseExtensions(derVal);
+
+                        // There should not be any other items in the
+                        // singleResponse at this point.
+                        if (tmp.available() > 0) {
+                            throw new IOException(tmp.available() +
+                                " bytes of additional data in singleResponse");
+                        }
                     } else {
-                        derVal = tmp.getDerValue();
-                        tag = (byte)(derVal.tag & 0x1f);
+                        // Unknown item in the singleResponse
+                        throw new IOException("Unsupported singleResponse " +
+                            "item, tag = " + String.format("%02X", derVal.tag));
                     }
-                } else {
-                    nextUpdate = null;
                 }
             }
-            // singleExtensions
-            if (tmp.available() > 0) {
-                derVal = tmp.getDerValue();
-                if (derVal.isContextSpecific((byte)1)) {
-                    DerValue[] singleExtDer = derVal.data.getSequence(3);
-                    singleExtensions =
-                        new HashMap<String, java.security.cert.Extension>
-                            (singleExtDer.length);
-                    for (int i = 0; i < singleExtDer.length; i++) {
-                        Extension ext = new Extension(singleExtDer[i]);
-                        if (debug != null) {
-                            debug.println("OCSP single extension: " + ext);
-                        }
-                        // We don't support any extensions yet. Therefore, if it
-                        // is critical we must throw an exception because we
-                        // don't know how to process it.
-                        if (ext.isCritical()) {
-                            throw new IOException(
-                                "Unsupported OCSP critical extension: " +
-                                ext.getExtensionId());
-                        }
-                        singleExtensions.put(ext.getId(), ext);
-                    }
-                } else {
-                    singleExtensions = Collections.emptyMap();
+
+            nextUpdate = tmpNextUpdate;
+            singleExtensions = (tmpMap != null) ? tmpMap :
+                    Collections.emptyMap();
+            if (debug != null) {
+                for (java.security.cert.Extension ext :
+                        singleExtensions.values()) {
+                   debug.println("singleExtension: " + ext);
                 }
-            } else {
-                singleExtensions = Collections.emptyMap();
             }
         }
 
         /*
          * Return the certificate's revocation status code
          */
-        @Override public CertStatus getCertStatus() {
+        @Override
+        public CertStatus getCertStatus() {
             return certStatus;
         }
 
-        private CertId getCertId() {
+        /**
+         * Get the Cert ID that this SingleResponse is for.
+         *
+         * @return the {@code CertId} for this {@code SingleResponse}
+         */
+        public CertId getCertId() {
             return certId;
         }
 
-        @Override public Date getRevocationTime() {
-            return (Date) revocationTime.clone();
+        /**
+         * Get the {@code thisUpdate} field from this {@code SingleResponse}.
+         *
+         * @return a {@link Date} object containing the thisUpdate date
+         */
+        public Date getThisUpdate() {
+            return (thisUpdate != null ? (Date) thisUpdate.clone() : null);
         }
 
-        @Override public CRLReason getRevocationReason() {
+        /**
+         * Get the {@code nextUpdate} field from this {@code SingleResponse}.
+         *
+         * @return a {@link Date} object containing the nexUpdate date or
+         * {@code null} if a nextUpdate field is not present in the response.
+         */
+        public Date getNextUpdate() {
+            return (nextUpdate != null ? (Date) nextUpdate.clone() : null);
+        }
+
+        /**
+         * Get the {@code revocationTime} field from this
+         * {@code SingleResponse}.
+         *
+         * @return a {@link Date} object containing the revocationTime date or
+         * {@code null} if the {@code SingleResponse} does not have a status
+         * of {@code REVOKED}.
+         */
+        @Override
+        public Date getRevocationTime() {
+            return (revocationTime != null ? (Date) revocationTime.clone() :
+                    null);
+        }
+
+        /**
+         * Get the {@code revocationReason} field for the
+         * {@code SingleResponse}.
+         *
+         * @return a {@link CRLReason} containing the revocation reason, or
+         * {@code null} if a revocation reason was not provided or the
+         * response status is not {@code REVOKED}.
+         */
+        @Override
+        public CRLReason getRevocationReason() {
             return revocationReason;
         }
 
+        /**
+         * Get the {@code singleExtensions} for this {@code SingleResponse}.
+         *
+         * @return a {@link Map} of {@link Extension} objects, keyed by
+         * their OID value in string form.
+         */
         @Override
         public Map<String, java.security.cert.Extension> getSingleExtensions() {
             return Collections.unmodifiableMap(singleExtensions);
@@ -816,18 +958,117 @@
          */
         @Override public String toString() {
             StringBuilder sb = new StringBuilder();
-            sb.append("SingleResponse:  \n");
+            sb.append("SingleResponse:\n");
             sb.append(certId);
-            sb.append("\nCertStatus: "+ certStatus + "\n");
+            sb.append("\nCertStatus: ").append(certStatus).append("\n");
             if (certStatus == CertStatus.REVOKED) {
-                sb.append("revocationTime is " + revocationTime + "\n");
-                sb.append("revocationReason is " + revocationReason + "\n");
+                sb.append("revocationTime is ");
+                sb.append(revocationTime).append("\n");
+                sb.append("revocationReason is ");
+                sb.append(revocationReason).append("\n");
             }
-            sb.append("thisUpdate is " + thisUpdate + "\n");
+            sb.append("thisUpdate is ").append(thisUpdate).append("\n");
             if (nextUpdate != null) {
-                sb.append("nextUpdate is " + nextUpdate + "\n");
+                sb.append("nextUpdate is ").append(nextUpdate).append("\n");
+            }
+            for (java.security.cert.Extension ext : singleExtensions.values()) {
+                sb.append("singleExtension: ");
+                sb.append(ext.toString()).append("\n");
             }
             return sb.toString();
         }
     }
+
+    /**
+     * Helper class that allows consumers to pass in issuer information.  This
+     * will always consist of the issuer's name and public key, but may also
+     * contain a certificate if the originating data is in that form.  The
+     * trust anchor for the certificate chain will be included for certpath
+     * disabled algorithm checking.
+     */
+    static final class IssuerInfo {
+        private final TrustAnchor anchor;
+        private final X509Certificate certificate;
+        private final X500Principal name;
+        private final PublicKey pubKey;
+
+        IssuerInfo(TrustAnchor anchor) {
+            this(anchor, (anchor != null) ? anchor.getTrustedCert() : null);
+        }
+
+        IssuerInfo(X509Certificate issuerCert) {
+            this(null, issuerCert);
+        }
+
+        IssuerInfo(TrustAnchor anchor, X509Certificate issuerCert) {
+            if (anchor == null && issuerCert == null) {
+                throw new NullPointerException("TrustAnchor and issuerCert " +
+                        "cannot be null");
+            }
+            this.anchor = anchor;
+            if (issuerCert != null) {
+                name = issuerCert.getSubjectX500Principal();
+                pubKey = issuerCert.getPublicKey();
+                certificate = issuerCert;
+            } else {
+                name = anchor.getCA();
+                pubKey = anchor.getCAPublicKey();
+                certificate = anchor.getTrustedCert();
+            }
+        }
+
+        /**
+         * Get the certificate in this IssuerInfo if present.
+         *
+         * @return the {@code X509Certificate} used to create this IssuerInfo
+         * object, or {@code null} if a certificate was not used in its
+         * creation.
+         */
+        X509Certificate getCertificate() {
+            return certificate;
+        }
+
+        /**
+         * Get the name of this issuer.
+         *
+         * @return an {@code X500Principal} corresponding to this issuer's
+         * name.  If derived from an issuer's {@code X509Certificate} this
+         * would be equivalent to the certificate subject name.
+         */
+        X500Principal getName() {
+            return name;
+        }
+
+        /**
+         * Get the public key for this issuer.
+         *
+         * @return a {@code PublicKey} for this issuer.
+         */
+        PublicKey getPublicKey() {
+            return pubKey;
+        }
+
+        /**
+         * Get the TrustAnchor for the certificate chain.
+         *
+         * @return a {@code TrustAnchor}.
+         */
+        TrustAnchor getAnchor() {
+            return anchor;
+        }
+
+        /**
+         * Create a string representation of this IssuerInfo.
+         *
+         * @return a {@code String} form of this IssuerInfo object.
+         */
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Issuer Info:\n");
+            sb.append("Name: ").append(name.toString()).append("\n");
+            sb.append("Public Key:\n").append(pubKey.toString()).append("\n");
+            return sb.toString();
+        }
+    }
 }
--- a/src/share/classes/sun/security/provider/certpath/PKIX.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/PKIX.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 
 import java.security.InvalidAlgorithmParameterException;
 import java.security.PublicKey;
+import java.security.Timestamp;
 import java.security.cert.*;
 import java.security.interfaces.DSAPublicKey;
 import java.util.*;
@@ -85,6 +86,8 @@
         private CertSelector constraints;
         private Set<TrustAnchor> anchors;
         private List<X509Certificate> certs;
+        private Timestamp timestamp;
+        private String variant;
 
         ValidatorParams(CertPath cp, PKIXParameters params)
             throws InvalidAlgorithmParameterException
@@ -100,6 +103,11 @@
         ValidatorParams(PKIXParameters params)
             throws InvalidAlgorithmParameterException
         {
+            if (params instanceof PKIXExtendedParameters) {
+                timestamp = ((PKIXExtendedParameters) params).getTimestamp();
+                variant = ((PKIXExtendedParameters) params).getVariant();
+            }
+
             this.anchors = params.getTrustAnchors();
             // Make sure that none of the trust anchors include name constraints
             // (not supported).
@@ -189,6 +197,14 @@
         PKIXParameters getPKIXParameters() {
             return params;
         }
+
+        Timestamp timestamp() {
+            return timestamp;
+        }
+
+        String variant() {
+            return variant;
+        }
     }
 
     static class BuilderParams extends ValidatorParams {
--- a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, 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
@@ -172,7 +172,8 @@
         List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
         // add standard checkers that we will be using
         certPathCheckers.add(untrustedChecker);
-        certPathCheckers.add(new AlgorithmChecker(anchor));
+        certPathCheckers.add(new AlgorithmChecker(anchor, null, params.date(),
+                params.timestamp(), params.variant()));
         certPathCheckers.add(new KeyChecker(certPathLen,
                                             params.targetCertConstraints()));
         certPathCheckers.add(new ConstraintsChecker(certPathLen));
@@ -189,8 +190,11 @@
                                              rootNode);
         certPathCheckers.add(pc);
         // default value for date is current time
-        BasicChecker bc = new BasicChecker(anchor, params.date(),
-                                           params.sigProvider(), false);
+        BasicChecker bc;
+        bc = new BasicChecker(anchor,
+                (params.timestamp() == null ? params.date() :
+                        params.timestamp().getTimestamp()),
+                params.sigProvider(), false);
         certPathCheckers.add(bc);
 
         boolean revCheckerAdded = false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/provider/certpath/PKIXExtendedParameters.java	Thu May 18 14:30:18 2017 -0700
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.security.provider.certpath;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Timestamp;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.TrustAnchor;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
+ * and a string for the variant type, can be passed when doing certpath
+ * checking.
+ */
+
+public class PKIXExtendedParameters extends PKIXBuilderParameters {
+
+    private final PKIXBuilderParameters p;
+    private Timestamp jarTimestamp;
+    private final String variant;
+
+    public PKIXExtendedParameters(PKIXBuilderParameters params,
+            Timestamp timestamp, String variant)
+            throws InvalidAlgorithmParameterException {
+        super(params.getTrustAnchors(), null);
+        p = params;
+        jarTimestamp = timestamp;
+        this.variant = variant;
+    }
+
+    public Timestamp getTimestamp() {
+        return jarTimestamp;
+    }
+    public void setTimestamp(Timestamp t) {
+        jarTimestamp = t;
+    }
+
+    public String getVariant() {
+        return variant;
+    }
+
+    @Override
+    public void setDate(Date d) {
+        p.setDate(d);
+    }
+
+    @Override
+    public void addCertPathChecker(PKIXCertPathChecker c) {
+        p.addCertPathChecker(c);
+    }
+
+    @Override
+    public void setMaxPathLength(int maxPathLength) {
+        p.setMaxPathLength(maxPathLength);
+    }
+
+    @Override
+    public int getMaxPathLength() {
+        return p.getMaxPathLength();
+    }
+
+    @Override
+    public String toString() {
+        return p.toString();
+    }
+
+    @Override
+    public Set<TrustAnchor> getTrustAnchors() {
+        return p.getTrustAnchors();
+    }
+
+    @Override
+    public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
+            throws InvalidAlgorithmParameterException {
+        // To avoid problems with PKIXBuilderParameter's constructors
+        if (p == null) {
+            return;
+        }
+        p.setTrustAnchors(trustAnchors);
+    }
+
+    @Override
+    public Set<String> getInitialPolicies() {
+        return p.getInitialPolicies();
+    }
+
+    @Override
+    public void setInitialPolicies(Set<String> initialPolicies) {
+        p.setInitialPolicies(initialPolicies);
+    }
+
+    @Override
+    public void setCertStores(List<CertStore> stores) {
+        p.setCertStores(stores);
+    }
+
+    @Override
+    public void addCertStore(CertStore store) {
+        p.addCertStore(store);
+    }
+
+    @Override
+    public List<CertStore> getCertStores() {
+        return p.getCertStores();
+    }
+
+    @Override
+    public void setRevocationEnabled(boolean val) {
+        p.setRevocationEnabled(val);
+    }
+
+    @Override
+    public boolean isRevocationEnabled() {
+        return p.isRevocationEnabled();
+    }
+
+    @Override
+    public void setExplicitPolicyRequired(boolean val) {
+        p.setExplicitPolicyRequired(val);
+    }
+
+    @Override
+    public boolean isExplicitPolicyRequired() {
+        return p.isExplicitPolicyRequired();
+    }
+
+    @Override
+    public void setPolicyMappingInhibited(boolean val) {
+        p.setPolicyMappingInhibited(val);
+    }
+
+    @Override
+    public boolean isPolicyMappingInhibited() {
+        return p.isPolicyMappingInhibited();
+    }
+
+    @Override
+    public void setAnyPolicyInhibited(boolean val) {
+        p.setAnyPolicyInhibited(val);
+    }
+
+    @Override
+    public boolean isAnyPolicyInhibited() {
+        return p.isAnyPolicyInhibited();
+    }
+
+    @Override
+    public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
+        p.setPolicyQualifiersRejected(qualifiersRejected);
+    }
+
+    @Override
+    public boolean getPolicyQualifiersRejected() {
+        return p.getPolicyQualifiersRejected();
+    }
+
+    @Override
+    public Date getDate() {
+        return p.getDate();
+    }
+
+    @Override
+    public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
+        p.setCertPathCheckers(checkers);
+    }
+
+    @Override
+    public List<PKIXCertPathChecker> getCertPathCheckers() {
+        return p.getCertPathCheckers();
+    }
+
+    @Override
+    public String getSigProvider() {
+        return p.getSigProvider();
+    }
+
+    @Override
+    public void setSigProvider(String sigProvider) {
+        p.setSigProvider(sigProvider);
+    }
+
+    @Override
+    public CertSelector getTargetCertConstraints() {
+        return p.getTargetCertConstraints();
+    }
+
+    @Override
+    public void setTargetCertConstraints(CertSelector selector) {
+        // To avoid problems with PKIXBuilderParameter's constructors
+        if (p == null) {
+            return;
+        }
+        p.setTargetCertConstraints(selector);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/provider/certpath/ResponderId.java	Thu May 18 14:30:18 2017 -0700
@@ -0,0 +1,315 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider.certpath;
+
+import java.util.Arrays;
+import java.io.IOException;
+import java.security.PublicKey;
+import javax.security.auth.x500.X500Principal;
+import sun.security.x509.KeyIdentifier;
+import sun.security.util.DerValue;
+
+/**
+ * Class for ResponderId entities as described in RFC6960.  ResponderId objects
+ * are used to uniquely identify OCSP responders.
+ * <p>
+ * The RFC 6960 defines a ResponderID structure as:
+ * <pre>
+ * ResponderID ::= CHOICE {
+ *      byName              [1] Name,
+ *      byKey               [2] KeyHash }
+ *
+ * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
+ * (excluding the tag and length fields)
+ *
+ * Name is defined in RFC 5280.
+ * </pre>
+ *
+ * @see ResponderId.Type
+ * @since 9
+ */
+public final class ResponderId {
+
+    /**
+     * A {@code ResponderId} enumeration describing the accepted forms for a
+     * {@code ResponderId}.
+     *
+     * @see ResponderId
+     * @since 9
+     */
+    public static enum Type {
+        /**
+         * A BY_NAME {@code ResponderId} will be built from a subject name,
+         * either as an {@code X500Principal} or a DER-encoded byte array.
+         */
+        BY_NAME(1, "byName"),
+
+        /**
+         * A BY_KEY {@code ResponderId} will be built from a public key
+         * identifier, either derived from a {@code PublicKey} or directly
+         * from a DER-encoded byte array containing the key identifier.
+         */
+        BY_KEY(2, "byKey");
+
+        private final int tagNumber;
+        private final String ridTypeName;
+
+        private Type(int value, String name) {
+            this.tagNumber = value;
+            this.ridTypeName = name;
+        }
+
+        public int value() {
+            return tagNumber;
+        }
+
+        @Override
+        public String toString() {
+            return ridTypeName;
+        }
+    }
+
+    private Type type;
+    private X500Principal responderName;
+    private KeyIdentifier responderKeyId;
+    private byte[] encodedRid;
+
+    /**
+     * Constructs a {@code ResponderId} object using an {@code X500Principal}.
+     * When encoded in DER this object will use the BY_NAME option.
+     *
+     * @param subjectName the subject name of the certificate used
+     * to sign OCSP responses.
+     *
+     * @throws IOException if the internal DER-encoding of the
+     *      {@code X500Principal} fails.
+     */
+    public ResponderId(X500Principal subjectName) throws IOException {
+        responderName = subjectName;
+        responderKeyId = null;
+        encodedRid = principalToBytes();
+        type = Type.BY_NAME;
+    }
+
+    /**
+     * Constructs a {@code ResponderId} object using a {@code PublicKey}.
+     * When encoded in DER this object will use the byKey option, a
+     * SHA-1 hash of the responder's public key.
+     *
+     * @param pubKey the the OCSP responder's public key
+     *
+     * @throws IOException if the internal DER-encoding of the
+     *      {@code KeyIdentifier} fails.
+     */
+    public ResponderId(PublicKey pubKey) throws IOException {
+        responderKeyId = new KeyIdentifier(pubKey);
+        responderName = null;
+        encodedRid = keyIdToBytes();
+        type = Type.BY_KEY;
+    }
+
+    /**
+     * Constructs a {@code ResponderId} object from its DER-encoding.
+     *
+     * @param encodedData the DER-encoded bytes
+     *
+     * @throws IOException if the encodedData is not properly DER encoded
+     */
+    public ResponderId(byte[] encodedData) throws IOException {
+        DerValue outer = new DerValue(encodedData);
+
+        if (outer.isContextSpecific((byte)Type.BY_NAME.value())
+                && outer.isConstructed()) {
+            // Use the X500Principal constructor as a way to sanity
+            // check the incoming data.
+            responderName = new X500Principal(outer.getDataBytes());
+            encodedRid = principalToBytes();
+            type = Type.BY_NAME;
+        } else if (outer.isContextSpecific((byte)Type.BY_KEY.value())
+                && outer.isConstructed()) {
+            // Use the KeyIdentifier constructor as a way to sanity
+            // check the incoming data.
+            responderKeyId =
+                new KeyIdentifier(new DerValue(outer.getDataBytes()));
+            encodedRid = keyIdToBytes();
+            type = Type.BY_KEY;
+        } else {
+            throw new IOException("Invalid ResponderId content");
+        }
+    }
+
+    /**
+     * Encode a {@code ResponderId} in DER form
+     *
+     * @return a byte array containing the DER-encoded representation for this
+     *      {@code ResponderId}
+     */
+    public byte[] getEncoded() {
+        return encodedRid.clone();
+    }
+
+    /**
+     * Return the type of {@ResponderId}
+     *
+     * @return a number corresponding to the context-specific tag number
+     *      used in the DER-encoding for a {@code ResponderId}
+     */
+    public ResponderId.Type getType() {
+        return type;
+    }
+
+    /**
+     * Get the length of the encoded {@code ResponderId} (including the tag and
+     * length of the explicit tagging from the outer ASN.1 CHOICE).
+     *
+     * @return the length of the encoded {@code ResponderId}
+     */
+    public int length() {
+        return encodedRid.length;
+    }
+
+    /**
+     * Obtain the underlying {@code X500Principal} from a {@code ResponderId}
+     *
+     * @return the {@code X500Principal} for this {@code ResponderId} if it
+     *      is a BY_NAME variant.  If the {@code ResponderId} is a BY_KEY
+     *      variant, this routine will return {@code null}.
+     */
+    public X500Principal getResponderName() {
+        return responderName;
+    }
+
+    /**
+     * Obtain the underlying key identifier from a {@code ResponderId}
+     *
+     * @return the {@code KeyIdentifier} for this {@code ResponderId} if it
+     *      is a BY_KEY variant.  If the {@code ResponderId} is a BY_NAME
+     *      variant, this routine will return {@code null}.
+     */
+    public KeyIdentifier getKeyIdentifier() {
+        return responderKeyId;
+    }
+
+    /**
+     * Compares the specified object with this {@code ResponderId} for equality.
+     * A ResponderId will only be considered equivalent if both the type and
+     * data value are equal.  Two ResponderIds initialized by name and
+     * key ID, respectively, will not be equal even if the
+     * ResponderId objects are created from the same source certificate.
+     *
+     * @param obj the object to be compared against
+     *
+     * @return true if the specified object is equal to this {@code Responderid}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof ResponderId) {
+            ResponderId respObj = (ResponderId)obj;
+                return Arrays.equals(encodedRid, respObj.getEncoded());
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the hash code value for this {@code ResponderId}
+     *
+     * @return the hash code value for this {@code ResponderId}
+     */
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(encodedRid);
+    }
+
+    /**
+     * Create a String representation of this {@code ResponderId}
+     *
+     * @return a String representation of this {@code ResponderId}
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        switch (type) {
+            case BY_NAME:
+                sb.append(type).append(": ").append(responderName);
+                break;
+            case BY_KEY:
+                sb.append(type).append(": ");
+                for (byte keyIdByte : responderKeyId.getIdentifier()) {
+                    sb.append(String.format("%02X", keyIdByte));
+                }
+                break;
+            default:
+                sb.append("Unknown ResponderId Type: ").append(type);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Convert the responderName data member into its DER-encoded form
+     *
+     * @return the DER encoding for a responder ID byName option, including
+     *      explicit context-specific tagging.
+     *
+     * @throws IOException if any encoding error occurs
+     */
+    private byte[] principalToBytes() throws IOException {
+        DerValue dv = new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte)Type.BY_NAME.value()),
+                responderName.getEncoded());
+        return dv.toByteArray();
+    }
+
+    /**
+     * Convert the responderKeyId data member into its DER-encoded form
+     *
+     * @return the DER encoding for a responder ID byKey option, including
+     *      explicit context-specific tagging.
+     *
+     * @throws IOException if any encoding error occurs
+     */
+    private byte[] keyIdToBytes() throws IOException {
+        // Place the KeyIdentifier bytes into an OCTET STRING
+        DerValue inner = new DerValue(DerValue.tag_OctetString,
+                responderKeyId.getIdentifier());
+
+        // Mark the OCTET STRING-wrapped KeyIdentifier bytes
+        // as EXPLICIT CONTEXT 2
+        DerValue outer = new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT,
+                true, (byte)Type.BY_KEY.value()), inner.toByteArray());
+
+        return outer.toByteArray();
+    }
+
+}
--- a/src/share/classes/sun/security/provider/certpath/RevocationChecker.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/RevocationChecker.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,6 @@
 
 import static sun.security.provider.certpath.OCSP.*;
 import static sun.security.provider.certpath.PKIX.*;
-import sun.security.action.GetPropertyAction;
 import sun.security.x509.*;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.util.Debug;
@@ -62,12 +61,12 @@
     private List<CertStore> certStores;
     private Map<X509Certificate, byte[]> ocspResponses;
     private List<Extension> ocspExtensions;
-    private boolean legacy;
+    private final boolean legacy;
     private LinkedList<CertPathValidatorException> softFailExceptions =
         new LinkedList<>();
 
     // state variables
-    private X509Certificate issuerCert;
+    private OCSPResponse.IssuerInfo issuerInfo;
     private PublicKey prevPubKey;
     private boolean crlSignFlag;
     private int certIndex;
@@ -302,9 +301,9 @@
                 CertPathValidatorException("forward checking not supported");
         }
         if (anchor != null) {
-            issuerCert = anchor.getTrustedCert();
-            prevPubKey = (issuerCert != null) ? issuerCert.getPublicKey()
-                                              : anchor.getCAPublicKey();
+            issuerInfo = new OCSPResponse.IssuerInfo(anchor);
+            prevPubKey = issuerInfo.getPublicKey();
+
         }
         crlSignFlag = true;
         if (params != null && params.certPath() != null) {
@@ -438,7 +437,7 @@
     private void updateState(X509Certificate cert)
         throws CertPathValidatorException
     {
-        issuerCert = cert;
+        issuerInfo = new OCSPResponse.IssuerInfo(anchor, cert);
 
         // Make new public key if parameters are missing
         PublicKey pubKey = cert.getPublicKey();
@@ -466,6 +465,34 @@
                   stackedCerts, params.trustAnchors());
     }
 
+    static boolean isCausedByNetworkIssue(String type, CertStoreException cse) {
+        boolean result;
+        Throwable t = cse.getCause();
+
+        switch (type) {
+            case "LDAP":
+                if (t != null) {
+                    // These two exception classes are inside java.naming module
+                    String cn = t.getClass().getName();
+                    result = (cn.equals("javax.naming.ServiceUnavailableException") ||
+                        cn.equals("javax.naming.CommunicationException"));
+                } else {
+                    result = false;
+                }
+                break;
+            case "SSLServer":
+                result = (t != null && t instanceof IOException);
+                break;
+            case "URI":
+                result = (t != null && t instanceof IOException);
+                break;
+            default:
+                // we don't know about any other remote CertStore types
+                return false;
+        }
+        return result;
+    }
+
     private void checkCRLs(X509Certificate cert, PublicKey prevKey,
                            X509Certificate prevCert, boolean signFlag,
                            boolean allowSeparateKey,
@@ -478,9 +505,9 @@
                           " ---checking revocation status ...");
         }
 
-        // reject circular dependencies - RFC 3280 is not explicit on how
-        // to handle this, so we feel it is safest to reject them until
-        // the issue is resolved in the PKIX WG.
+        // Reject circular dependencies - RFC 5280 is not explicit on how
+        // to handle this, but does suggest that they can be a security
+        // risk and can create unresolvable dependencies
         if (stackedCerts != null && stackedCerts.contains(cert)) {
             if (debug != null) {
                 debug.println("RevocationChecker.checkCRLs()" +
@@ -510,7 +537,7 @@
                                   "CertStoreException: " + e.getMessage());
                 }
                 if (networkFailureException == null &&
-                    CertStoreHelper.isCausedByNetworkIssue(store.getType(),e)) {
+                    isCausedByNetworkIssue(store.getType(),e)) {
                     // save this exception, we may need to throw it later
                     networkFailureException = new CertPathValidatorException(
                         "Unable to determine revocation status due to " +
@@ -550,15 +577,14 @@
             try {
                 if (crlDP) {
                     approvedCRLs.addAll(DistributionPointFetcher.getCRLs(
-                                        sel, signFlag, prevKey, prevCert,
-                                        params.sigProvider(), certStores,
-                                        reasonsMask, anchors, null));
+                            sel, signFlag, prevKey, prevCert,
+                            params.sigProvider(), certStores, reasonsMask,
+                            anchors, null, params.variant()));
                 }
             } catch (CertStoreException e) {
                 if (e instanceof CertStoreTypeException) {
                     CertStoreTypeException cste = (CertStoreTypeException)e;
-                    if (CertStoreHelper.isCausedByNetworkIssue(cste.getType(),
-                                                               e)) {
+                    if (isCausedByNetworkIssue(cste.getType(), e)) {
                         throw new CertPathValidatorException(
                             "Unable to determine revocation status due to " +
                             "network error", e, null, -1,
@@ -634,7 +660,7 @@
                 /*
                  * Abort CRL validation and throw exception if there are any
                  * unrecognized critical CRL entry extensions (see section
-                 * 5.3 of RFC 3280).
+                 * 5.3 of RFC 5280).
                  */
                 Set<String> unresCritExts = entry.getCriticalExtensionOIDs();
                 if (unresCritExts != null && !unresCritExts.isEmpty()) {
@@ -682,14 +708,8 @@
         OCSPResponse response = null;
         CertId certId = null;
         try {
-            if (issuerCert != null) {
-                certId = new CertId(issuerCert,
-                                    currCert.getSerialNumberObject());
-            } else {
-                // must be an anchor name and key
-                certId = new CertId(anchor.getCA(), anchor.getCAPublicKey(),
-                                    currCert.getSerialNumberObject());
-            }
+            certId = new CertId(issuerInfo.getName(), issuerInfo.getPublicKey(),
+                    currCert.getSerialNumberObject());
 
             // check if there is a cached OCSP response available
             byte[] responseBytes = ocspResponses.get(cert);
@@ -706,8 +726,8 @@
                         nonce = ext.getValue();
                     }
                 }
-                response.verify(Collections.singletonList(certId), issuerCert,
-                                responderCert, params.date(), nonce);
+                response.verify(Collections.singletonList(certId), issuerInfo,
+                        responderCert, params.date(), nonce, params.variant());
 
             } else {
                 URI responderURI = (this.responderURI != null)
@@ -720,8 +740,8 @@
                 }
 
                 response = OCSP.check(Collections.singletonList(certId),
-                                      responderURI, issuerCert, responderCert,
-                                      null, ocspExtensions);
+                        responderURI, issuerInfo, responderCert, null,
+                        ocspExtensions, params.variant());
             }
         } catch (IOException e) {
             throw new CertPathValidatorException(
@@ -833,7 +853,7 @@
                     if (DistributionPointFetcher.verifyCRL(
                             certImpl, point, crl, reasonsMask, signFlag,
                             prevKey, null, params.sigProvider(), anchors,
-                            certStores, params.date()))
+                            certStores, params.date(), params.variant()))
                     {
                         results.add(crl);
                     }
@@ -886,9 +906,9 @@
                 " ---checking " + msg + "...");
         }
 
-        // reject circular dependencies - RFC 3280 is not explicit on how
-        // to handle this, so we feel it is safest to reject them until
-        // the issue is resolved in the PKIX WG.
+        // Reject circular dependencies - RFC 5280 is not explicit on how
+        // to handle this, but does suggest that they can be a security
+        // risk and can create unresolvable dependencies
         if ((stackedCerts != null) && stackedCerts.contains(cert)) {
             if (debug != null) {
                 debug.println(
--- a/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, 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
@@ -50,7 +50,7 @@
  * <p> If successful, it returns a certification path which has successfully
  * satisfied all the constraints and requirements specified in the
  * PKIXBuilderParameters object and has been validated according to the PKIX
- * path validation algorithm defined in RFC 3280.
+ * path validation algorithm defined in RFC 5280.
  *
  * <p> This implementation uses a depth-first search approach to finding
  * certification paths. If it comes to a point in which it cannot find
@@ -343,7 +343,8 @@
                 checkers.add(policyChecker);
 
                 // add the algorithm checker
-                checkers.add(new AlgorithmChecker(builder.trustAnchor));
+                checkers.add(new AlgorithmChecker(builder.trustAnchor,
+                        buildParams.date(), buildParams.variant()));
 
                 BasicChecker basicChecker = null;
                 if (nextState.keyParamsNeeded()) {
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -37,6 +37,7 @@
 
 import sun.security.provider.certpath.AlgorithmChecker;
 import sun.security.action.GetPropertyAction;
+import sun.security.validator.Validator;
 
 public abstract class SSLContextImpl extends SSLContextSpi {
 
@@ -1040,7 +1041,7 @@
                 constraints = new SSLAlgorithmConstraints(sslSocket, true);
             }
 
-            checkAlgorithmConstraints(chain, constraints);
+            checkAlgorithmConstraints(chain, constraints, isClient);
         }
     }
 
@@ -1082,12 +1083,12 @@
                 constraints = new SSLAlgorithmConstraints(engine, true);
             }
 
-            checkAlgorithmConstraints(chain, constraints);
+            checkAlgorithmConstraints(chain, constraints, isClient);
         }
     }
 
     private void checkAlgorithmConstraints(X509Certificate[] chain,
-            AlgorithmConstraints constraints) throws CertificateException {
+            AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
 
         try {
             // Does the certificate chain end with a trusted certificate?
@@ -1105,7 +1106,9 @@
 
             // A forward checker, need to check from trust to target
             if (checkedLength >= 0) {
-                AlgorithmChecker checker = new AlgorithmChecker(constraints);
+                AlgorithmChecker checker =
+                        new AlgorithmChecker(constraints, null,
+                                (isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
                 checker.init(false);
                 for (int i = checkedLength; i >= 0; i--) {
                     Certificate cert = chain[i];
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -220,6 +220,11 @@
                                     Collections.<SNIServerName>emptyList();
     Collection<SNIMatcher>      sniMatchers =
                                     Collections.<SNIMatcher>emptyList();
+    // Is the serverNames set to empty with SSLParameters.setServerNames()?
+    private boolean             noSniExtension = false;
+
+    // Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
+    private boolean             noSniMatcher = false;
 
     /*
      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
@@ -666,6 +671,11 @@
         }
 
         super.connect(endpoint, timeout);
+
+        if (host == null || host.length() == 0) {
+            useImplicitHost(false);
+        }
+
         doneConnect();
     }
 
@@ -2158,41 +2168,61 @@
         output.r.setVersion(protocolVersion);
     }
 
+    //
+    // ONLY used by ClientHandshaker for the server hostname during handshaking
+    //
     synchronized String getHost() {
         // Note that the host may be null or empty for localhost.
         if (host == null || host.length() == 0) {
-            if (!trustNameService) {
-                // If the local name service is not trustworthy, reverse host
-                // name resolution should not be performed for endpoint
-                // identification.  Use the application original specified
-                // hostname or IP address instead.
-                host = getOriginalHostname(getInetAddress());
-            } else {
-                host = getInetAddress().getHostName();
-            }
+            useImplicitHost(true);
         }
 
         return host;
     }
 
     /*
-     * Get the original application specified hostname.
+     * Try to set and use the implicit specified hostname
      */
-    private static String getOriginalHostname(InetAddress inetAddress) {
-        /*
-         * Get the original hostname via sun.misc.SharedSecrets.
-         */
+    private synchronized void useImplicitHost(boolean noSniUpdate) {
+
+        // Note: If the local name service is not trustworthy, reverse
+        // host name resolution should not be performed for endpoint
+        // identification.  Use the application original specified
+        // hostname or IP address instead.
+
+        // Get the original hostname via jdk.internal.misc.SharedSecrets
+        InetAddress inetAddress = getInetAddress();
+        if (inetAddress == null) {      // not connected
+            return;
+        }
+
         JavaNetAccess jna = SharedSecrets.getJavaNetAccess();
         String originalHostname = jna.getOriginalHostName(inetAddress);
+        if ((originalHostname != null) &&
+                (originalHostname.length() != 0)) {
 
-        /*
-         * If no application specified hostname, use the IP address.
-         */
-        if (originalHostname == null || originalHostname.length() == 0) {
-            originalHostname = inetAddress.getHostAddress();
+            host = originalHostname;
+            if (!noSniUpdate && serverNames.isEmpty() && !noSniExtension) {
+                serverNames =
+                        Utilities.addToSNIServerNameList(serverNames, host);
+
+                if (!roleIsServer &&
+                        (handshaker != null) && !handshaker.started()) {
+                    handshaker.setSNIServerNames(serverNames);
+                }
+            }
+
+            return;
         }
 
-        return originalHostname;
+        // No explicitly specified hostname, no server name indication.
+        if (!trustNameService) {
+            // The local name service is not trustworthy, use IP address.
+            host = inetAddress.getHostAddress();
+        } else {
+            // Use the underlying reverse host name resolution service.
+            host = getInetAddress().getHostName();
+        }
     }
 
 
@@ -2205,6 +2235,10 @@
         this.host = host;
         this.serverNames =
             Utilities.addToSNIServerNameList(this.serverNames, this.host);
+
+        if (!roleIsServer && (handshaker != null) && !handshaker.started()) {
+            handshaker.setSNIServerNames(serverNames);
+        }
     }
 
     /**
@@ -2571,8 +2605,21 @@
         // the super implementation does not handle the following parameters
         params.setEndpointIdentificationAlgorithm(identificationProtocol);
         params.setAlgorithmConstraints(algorithmConstraints);
-        params.setSNIMatchers(sniMatchers);
-        params.setServerNames(serverNames);
+
+        if (sniMatchers.isEmpty() && !noSniMatcher) {
+            // 'null' indicates none has been set
+            params.setSNIMatchers(null);
+        } else {
+            params.setSNIMatchers(sniMatchers);
+        }
+
+        if (serverNames.isEmpty() && !noSniExtension) {
+            // 'null' indicates none has been set
+            params.setServerNames(null);
+        } else {
+            params.setServerNames(serverNames);
+        }
+
         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
 
         return params;
@@ -2592,11 +2639,13 @@
 
         List<SNIServerName> sniNames = params.getServerNames();
         if (sniNames != null) {
+            noSniExtension = sniNames.isEmpty();
             serverNames = sniNames;
         }
 
         Collection<SNIMatcher> matchers = params.getSNIMatchers();
         if (matchers != null) {
+            noSniMatcher = matchers.isEmpty();
             sniMatchers = matchers;
         }
 
--- a/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
 import javax.net.ssl.*;
 
 import sun.security.provider.certpath.AlgorithmChecker;
+import sun.security.validator.Validator;
 
 /**
  * The new X509 key manager implementation. The main differences to the
@@ -62,7 +63,7 @@
 
     private static final Debug debug = Debug.getInstance("ssl");
 
-    private final static boolean useDebug =
+    private static final boolean useDebug =
                             (debug != null) && Debug.isOn("keymanager");
 
     // for unit testing only, set via privileged reflection
@@ -661,6 +662,15 @@
 
             return CheckResult.OK;
         }
+
+        public String getValidator() {
+            if (this == CLIENT) {
+                return Validator.VAR_TLS_CLIENT;
+            } else if (this == SERVER) {
+                return Validator.VAR_TLS_SERVER;
+            }
+            return Validator.VAR_GENERIC;
+        }
     }
 
     // enum for the result of the extension check
@@ -774,7 +784,8 @@
 
             // check the algorithm constraints
             if (constraints != null &&
-                    !conformsToAlgorithmConstraints(constraints, chain)) {
+                    !conformsToAlgorithmConstraints(constraints, chain,
+                            checkType.getValidator())) {
 
                 if (useDebug) {
                     debug.println("Ignoring alias " + alias +
@@ -811,13 +822,19 @@
     }
 
     private static boolean conformsToAlgorithmConstraints(
-            AlgorithmConstraints constraints, Certificate[] chain) {
+            AlgorithmConstraints constraints, Certificate[] chain,
+            String variant) {
 
-        AlgorithmChecker checker = new AlgorithmChecker(constraints);
+        AlgorithmChecker checker = new AlgorithmChecker(constraints, null, variant);
         try {
             checker.init(false);
         } catch (CertPathValidatorException cpve) {
             // unlikely to happen
+            if (useDebug) {
+                debug.println(
+                    "Cannot initialize algorithm constraints checker: " + cpve);
+            }
+
             return false;
         }
 
@@ -828,6 +845,11 @@
                 // We don't care about the unresolved critical extensions.
                 checker.check(cert, Collections.<String>emptySet());
             } catch (CertPathValidatorException cpve) {
+                if (useDebug) {
+                    debug.println("Certificate (" + cert +
+                        ") does not conform to algorithm constraints: " + cpve);
+                }
+
                 return false;
             }
         }
--- a/src/share/classes/sun/security/util/AnchorCertificates.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/util/AnchorCertificates.java	Thu May 18 14:30:18 2017 -0700
@@ -31,8 +31,10 @@
 import java.security.KeyStore;
 import java.security.PrivilegedAction;
 import java.security.cert.X509Certificate;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.Set;
 
 import sun.security.x509.X509CertImpl;
 
@@ -44,7 +46,7 @@
 
     private static final Debug debug = Debug.getInstance("certpath");
     private static final String HASH = "SHA-256";
-    private static HashSet<String> certs;
+    private static Set<String> certs = Collections.emptySet();
 
     static  {
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/src/share/classes/sun/security/util/CertConstraintParameters.java	Fri Apr 28 14:28:06 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.util;
-
-import java.security.cert.X509Certificate;
-
-/**
- * This class is a wrapper for keeping state and passing objects between PKIX,
- * AlgorithmChecker, and DisabledAlgorithmConstraints.
- */
-public class CertConstraintParameters {
-    // A certificate being passed to check against constraints.
-    private final X509Certificate cert;
-
-    // This is true if the trust anchor in the certificate chain matches a cert
-    // in AnchorCertificates
-    private final boolean trustedMatch;
-
-    public CertConstraintParameters(X509Certificate c, boolean match) {
-        cert = c;
-        trustedMatch = match;
-    }
-
-    public CertConstraintParameters(X509Certificate c) {
-        this(c, false);
-    }
-
-    // Returns if the trust anchor has a match if anchor checking is enabled.
-    public boolean isTrustedMatch() {
-        return trustedMatch;
-    }
-
-    public X509Certificate getCertificate() {
-        return cert;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/util/ConstraintsParameters.java	Thu May 18 14:30:18 2017 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import sun.security.validator.Validator;
+
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.Timestamp;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * This class contains parameters for checking against constraints that extend
+ * past the publicly available parameters in java.security.AlgorithmConstraints.
+
+ * This is currently on passed between  between PKIX, AlgorithmChecker,
+ * and DisabledAlgorithmConstraints.
+ */
+public class ConstraintsParameters {
+    /*
+     * The below 3 values are used the same as the permit() methods
+     * published in java.security.AlgorithmConstraints.
+     */
+    // Algorithm string to be checked against constraints
+    private final String algorithm;
+    // AlgorithmParameters to the algorithm being checked
+    private final AlgorithmParameters algParams;
+    // Public Key being checked against constraints
+    private final Key publicKey;
+
+    /*
+     * New values that are checked against constraints that the current public
+     * API does not support.
+     */
+    // A certificate being passed to check against constraints.
+    private final X509Certificate cert;
+    // This is true if the trust anchor in the certificate chain matches a cert
+    // in AnchorCertificates
+    private final boolean trustedMatch;
+    // PKIXParameter date
+    private final Date pkixDate;
+    // Timestamp of the signed JAR file
+    private final Timestamp jarTimestamp;
+    private final String variant;
+
+    public ConstraintsParameters(X509Certificate c, boolean match,
+            Date pkixdate, Timestamp jarTime, String variant) {
+        cert = c;
+        trustedMatch = match;
+        pkixDate = pkixdate;
+        jarTimestamp = jarTime;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+        algorithm = null;
+        algParams = null;
+        publicKey = null;
+    }
+
+    public ConstraintsParameters(String algorithm, AlgorithmParameters params,
+            Key key, String variant) {
+        this.algorithm = algorithm;
+        algParams = params;
+        this.publicKey = key;
+        cert = null;
+        trustedMatch = false;
+        pkixDate = null;
+        jarTimestamp = null;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+    }
+
+
+    public ConstraintsParameters(X509Certificate c) {
+        this(c, false, null, null,
+                Validator.VAR_GENERIC);
+    }
+
+    public ConstraintsParameters(Timestamp jarTime) {
+        this(null, false, null, jarTime, Validator.VAR_GENERIC);
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public AlgorithmParameters getAlgParams() {
+        return algParams;
+    }
+
+    public Key getPublicKey() {
+        return publicKey;
+    }
+    // Returns if the trust anchor has a match if anchor checking is enabled.
+    public boolean isTrustedMatch() {
+        return trustedMatch;
+    }
+
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+
+    public Date getPKIXParamDate() {
+        return pkixDate;
+    }
+
+    public Timestamp getJARTimestamp() {
+        return jarTimestamp;
+    }
+
+    public String getVariant() {
+        return variant;
+    }
+}
--- a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, 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
@@ -25,17 +25,28 @@
 
 package sun.security.util;
 
+import sun.security.validator.Validator;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
 import java.security.CryptoPrimitive;
 import java.security.AlgorithmParameters;
 import java.security.Key;
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertPathValidatorException.BasicReason;
 import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 
@@ -49,11 +60,11 @@
     private static final Debug debug = Debug.getInstance("certpath");
 
     // the known security property, jdk.certpath.disabledAlgorithms
-    public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
+    public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
             "jdk.certpath.disabledAlgorithms";
 
     // the known security property, jdk.tls.disabledAlgorithms
-    public final static String PROPERTY_TLS_DISABLED_ALGS =
+    public static final String PROPERTY_TLS_DISABLED_ALGS =
             "jdk.tls.disabledAlgorithms";
 
     // the known security property, jdk.jar.disabledAlgorithms
@@ -93,14 +104,8 @@
      * there are keysize or other limit, this method allow the algorithm.
      */
     @Override
-    final public boolean permits(Set<CryptoPrimitive> primitives,
+    public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
-
-        if (primitives == null || primitives.isEmpty()) {
-            throw new IllegalArgumentException(
-                        "No cryptographic primitive specified");
-        }
-
         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
     }
 
@@ -109,7 +114,7 @@
      * placed on the key.
      */
     @Override
-    final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
+    public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
         return checkConstraints(primitives, "", key, null);
     }
 
@@ -118,7 +123,7 @@
      * been placed on the key.
      */
     @Override
-    final public boolean permits(Set<CryptoPrimitive> primitives,
+    public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, Key key, AlgorithmParameters parameters) {
 
         if (algorithm == null || algorithm.length() == 0) {
@@ -128,6 +133,18 @@
         return checkConstraints(primitives, algorithm, key, parameters);
     }
 
+    public final void permits(ConstraintsParameters cp)
+            throws CertPathValidatorException {
+        permits(cp.getAlgorithm(), cp);
+    }
+
+    public final void permits(String algorithm, Key key,
+            AlgorithmParameters params, String variant)
+            throws CertPathValidatorException {
+        permits(algorithm, new ConstraintsParameters(algorithm, params, key,
+                (variant == null) ? Validator.VAR_GENERIC : variant));
+    }
+
     /*
      * Check if a x509Certificate object is permitted.  Check if all
      * algorithms are allowed, certificate constraints, and the
@@ -135,18 +152,10 @@
      *
      * Uses new style permit() which throws exceptions.
      */
-    public final void permits(Set<CryptoPrimitive> primitives,
-            CertConstraintParameters cp) throws CertPathValidatorException {
-        checkConstraints(primitives, cp);
-    }
 
-    /*
-     * Check if Certificate object is within the constraints.
-     * Uses new style permit() which throws exceptions.
-     */
-    public final void permits(Set<CryptoPrimitive> primitives,
-            X509Certificate cert) throws CertPathValidatorException {
-        checkConstraints(primitives, new CertConstraintParameters(cert));
+    public final void permits(String algorithm, ConstraintsParameters cp)
+            throws CertPathValidatorException {
+        algorithmConstraints.permits(algorithm, cp);
     }
 
     // Check if a string is contained inside the property
@@ -169,7 +178,7 @@
             throw new IllegalArgumentException("The key cannot be null");
         }
 
-        // check the signature algorithm
+        // check the signature algorithm with parameters
         if (algorithm != null && algorithm.length() != 0) {
             if (!permits(primitives, algorithm, parameters)) {
                 return false;
@@ -185,36 +194,6 @@
         return algorithmConstraints.permits(key);
     }
 
-    /*
-     * Check algorithm constraints with Certificate
-     * Uses new style permit() which throws exceptions.
-     */
-    private void checkConstraints(Set<CryptoPrimitive> primitives,
-            CertConstraintParameters cp) throws CertPathValidatorException {
-
-        X509Certificate cert = cp.getCertificate();
-        String algorithm = cert.getSigAlgName();
-
-        // Check signature algorithm is not disabled
-        if (!permits(primitives, algorithm, null)) {
-            throw new CertPathValidatorException(
-                    "Algorithm constraints check failed on disabled "+
-                            "signature algorithm: " + algorithm,
-                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
-        // Check key algorithm is not disabled
-        if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
-            throw new CertPathValidatorException(
-                    "Algorithm constraints check failed on disabled "+
-                            "public key algorithm: " + algorithm,
-                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
-        // Check the certificate and key constraints
-        algorithmConstraints.permits(cp);
-
-    }
 
     /**
      * Key and Certificate Constraints
@@ -229,15 +208,18 @@
      * 'true' means the operation is allowed.
      * 'false' means it failed the constraints and is disallowed.
      *
-     * When passing CertConstraintParameters through permit(), an exception
+     * When passing ConstraintsParameters through permit(), an exception
      * will be thrown on a failure to better identify why the operation was
      * disallowed.
      */
 
     private static class Constraints {
-        private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
-        private static final Pattern keySizePattern = Pattern.compile(
-                "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
+        private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
+
+        private static class Holder {
+            private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
+                    "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
+        }
 
         public Constraints(String[] constraintArray) {
             for (String constraintEntry : constraintArray) {
@@ -252,39 +234,47 @@
 
                 // Check if constraint is a complete disabling of an
                 // algorithm or has conditions.
-                String algorithm;
-                String policy;
                 int space = constraintEntry.indexOf(' ');
-                if (space > 0) {
-                    algorithm = AlgorithmDecomposer.hashName(
-                            constraintEntry.substring(0, space).
-                                    toUpperCase(Locale.ENGLISH));
-                    policy = constraintEntry.substring(space + 1);
-                } else {
-                    constraintsMap.putIfAbsent(
-                            constraintEntry.toUpperCase(Locale.ENGLISH),
-                            new HashSet<>());
+                String algorithm = AlgorithmDecomposer.hashName(
+                        ((space > 0 ? constraintEntry.substring(0, space) :
+                                constraintEntry).
+                                toUpperCase(Locale.ENGLISH)));
+                List<Constraint> constraintList =
+                        constraintsMap.getOrDefault(algorithm,
+                                new ArrayList<>(1));
+                constraintsMap.putIfAbsent(algorithm, constraintList);
+                if (space <= 0) {
+                    constraintList.add(new DisabledConstraint(algorithm));
                     continue;
                 }
 
+                String policy = constraintEntry.substring(space + 1);
+
                 // Convert constraint conditions into Constraint classes
-                Constraint c = null;
-                Constraint lastConstraint = null;
+                Constraint c, lastConstraint = null;
                 // Allow only one jdkCA entry per constraint entry
                 boolean jdkCALimit = false;
+                // Allow only one denyAfter entry per constraint entry
+                boolean denyAfterLimit = false;
 
                 for (String entry : policy.split("&")) {
                     entry = entry.trim();
 
-                    Matcher matcher = keySizePattern.matcher(entry);
-                    if (matcher.matches()) {
+                    Matcher matcher;
+                    if (entry.startsWith("keySize")) {
                         if (debug != null) {
                             debug.println("Constraints set to keySize: " +
                                     entry);
                         }
+                        StringTokenizer tokens = new StringTokenizer(entry);
+                        if (!"keySize".equals(tokens.nextToken())) {
+                            throw new IllegalArgumentException("Error in " +
+                                    "security property. Constraint unknown: " +
+                                    entry);
+                        }
                         c = new KeySizeConstraint(algorithm,
-                                KeySizeConstraint.Operator.of(matcher.group(1)),
-                                Integer.parseInt(matcher.group(2)));
+                                KeySizeConstraint.Operator.of(tokens.nextToken()),
+                                Integer.parseInt(tokens.nextToken()));
 
                     } else if (entry.equalsIgnoreCase("jdkCA")) {
                         if (debug != null) {
@@ -297,18 +287,39 @@
                         }
                         c = new jdkCAConstraint(algorithm);
                         jdkCALimit = true;
+
+                    } else if (entry.startsWith("denyAfter") &&
+                            (matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
+                                    .matches()) {
+                        if (debug != null) {
+                            debug.println("Constraints set to denyAfter");
+                        }
+                        if (denyAfterLimit) {
+                            throw new IllegalArgumentException("Only one " +
+                                    "denyAfter entry allowed in property. " +
+                                    "Constraint: " + constraintEntry);
+                        }
+                        int year = Integer.parseInt(matcher.group(1));
+                        int month = Integer.parseInt(matcher.group(2));
+                        int day = Integer.parseInt(matcher.group(3));
+                        c = new DenyAfterConstraint(algorithm, year, month,
+                                day);
+                        denyAfterLimit = true;
+                    } else if (entry.startsWith("usage")) {
+                        String s[] = (entry.substring(5)).trim().split(" ");
+                        c = new UsageConstraint(algorithm, s);
+                        if (debug != null) {
+                            debug.println("Constraints usage length is " + s.length);
+                        }
+                    } else {
+                        throw new IllegalArgumentException("Error in security" +
+                                " property. Constraint unknown: " + entry);
                     }
 
                     // Link multiple conditions for a single constraint
                     // into a linked list.
                     if (lastConstraint == null) {
-                        if (!constraintsMap.containsKey(algorithm)) {
-                            constraintsMap.putIfAbsent(algorithm,
-                                    new HashSet<>());
-                        }
-                        if (c != null) {
-                            constraintsMap.get(algorithm).add(c);
-                        }
+                        constraintList.add(c);
                     } else {
                         lastConstraint.nextConstraint = c;
                     }
@@ -318,61 +329,73 @@
         }
 
         // Get applicable constraints based off the signature algorithm
-        private Set<Constraint> getConstraints(String algorithm) {
+        private List<Constraint> getConstraints(String algorithm) {
             return constraintsMap.get(algorithm);
         }
 
         // Check if KeySizeConstraints permit the specified key
         public boolean permits(Key key) {
-            Set<Constraint> set = getConstraints(key.getAlgorithm());
-            if (set == null) {
+            List<Constraint> list = getConstraints(key.getAlgorithm());
+            if (list == null) {
                 return true;
             }
-            for (Constraint constraint : set) {
+            for (Constraint constraint : list) {
                 if (!constraint.permits(key)) {
                     if (debug != null) {
                         debug.println("keySizeConstraint: failed key " +
                                 "constraint check " + KeyUtil.getKeySize(key));
                     }
-            return false;
+                    return false;
+                }
+            }
+            return true;
         }
-            }
-        return true;
-    }
 
         // Check if constraints permit this cert.
-        public void permits(CertConstraintParameters cp)
+        public void permits(String algorithm, ConstraintsParameters cp)
                 throws CertPathValidatorException {
             X509Certificate cert = cp.getCertificate();
 
             if (debug != null) {
-                debug.println("Constraints.permits(): " + cert.getSigAlgName());
+                debug.println("Constraints.permits(): " + algorithm +
+                        " Variant: " + cp.getVariant());
             }
 
             // Get all signature algorithms to check for constraints
-            Set<String> algorithms =
-                    AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
-            if (algorithms == null || algorithms.isEmpty()) {
-                return;
-    }
+            Set<String> algorithms = new HashSet<>();
+            if (algorithm != null) {
+                algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
+            }
 
-            // Attempt to add the public key algorithm to the set
-            algorithms.add(cert.getPublicKey().getAlgorithm());
-
+            // Attempt to add the public key algorithm if cert provided
+            if (cert != null) {
+                algorithms.add(cert.getPublicKey().getAlgorithm());
+            }
+            if (cp.getPublicKey() != null) {
+                algorithms.add(cp.getPublicKey().getAlgorithm());
+            }
             // Check all applicable constraints
-            for (String algorithm : algorithms) {
-                Set<Constraint> set = getConstraints(algorithm);
-                if (set == null) {
+            for (String alg : algorithms) {
+                List<Constraint> list = getConstraints(alg);
+                if (list == null) {
                     continue;
                 }
-                for (Constraint constraint : set) {
+                for (Constraint constraint : list) {
                     constraint.permits(cp);
                 }
             }
         }
-                        }
+    }
 
-    // Abstract class for algorithm constraint checking
+    /**
+     * This abstract Constraint class for algorithm-based checking
+     * may contain one or more constraints.  If the '&' on the {@Security}
+     * property is used, multiple constraints have been grouped together
+     * requiring all the constraints to fail for the check to be disallowed.
+     *
+     * If the class contains multiple constraints, the next constraint
+     * is stored in {@code nextConstraint} in linked-list fashion.
+     */
     private abstract static class Constraint {
         String algorithm;
         Constraint nextConstraint = null;
@@ -408,22 +431,87 @@
         }
 
         /**
-         * Check if an algorithm constraint permit this key to be used.
+         * Check if an algorithm constraint is permitted with a given key.
+         *
+         * If the check inside of {@code permit()} fails, it must call
+         * {@code next()} with the same {@code Key} parameter passed if
+         * multiple constraints need to be checked.
+         *
          * @param key Public key
-         * @return true if constraints do not match
+         * @return 'true' if constraint is allowed, 'false' if disallowed.
          */
         public boolean permits(Key key) {
             return true;
         }
 
         /**
-         * Check if an algorithm constraint is permit this certificate to
-         * be used.
-         * @param cp CertificateParameter containing certificate and state info
-         * @return true if constraints do not match
+         * Check if an algorithm constraint is permitted with a given
+         * ConstraintsParameters.
+         *
+         * If the check inside of {@code permits()} fails, it must call
+         * {@code next()} with the same {@code ConstraintsParameters}
+         * parameter passed if multiple constraints need to be checked.
+         *
+         * @param cp CertConstraintParameter containing certificate info
+         * @throws CertPathValidatorException if constraint disallows.
+         *
          */
-        public abstract void permits(CertConstraintParameters cp)
+        public abstract void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException;
+
+        /**
+         * Recursively check if the constraints are allowed.
+         *
+         * If {@code nextConstraint} is non-null, this method will
+         * call {@code nextConstraint}'s {@code permits()} to check if the
+         * constraint is allowed or denied.  If the constraint's
+         * {@code permits()} is allowed, this method will exit this and any
+         * recursive next() calls, returning 'true'.  If the constraints called
+         * were disallowed, the last constraint will throw
+         * {@code CertPathValidatorException}.
+         *
+         * @param cp ConstraintsParameters
+         * @return 'true' if constraint allows the operation, 'false' if
+         * we are at the end of the constraint list or,
+         * {@code nextConstraint} is null.
+         */
+        boolean next(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            if (nextConstraint != null) {
+                nextConstraint.permits(cp);
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Recursively check if this constraint is allowed,
+         *
+         * If {@code nextConstraint} is non-null, this method will
+         * call {@code nextConstraint}'s {@code permit()} to check if the
+         * constraint is allowed or denied.  If the constraint's
+         * {@code permit()} is allowed, this method will exit this and any
+         * recursive next() calls, returning 'true'.  If the constraints
+         * called were disallowed the check will exit with 'false'.
+         *
+         * @param key Public key
+         * @return 'true' if constraint allows the operation, 'false' if
+         * the constraint denies the operation.
+         */
+        boolean next(Key key) {
+            if (nextConstraint != null && nextConstraint.permits(key)) {
+                return true;
+            }
+            return false;
+        }
+
+        String extendedMsg(ConstraintsParameters cp) {
+            return (cp.getCertificate() == null ? "." :
+                    " used with certificate: " +
+                            cp.getCertificate().getSubjectX500Principal() +
+                    (cp.getVariant() != Validator.VAR_GENERIC ?
+                            ".  Usage was " + cp.getVariant() : "."));
+        }
     }
 
     /*
@@ -436,30 +524,175 @@
         }
 
         /*
-         * Check if each constraint fails and check if there is a linked
-         * constraint  Any permitted constraint will exit the linked list
-         * to allow the operation.
+         * Check if ConstraintsParameters has a trusted match, if it does
+         * call next() for any following constraints. If it does not, exit
+         * as this constraint(s) does not restrict the operation.
          */
-        public void permits(CertConstraintParameters cp)
+        public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             if (debug != null) {
                 debug.println("jdkCAConstraints.permits(): " + algorithm);
             }
 
-            // Return false if the chain has a trust anchor in cacerts
+            // Check chain has a trust anchor in cacerts
             if (cp.isTrustedMatch()) {
-                if (nextConstraint != null) {
-                    nextConstraint.permits(cp);
+                if (next(cp)) {
                     return;
                 }
                 throw new CertPathValidatorException(
                         "Algorithm constraints check failed on certificate " +
-                                "anchor limits",
+                        "anchor limits. " + algorithm + extendedMsg(cp),
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
     }
 
+    /*
+     * This class handles the denyAfter constraint.  The date is in the UTC/GMT
+     * timezone.
+     */
+     private static class DenyAfterConstraint extends Constraint {
+         private Date denyAfterDate;
+         private static final SimpleDateFormat dateFormat =
+                 new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy");
+
+         DenyAfterConstraint(String algo, int year, int month, int day) {
+             Calendar c;
+
+             algorithm = algo;
+
+             if (debug != null) {
+                 debug.println("DenyAfterConstraint read in as:  year " +
+                         year + ", month = " + month + ", day = " + day);
+             }
+
+             c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT"))
+                     .setDate(year, month - 1, day).build();
+
+             if (year > c.getActualMaximum(Calendar.YEAR) ||
+                     year < c.getActualMinimum(Calendar.YEAR)) {
+                 throw new IllegalArgumentException(
+                         "Invalid year given in constraint: " + year);
+             }
+             if ((month - 1) > c.getActualMaximum(Calendar.MONTH) ||
+                     (month - 1) < c.getActualMinimum(Calendar.MONTH)) {
+                 throw new IllegalArgumentException(
+                         "Invalid month given in constraint: " + month);
+             }
+             if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) ||
+                     day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) {
+                 throw new IllegalArgumentException(
+                         "Invalid Day of Month given in constraint: " + day);
+             }
+
+             denyAfterDate = c.getTime();
+             if (debug != null) {
+                 debug.println("DenyAfterConstraint date set to: " +
+                         dateFormat.format(denyAfterDate));
+             }
+         }
+
+         /*
+          * Checking that the provided date is not beyond the constraint date.
+          * The provided date can be the PKIXParameter date if given,
+          * otherwise it is the current date.
+          *
+          * If the constraint disallows, call next() for any following
+          * constraints. Throw an exception if this is the last constraint.
+          */
+         @Override
+         public void permits(ConstraintsParameters cp)
+                 throws CertPathValidatorException {
+             Date currentDate;
+             String errmsg;
+
+             if (cp.getJARTimestamp() != null) {
+                 currentDate = cp.getJARTimestamp().getTimestamp();
+                 errmsg = "JAR Timestamp date: ";
+             } else if (cp.getPKIXParamDate() != null) {
+                 currentDate = cp.getPKIXParamDate();
+                 errmsg = "PKIXParameter date: ";
+             } else {
+                 currentDate = new Date();
+                 errmsg = "Current date: ";
+             }
+
+             if (!denyAfterDate.after(currentDate)) {
+                 if (next(cp)) {
+                     return;
+                 }
+                 throw new CertPathValidatorException(
+                         "denyAfter constraint check failed: " + algorithm +
+                         " used with Constraint date: " +
+                         dateFormat.format(denyAfterDate) + "; " + errmsg +
+                         dateFormat.format(currentDate) + extendedMsg(cp),
+                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+             }
+         }
+
+         /*
+          * Return result if the constraint's date is beyond the current date
+          * in UTC timezone.
+          */
+         public boolean permits(Key key) {
+             if (next(key)) {
+                 return true;
+             }
+             if (debug != null) {
+                 debug.println("DenyAfterConstraints.permits(): " + algorithm);
+             }
+
+             return denyAfterDate.after(new Date());
+         }
+     }
+
+    /*
+     * The usage constraint is for the "usage" keyword.  It checks against the
+     * variant value in ConstraintsParameters.
+     */
+    private static class UsageConstraint extends Constraint {
+        String[] usages;
+
+        UsageConstraint(String algorithm, String[] usages) {
+            this.algorithm = algorithm;
+            this.usages = usages;
+        }
+
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            for (String usage : usages) {
+
+                String v = null;
+                if (usage.compareToIgnoreCase("TLSServer") == 0) {
+                    v = Validator.VAR_TLS_SERVER;
+                } else if (usage.compareToIgnoreCase("TLSClient") == 0) {
+                    v = Validator.VAR_TLS_CLIENT;
+                } else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
+                    v = Validator.VAR_PLUGIN_CODE_SIGNING;
+                }
+
+                if (debug != null) {
+                    debug.println("Checking if usage constraint \"" + v +
+                            "\" matches \"" + cp.getVariant() + "\"");
+                    // Because usage checking can come from many places
+                    // a stack trace is very helpful.
+                    ByteArrayOutputStream ba = new ByteArrayOutputStream();
+                    PrintStream ps = new PrintStream(ba);
+                    (new Exception()).printStackTrace(ps);
+                    debug.println(ba.toString());
+                }
+                if (cp.getVariant().compareTo(v) == 0) {
+                    if (next(cp)) {
+                        return;
+                    }
+                    throw new CertPathValidatorException("Usage constraint " +
+                            usage + " check failed: " + algorithm +
+                            extendedMsg(cp),
+                            null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+                }
+            }
+        }
+    }
 
     /*
      * This class contains constraints dealing with the key size
@@ -513,15 +746,23 @@
          * constraint  Any permitted constraint will exit the linked list
          * to allow the operation.
          */
-        public void permits(CertConstraintParameters cp)
+        public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
-            if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+            Key key = null;
+            if (cp.getPublicKey() != null) {
+                key = cp.getPublicKey();
+            } else if (cp.getCertificate() != null) {
+                key = cp.getCertificate().getPublicKey();
+            }
+            if (key != null && !permitsImpl(key)) {
                 if (nextConstraint != null) {
                     nextConstraint.permits(cp);
                     return;
                 }
                 throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on keysize limits",
+                        "Algorithm constraints check failed on keysize limits. " +
+                        algorithm + " " + KeyUtil.getKeySize(key) + "bit key" +
+                        extendedMsg(cp),
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
@@ -559,6 +800,27 @@
 
             return true;
         }
+    }
+
+    /*
+     * This constraint is used for the complete disabling of the algorithm.
+     */
+    private static class DisabledConstraint extends Constraint {
+        DisabledConstraint(String algo) {
+            algorithm = algo;
+        }
+
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled " +
+                            "algorithm: " + algorithm + extendedMsg(cp),
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        public boolean permits(Key key) {
+            return false;
         }
     }
+}
 
--- a/src/share/classes/sun/security/util/SignatureFileVerifier.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,25 +28,23 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.CodeSigner;
-import java.security.CryptoPrimitive;
+import java.security.GeneralSecurityException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SignatureException;
+import java.security.Timestamp;
 import java.security.cert.CertPath;
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
 import java.util.Base64;
-import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 import java.util.jar.Attributes;
 import java.util.jar.JarException;
 import java.util.jar.JarFile;
@@ -61,9 +59,6 @@
     /* Are we debugging ? */
     private static final Debug debug = Debug.getInstance("jar");
 
-    private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
-            Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
-
     private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
             new DisabledAlgorithmConstraints(
                     DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
@@ -78,7 +73,7 @@
     private PKCS7 block;
 
     /** the raw bytes of the .SF file */
-    private byte sfBytes[];
+    private byte[] sfBytes;
 
     /** the name of the signature block file, uppercased and without
      *  the extension (.DSA/.RSA/.EC)
@@ -97,6 +92,14 @@
     /* for generating certpath objects */
     private CertificateFactory certificateFactory = null;
 
+    /** Algorithms that have been checked if they are weak. */
+    private Map<String, Boolean> permittedAlgs= new HashMap<>();
+
+    /** TSA timestamp of signed jar.  The newest timestamp is used.  If there
+     *  was no TSA timestamp used when signed, current time is used ("null").
+     */
+    private Timestamp timestamp = null;
+
     /**
      * Create the named SignatureFileVerifier.
      *
@@ -107,7 +110,7 @@
     public SignatureFileVerifier(ArrayList<CodeSigner[]> signerCache,
                                  ManifestDigester md,
                                  String name,
-                                 byte rawBytes[])
+                                 byte[] rawBytes)
         throws IOException, CertificateException
     {
         // new PKCS7() calls CertificateFactory.getInstance()
@@ -121,7 +124,7 @@
         } finally {
             Providers.stopJarVerification(obj);
         }
-        this.name = name.substring(0, name.lastIndexOf("."))
+        this.name = name.substring(0, name.lastIndexOf('.'))
                                                    .toUpperCase(Locale.ENGLISH);
         this.md = md;
         this.signerCache = signerCache;
@@ -152,7 +155,7 @@
      * used to set the raw bytes of the .SF file when it
      * is external to the signature block file.
      */
-    public void setSignatureFile(byte sfBytes[])
+    public void setSignatureFile(byte[] sfBytes)
     {
         this.sfBytes = sfBytes;
     }
@@ -168,11 +171,10 @@
      */
     public static boolean isBlockOrSF(String s) {
         // we currently only support DSA and RSA PKCS7 blocks
-        if (s.endsWith(".SF") || s.endsWith(".DSA") ||
-                s.endsWith(".RSA") || s.endsWith(".EC")) {
-            return true;
-        }
-        return false;
+        return s.endsWith(".SF")
+            || s.endsWith(".DSA")
+            || s.endsWith(".RSA")
+            || s.endsWith(".EC");
     }
 
     /**
@@ -182,7 +184,7 @@
      * unknown signature related files (those starting with SIG- with
      * an optional [A-Z0-9]{1,3} extension right inside META-INF).
      *
-     * @param s file name
+     * @param name file name
      * @return true if the input file name is signature related
      */
     public static boolean isSigningRelated(String name) {
@@ -198,7 +200,7 @@
             return true;
         } else if (name.startsWith("SIG-")) {
             // check filename extension
-            // see https://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures
+            // see http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures
             // for what filename extensions are legal
             int extIndex = name.lastIndexOf('.');
             if (extIndex != -1) {
@@ -223,17 +225,10 @@
 
     /** get digest from cache */
 
-    private MessageDigest getDigest(String algorithm) throws SignatureException {
-        // check that algorithm is not restricted
-        if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
-            SignatureException e =
-                    new SignatureException("SignatureFile check failed. " +
-                            "Disabled algorithm used: " + algorithm);
-            throw e;
-        }
-
+    private MessageDigest getDigest(String algorithm)
+            throws SignatureException {
         if (createdDigests == null)
-            createdDigests = new HashMap<String, MessageDigest>();
+            createdDigests = new HashMap<>();
 
         MessageDigest digest = createdDigests.get(algorithm);
 
@@ -303,6 +298,27 @@
         if (newSigners == null)
             return;
 
+        /*
+         * Look for the latest timestamp in the signature block.  If an entry
+         * has no timestamp, use current time (aka null).
+         */
+        for (CodeSigner s: newSigners) {
+            if (debug != null) {
+                debug.println("Gathering timestamp for:  " + s.toString());
+            }
+            if (s.getTimestamp() == null) {
+                timestamp = null;
+                break;
+            } else if (timestamp == null) {
+                timestamp = s.getTimestamp();
+            } else {
+                if (timestamp.getTimestamp().before(
+                        s.getTimestamp().getTimestamp())) {
+                    timestamp = s.getTimestamp();
+                }
+            }
+        }
+
         Iterator<Map.Entry<String,Attributes>> entries =
                                 sf.getEntries().entrySet().iterator();
 
@@ -346,6 +362,68 @@
     }
 
     /**
+     * Check if algorithm is permitted using the permittedAlgs Map.
+     * If the algorithm is not in the map, check against disabled algorithms and
+     * store the result. If the algorithm is in the map use that result.
+     * False is returned for weak algorithm, true for good algorithms.
+     */
+    boolean permittedCheck(String key, String algorithm) {
+        Boolean permitted = permittedAlgs.get(algorithm);
+        if (permitted == null) {
+            try {
+                JAR_DISABLED_CHECK.permits(algorithm,
+                        new ConstraintsParameters(timestamp));
+            } catch(GeneralSecurityException e) {
+                permittedAlgs.put(algorithm, Boolean.FALSE);
+                permittedAlgs.put(key.toUpperCase(), Boolean.FALSE);
+                if (debug != null) {
+                    if (e.getMessage() != null) {
+                        debug.println(key + ":  " + e.getMessage());
+                    } else {
+                        debug.println(key + ":  " + algorithm +
+                                " was disabled, no exception msg given.");
+                        e.printStackTrace();
+                    }
+                }
+                return false;
+            }
+
+            permittedAlgs.put(algorithm, Boolean.TRUE);
+            return true;
+        }
+
+        // Algorithm has already been checked, return the value from map.
+        return permitted.booleanValue();
+    }
+
+    /**
+     * With a given header (*-DIGEST*), return a string that lists all the
+     * algorithms associated with the header.
+     * If there are none, return "Unknown Algorithm".
+     */
+    String getWeakAlgorithms(String header) {
+        String w = "";
+        try {
+            for (String key : permittedAlgs.keySet()) {
+                if (key.endsWith(header)) {
+                    w += key.substring(0, key.length() - header.length()) + " ";
+                }
+            }
+        } catch (RuntimeException e) {
+            w = "Unknown Algorithm(s).  Error processing " + header + ".  " +
+                    e.getMessage();
+        }
+
+        // This means we have an error in finding weak algorithms, run in
+        // debug mode to see permittedAlgs map's values.
+        if (w.length() == 0) {
+            return "Unknown Algorithm(s)";
+        }
+
+        return w;
+    }
+
+    /**
      * See if the whole manifest was signed.
      */
     private boolean verifyManifestHash(Manifest sf,
@@ -355,6 +433,10 @@
     {
         Attributes mattr = sf.getMainAttributes();
         boolean manifestSigned = false;
+        // If only weak algorithms are used.
+        boolean weakAlgs = true;
+        // If a "*-DIGEST-MANIFEST" entry is found.
+        boolean validEntry = false;
 
         // go through all the attributes and process *-Digest-Manifest entries
         for (Map.Entry<Object,Object> se : mattr.entrySet()) {
@@ -364,6 +446,16 @@
             if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST-MANIFEST")) {
                 // 16 is length of "-Digest-Manifest"
                 String algorithm = key.substring(0, key.length()-16);
+                validEntry = true;
+
+                // Check if this algorithm is permitted, skip if false.
+                if (!permittedCheck(key, algorithm)) {
+                    continue;
+                }
+
+                // A non-weak algorithm was used, any weak algorithms found do
+                // not need to be reported.
+                weakAlgs = false;
 
                 manifestDigests.add(key);
                 manifestDigests.add(se.getValue());
@@ -374,15 +466,14 @@
                         Base64.getMimeDecoder().decode((String)se.getValue());
 
                     if (debug != null) {
-                     debug.println("Signature File: Manifest digest " +
-                                          digest.getAlgorithm());
-                     debug.println( "  sigfile  " + toHex(expectedHash));
-                     debug.println( "  computed " + toHex(computedHash));
-                     debug.println();
+                        debug.println("Signature File: Manifest digest " +
+                                algorithm);
+                        debug.println( "  sigfile  " + toHex(expectedHash));
+                        debug.println( "  computed " + toHex(computedHash));
+                        debug.println();
                     }
 
-                    if (MessageDigest.isEqual(computedHash,
-                                              expectedHash)) {
+                    if (MessageDigest.isEqual(computedHash, expectedHash)) {
                         manifestSigned = true;
                     } else {
                         //XXX: we will continue and verify each section
@@ -390,15 +481,33 @@
                 }
             }
         }
+
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms entries used, throw an exception.
+        if (validEntry && weakAlgs) {
+            throw new SignatureException("Manifest hash check failed " +
+                    "(DIGEST-MANIFEST). Disabled algorithm(s) used: " +
+                    getWeakAlgorithms("-DIGEST-MANIFEST"));
+        }
         return manifestSigned;
     }
 
-    private boolean verifyManifestMainAttrs(Manifest sf,
-                                        ManifestDigester md)
+    private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
          throws IOException, SignatureException
     {
         Attributes mattr = sf.getMainAttributes();
         boolean attrsVerified = true;
+        // If only weak algorithms are used.
+        boolean weakAlgs = true;
+        // If a ATTR_DIGEST entry is found.
+        boolean validEntry = false;
 
         // go through all the attributes and process
         // digest entries for the manifest main attributes
@@ -408,6 +517,16 @@
             if (key.toUpperCase(Locale.ENGLISH).endsWith(ATTR_DIGEST)) {
                 String algorithm =
                         key.substring(0, key.length() - ATTR_DIGEST.length());
+                validEntry = true;
+
+                // Check if this algorithm is permitted, skip if false.
+                if (!permittedCheck(key, algorithm)) {
+                    continue;
+                }
+
+                // A non-weak algorithm was used, any weak algorithms found do
+                // not need to be reported.
+                weakAlgs = false;
 
                 MessageDigest digest = getDigest(algorithm);
                 if (digest != null) {
@@ -426,8 +545,7 @@
                      debug.println();
                     }
 
-                    if (MessageDigest.isEqual(computedHash,
-                                              expectedHash)) {
+                    if (MessageDigest.isEqual(computedHash, expectedHash)) {
                         // good
                     } else {
                         // we will *not* continue and verify each section
@@ -443,6 +561,22 @@
             }
         }
 
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms entries used, throw an exception.
+        if (validEntry && weakAlgs) {
+            throw new SignatureException("Manifest Main Attribute check " +
+                    "failed (" + ATTR_DIGEST + ").  " +
+                    "Disabled algorithm(s) used: " +
+                    getWeakAlgorithms(ATTR_DIGEST));
+        }
+
         // this method returns 'true' if either:
         //      . manifest main attributes were not signed, or
         //      . manifest main attributes were signed and verified
@@ -465,6 +599,10 @@
     {
         boolean oneDigestVerified = false;
         ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
+        // If only weak algorithms are used.
+        boolean weakAlgs = true;
+        // If a "*-DIGEST" entry is found.
+        boolean validEntry = false;
 
         if (mde == null) {
             throw new SecurityException(
@@ -472,8 +610,7 @@
         }
 
         if (sfAttr != null) {
-
-            //sun.misc.HexDumpEncoder hex = new sun.misc.HexDumpEncoder();
+            //sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
             //hex.encodeBuffer(data, System.out);
 
             // go through all the attributes and process *-Digest entries
@@ -483,6 +620,16 @@
                 if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST")) {
                     // 7 is length of "-Digest"
                     String algorithm = key.substring(0, key.length()-7);
+                    validEntry = true;
+
+                    // Check if this algorithm is permitted, skip if false.
+                    if (!permittedCheck(key, algorithm)) {
+                        continue;
+                    }
+
+                    // A non-weak algorithm was used, any weak algorithms found do
+                    // not need to be reported.
+                    weakAlgs = false;
 
                     MessageDigest digest = getDigest(algorithm);
 
@@ -533,6 +680,22 @@
                 }
             }
         }
+
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms entries used, throw an exception.
+        if (validEntry && weakAlgs) {
+            throw new SignatureException("Manifest Main Attribute check " +
+                    "failed (DIGEST).  Disabled algorithm(s) used: " +
+                    getWeakAlgorithms("DIGEST"));
+        }
+
         return oneDigestVerified;
     }
 
@@ -541,7 +704,7 @@
      * CodeSigner objects. We do this only *once* for a given
      * signature block file.
      */
-    private CodeSigner[] getSigners(SignerInfo infos[], PKCS7 block)
+    private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block)
         throws IOException, NoSuchAlgorithmException, SignatureException,
             CertificateException {
 
@@ -553,7 +716,7 @@
             ArrayList<X509Certificate> chain = info.getCertificateChain(block);
             CertPath certChain = certificateFactory.generateCertPath(chain);
             if (signers == null) {
-                signers = new ArrayList<CodeSigner>();
+                signers = new ArrayList<>();
             }
             // Append the new code signer
             signers.add(new CodeSigner(certChain, info.getTimestamp()));
@@ -582,7 +745,7 @@
 
     static String toHex(byte[] data) {
 
-        StringBuffer sb = new StringBuffer(data.length*2);
+        StringBuilder sb = new StringBuilder(data.length*2);
 
         for (int i=0; i<data.length; i++) {
             sb.append(hexc[(data[i] >>4) & 0x0f]);
--- a/src/share/classes/sun/security/validator/PKIXValidator.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/validator/PKIXValidator.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,10 +33,11 @@
 import javax.security.auth.x500.X500Principal;
 import sun.security.action.GetBooleanAction;
 import sun.security.provider.certpath.AlgorithmChecker;
+import sun.security.provider.certpath.PKIXExtendedParameters;
 
 /**
  * Validator implementation built on the PKIX CertPath API. This
- * implementation will be emphasized going forward.<p>
+ * implementation will be emphasized going forward.
  * <p>
  * Note that the validate() implementation tries to use a PKIX validator
  * if that appears possible and a PKIX builder otherwise. This increases
@@ -208,13 +209,22 @@
                 ("null or zero-length certificate chain");
         }
 
-        // add  new algorithm constraints checker
-        PKIXBuilderParameters pkixParameters =
-                    (PKIXBuilderParameters) parameterTemplate.clone();
-        AlgorithmChecker algorithmChecker = null;
+        // Use PKIXExtendedParameters for timestamp and variant additions
+        PKIXBuilderParameters pkixParameters = null;
+        try {
+            pkixParameters = new PKIXExtendedParameters(
+                    (PKIXBuilderParameters) parameterTemplate.clone(),
+                    (parameter instanceof Timestamp) ?
+                            (Timestamp) parameter : null,
+                    variant);
+        } catch (InvalidAlgorithmParameterException e) {
+            // ignore exception
+        }
+
+        // add a new algorithm constraints checker
         if (constraints != null) {
-            algorithmChecker = new AlgorithmChecker(constraints);
-            pkixParameters.addCertPathChecker(algorithmChecker);
+            pkixParameters.addCertPathChecker(
+                    new AlgorithmChecker(constraints, null, variant));
         }
 
         if (TRY_VALIDATOR) {
--- a/src/share/classes/sun/security/validator/SimpleValidator.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/validator/SimpleValidator.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
 import javax.security.auth.x500.X500Principal;
 
 import sun.security.x509.X509CertImpl;
+import sun.security.x509.KeyIdentifier;
 import sun.security.x509.NetscapeCertTypeExtension;
 import sun.security.util.DerValue;
 import sun.security.util.DerInputStream;
@@ -153,12 +154,14 @@
 
         // create default algorithm constraints checker
         TrustAnchor anchor = new TrustAnchor(anchorCert, null);
-        AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
+        AlgorithmChecker defaultAlgChecker =
+                new AlgorithmChecker(anchor, variant);
 
         // create application level algorithm constraints checker
         AlgorithmChecker appAlgChecker = null;
         if (constraints != null) {
-            appAlgChecker = new AlgorithmChecker(anchor, constraints);
+            appAlgChecker = new AlgorithmChecker(anchor, constraints, null,
+                    null, variant);
         }
 
         // verify top down, starting at the certificate issued by
--- a/src/share/classes/sun/security/x509/PKIXExtensions.java	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/classes/sun/security/x509/PKIXExtensions.java	Thu May 18 14:30:18 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,34 +49,39 @@
  */
 public class PKIXExtensions {
     // The object identifiers
-    private static final int AuthorityKey_data [] = { 2, 5, 29, 35 };
-    private static final int SubjectKey_data [] = { 2, 5, 29, 14 };
-    private static final int KeyUsage_data [] = { 2, 5, 29, 15 };
-    private static final int PrivateKeyUsage_data [] = { 2, 5, 29, 16 };
-    private static final int CertificatePolicies_data [] = { 2, 5, 29, 32 };
-    private static final int PolicyMappings_data [] = { 2, 5, 29, 33 };
-    private static final int SubjectAlternativeName_data [] = { 2, 5, 29, 17 };
-    private static final int IssuerAlternativeName_data [] = { 2, 5, 29, 18 };
-    private static final int SubjectDirectoryAttributes_data [] = { 2, 5, 29, 9 };
-    private static final int BasicConstraints_data [] = { 2, 5, 29, 19 };
-    private static final int NameConstraints_data [] = { 2, 5, 29, 30 };
-    private static final int PolicyConstraints_data [] = { 2, 5, 29, 36 };
-    private static final int CRLDistributionPoints_data [] = { 2, 5, 29, 31 };
-    private static final int CRLNumber_data [] = { 2, 5, 29, 20 };
-    private static final int IssuingDistributionPoint_data [] = { 2, 5, 29, 28 };
-    private static final int DeltaCRLIndicator_data [] = { 2, 5, 29, 27 };
-    private static final int ReasonCode_data [] = { 2, 5, 29, 21 };
-    private static final int HoldInstructionCode_data [] = { 2, 5, 29, 23 };
-    private static final int InvalidityDate_data [] = { 2, 5, 29, 24 };
-    private static final int ExtendedKeyUsage_data [] = { 2, 5, 29, 37 };
-    private static final int InhibitAnyPolicy_data [] = { 2, 5, 29, 54 };
-    private static final int CertificateIssuer_data [] = { 2, 5, 29, 29 };
-    private static final int AuthInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 1};
-    private static final int SubjectInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 11};
-    private static final int FreshestCRL_data [] = { 2, 5, 29, 46 };
-    private static final int OCSPNoCheck_data [] = { 1, 3, 6, 1, 5, 5, 7,
+    private static final int[] AuthorityKey_data = { 2, 5, 29, 35 };
+    private static final int[] SubjectKey_data = { 2, 5, 29, 14 };
+    private static final int[] KeyUsage_data = { 2, 5, 29, 15 };
+    private static final int[] PrivateKeyUsage_data = { 2, 5, 29, 16 };
+    private static final int[] CertificatePolicies_data = { 2, 5, 29, 32 };
+    private static final int[] PolicyMappings_data = { 2, 5, 29, 33 };
+    private static final int[] SubjectAlternativeName_data = { 2, 5, 29, 17 };
+    private static final int[] IssuerAlternativeName_data = { 2, 5, 29, 18 };
+    private static final int[] SubjectDirectoryAttributes_data = { 2, 5, 29, 9 };
+    private static final int[] BasicConstraints_data = { 2, 5, 29, 19 };
+    private static final int[] NameConstraints_data = { 2, 5, 29, 30 };
+    private static final int[] PolicyConstraints_data = { 2, 5, 29, 36 };
+    private static final int[] CRLDistributionPoints_data = { 2, 5, 29, 31 };
+    private static final int[] CRLNumber_data = { 2, 5, 29, 20 };
+    private static final int[] IssuingDistributionPoint_data = { 2, 5, 29, 28 };
+    private static final int[] DeltaCRLIndicator_data = { 2, 5, 29, 27 };
+    private static final int[] ReasonCode_data = { 2, 5, 29, 21 };
+    private static final int[] HoldInstructionCode_data = { 2, 5, 29, 23 };
+    private static final int[] InvalidityDate_data = { 2, 5, 29, 24 };
+    private static final int[] ExtendedKeyUsage_data = { 2, 5, 29, 37 };
+    private static final int[] InhibitAnyPolicy_data = { 2, 5, 29, 54 };
+    private static final int[] CertificateIssuer_data = { 2, 5, 29, 29 };
+    private static final int[] AuthInfoAccess_data = { 1, 3, 6, 1, 5, 5, 7, 1, 1};
+    private static final int[] SubjectInfoAccess_data = { 1, 3, 6, 1, 5, 5, 7, 1, 11};
+    private static final int[] FreshestCRL_data = { 2, 5, 29, 46 };
+    private static final int[] OCSPNoCheck_data = { 1, 3, 6, 1, 5, 5, 7,
                                                     48, 1, 5};
 
+    // Additional extensions under the PKIX arc that are not necessarily
+    // used in X.509 Certificates or CRLs.
+    private static final int[] OCSPNonce_data = { 1, 3, 6, 1, 5, 5, 7,
+                                                  48, 1, 2};
+
     /**
      * Identifies the particular public key used to sign the certificate.
      */
@@ -104,18 +109,20 @@
     public static final ObjectIdentifier CertificatePolicies_Id;
 
     /**
-     * Lists pairs of objectidentifiers of policies considered equivalent by the
-     * issuing CA to the subject CA.
+     * Lists pairs of object identifiers of policies considered equivalent by
+     * the issuing CA to the subject CA.
      */
     public static final ObjectIdentifier PolicyMappings_Id;
 
     /**
-     * Allows additional identities to be bound to the subject of the certificate.
+     * Allows additional identities to be bound to the subject of the
+     * certificate.
      */
     public static final ObjectIdentifier SubjectAlternativeName_Id;
 
     /**
-     * Allows additional identities to be associated with the certificate issuer.
+     * Allows additional identities to be associated with the certificate
+     * issuer.
      */
     public static final ObjectIdentifier IssuerAlternativeName_Id;
 
@@ -224,6 +231,12 @@
      */
     public static final ObjectIdentifier OCSPNoCheck_Id;
 
+    /**
+     * This extension is used to provide nonce data for OCSP requests
+     * or responses.
+     */
+    public static final ObjectIdentifier OCSPNonce_Id;
+
     static {
         AuthorityKey_Id = ObjectIdentifier.newInternal(AuthorityKey_data);
         SubjectKey_Id   = ObjectIdentifier.newInternal(SubjectKey_data);
@@ -266,5 +279,6 @@
             ObjectIdentifier.newInternal(SubjectInfoAccess_data);
         FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data);
         OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data);
+        OCSPNonce_Id = ObjectIdentifier.newInternal(OCSPNonce_data);
     }
 }
--- a/src/share/lib/security/java.security-aix	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/lib/security/java.security-aix	Thu May 18 14:30:18 2017 -0700
@@ -426,9 +426,7 @@
 # describes the mechanism for disabling algorithms based on algorithm name
 # and/or key length.  This includes algorithms used in certificates, as well
 # as revocation information such as CRLs and signed OCSP Responses.
-#
-# The syntax of the disabled algorithm string is described as this Java
-# BNF-style:
+# The syntax of the disabled algorithm string is described as follows:
 #   DisabledAlgorithms:
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
@@ -439,25 +437,26 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint, CertConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
-#       keySize Operator DecimalInteger
+#       keySize Operator KeyLength
 #
 #   Operator:
 #       <= | < | == | != | >= | >
 #
-#   DecimalInteger:
-#       DecimalDigits
+#   KeyLength:
+#       Integer value of the algorithm's key length in bits
 #
-#   DecimalDigits:
-#       DecimalDigit {DecimalDigit}
+#   CAConstraint:
+#       jdkCA
 #
-#   DecimalDigit: one of
-#       1 2 3 4 5 6 7 8 9 0
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
 #
-#   CertConstraint
-#       jdkCA
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
 #
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
@@ -471,27 +470,55 @@
 # that rely on DSA, such as NONEwithDSA, SHA1withDSA.  However, the assertion
 # will not disable algorithms related to "ECDSA".
 #
-# A "Constraint" provides further guidance for the algorithm being specified.
-# The "KeySizeConstraint" requires a key of a valid size range if the
-# "AlgorithmName" is of a key algorithm.  The "DecimalInteger" indicates the
-# key size specified in number of bits.  For example, "RSA keySize <= 1024"
-# indicates that any RSA key with key size less than or equal to 1024 bits
-# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
-# that any RSA key with key size less than 1024 or greater than 2048 should
-# be disabled. Note that the "KeySizeConstraint" only makes sense to key
-# algorithms.
+# A "Constraint" defines restrictions on the keys and/or certificates for
+# a specified AlgorithmName:
 #
-# "CertConstraint" specifies additional constraints for
-# certificates that contain algorithms that are restricted:
+#   KeySizeConstraint:
+#     keySize Operator KeyLength
+#       The constraint requires a key of a valid size range if the
+#       "AlgorithmName" is of a key algorithm.  The "KeyLength" indicates
+#       the key size specified in number of bits.  For example,
+#       "RSA keySize <= 1024" indicates that any RSA key with key size less
+#       than or equal to 1024 bits should be disabled, and
+#       "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key
+#       with key size less than 1024 or greater than 2048 should be disabled.
+#       This constraint is only used on algorithms that have a key size.
 #
-#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
-#     in a certificate chain that terminates at a marked trust anchor in the
-#     lib/security/cacerts keystore.  All other chains are not affected.
-#     If the jdkCA constraint is not set, then all chains using the
-#     specified algorithm are restricted.  jdkCA may only be used once in
-#     a DisabledAlgorithm expression.
-#     Example:  To apply this constraint to SHA-1 certificates, include
-#     the following  "SHA1 jdkCA"
+#   CAConstraint:
+#     jdkCA
+#       This constraint prohibits the specified algorithm only if the
+#       algorithm is used in a certificate chain that terminates at a marked
+#       trust anchor in the lib/security/cacerts keystore.  If the jdkCA
+#       constraint is not set, then all chains using the specified algorithm
+#       are restricted.  jdkCA may only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To apply this constraint to SHA-1 certificates, include
+#       the following:  "SHA1 jdkCA"
+#
+#   DenyAfterConstraint:
+#     denyAfter YYYY-MM-DD
+#       This constraint prohibits a certificate with the specified algorithm
+#       from being used after the date regardless of the certificate's
+#       validity.  JAR files that are signed and timestamped before the
+#       constraint date with certificates containing the disabled algorithm
+#       will not be restricted.  The date is processed in the UTC timezone.
+#       This constraint can only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
+#       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
+#
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
 #
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
@@ -504,6 +531,9 @@
 # before larger keysize constraints of the same algorithm.  For example:
 # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by Oracle's PKIX implementation. It
 # is not guaranteed to be examined and used by other implementations.
 #
@@ -511,9 +541,10 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
-    DSA keySize < 1024, EC keySize < 224
+jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
+    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
+#
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -528,17 +559,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -549,8 +583,11 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
 #
@@ -572,6 +609,9 @@
 # See the specification of "jdk.certpath.disabledAlgorithms" for the
 # syntax of the disabled algorithm string.
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by the JDK Reference implementation.
 # It is not guaranteed to be examined and used by other implementations.
 #
--- a/src/share/lib/security/java.security-linux	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/lib/security/java.security-linux	Thu May 18 14:30:18 2017 -0700
@@ -426,9 +426,7 @@
 # describes the mechanism for disabling algorithms based on algorithm name
 # and/or key length.  This includes algorithms used in certificates, as well
 # as revocation information such as CRLs and signed OCSP Responses.
-#
-# The syntax of the disabled algorithm string is described as this Java
-# BNF-style:
+# The syntax of the disabled algorithm string is described as follows:
 #   DisabledAlgorithms:
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
@@ -439,25 +437,26 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint, CertConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
-#       keySize Operator DecimalInteger
+#       keySize Operator KeyLength
 #
 #   Operator:
 #       <= | < | == | != | >= | >
 #
-#   DecimalInteger:
-#       DecimalDigits
+#   KeyLength:
+#       Integer value of the algorithm's key length in bits
 #
-#   DecimalDigits:
-#       DecimalDigit {DecimalDigit}
+#   CAConstraint:
+#       jdkCA
 #
-#   DecimalDigit: one of
-#       1 2 3 4 5 6 7 8 9 0
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
 #
-#   CertConstraint
-#       jdkCA
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
 #
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
@@ -471,27 +470,55 @@
 # that rely on DSA, such as NONEwithDSA, SHA1withDSA.  However, the assertion
 # will not disable algorithms related to "ECDSA".
 #
-# A "Constraint" provides further guidance for the algorithm being specified.
-# The "KeySizeConstraint" requires a key of a valid size range if the
-# "AlgorithmName" is of a key algorithm.  The "DecimalInteger" indicates the
-# key size specified in number of bits.  For example, "RSA keySize <= 1024"
-# indicates that any RSA key with key size less than or equal to 1024 bits
-# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
-# that any RSA key with key size less than 1024 or greater than 2048 should
-# be disabled. Note that the "KeySizeConstraint" only makes sense to key
-# algorithms.
+# A "Constraint" defines restrictions on the keys and/or certificates for
+# a specified AlgorithmName:
 #
-# "CertConstraint" specifies additional constraints for
-# certificates that contain algorithms that are restricted:
+#   KeySizeConstraint:
+#     keySize Operator KeyLength
+#       The constraint requires a key of a valid size range if the
+#       "AlgorithmName" is of a key algorithm.  The "KeyLength" indicates
+#       the key size specified in number of bits.  For example,
+#       "RSA keySize <= 1024" indicates that any RSA key with key size less
+#       than or equal to 1024 bits should be disabled, and
+#       "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key
+#       with key size less than 1024 or greater than 2048 should be disabled.
+#       This constraint is only used on algorithms that have a key size.
 #
-#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
-#     in a certificate chain that terminates at a marked trust anchor in the
-#     lib/security/cacerts keystore.  All other chains are not affected.
-#     If the jdkCA constraint is not set, then all chains using the
-#     specified algorithm are restricted.  jdkCA may only be used once in
-#     a DisabledAlgorithm expression.
-#     Example:  To apply this constraint to SHA-1 certificates, include
-#     the following:  "SHA1 jdkCA"
+#   CAConstraint:
+#     jdkCA
+#       This constraint prohibits the specified algorithm only if the
+#       algorithm is used in a certificate chain that terminates at a marked
+#       trust anchor in the lib/security/cacerts keystore.  If the jdkCA
+#       constraint is not set, then all chains using the specified algorithm
+#       are restricted.  jdkCA may only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To apply this constraint to SHA-1 certificates, include
+#       the following:  "SHA1 jdkCA"
+#
+#   DenyAfterConstraint:
+#     denyAfter YYYY-MM-DD
+#       This constraint prohibits a certificate with the specified algorithm
+#       from being used after the date regardless of the certificate's
+#       validity.  JAR files that are signed and timestamped before the
+#       constraint date with certificates containing the disabled algorithm
+#       will not be restricted.  The date is processed in the UTC timezone.
+#       This constraint can only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
+#       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
+#
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
 #
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
@@ -504,6 +531,9 @@
 # before larger keysize constraints of the same algorithm.  For example:
 # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by Oracle's PKIX implementation. It
 # is not guaranteed to be examined and used by other implementations.
 #
@@ -511,9 +541,10 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
-    DSA keySize < 1024, EC keySize < 224
+jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
+    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
+#
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -528,17 +559,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -549,8 +583,11 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
 #
@@ -572,6 +609,9 @@
 # See the specification of "jdk.certpath.disabledAlgorithms" for the
 # syntax of the disabled algorithm string.
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by the JDK Reference implementation.
 # It is not guaranteed to be examined and used by other implementations.
 #
--- a/src/share/lib/security/java.security-macosx	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/lib/security/java.security-macosx	Thu May 18 14:30:18 2017 -0700
@@ -429,9 +429,7 @@
 # describes the mechanism for disabling algorithms based on algorithm name
 # and/or key length.  This includes algorithms used in certificates, as well
 # as revocation information such as CRLs and signed OCSP Responses.
-#
-# The syntax of the disabled algorithm string is described as this Java
-# BNF-style:
+# The syntax of the disabled algorithm string is described as follows:
 #   DisabledAlgorithms:
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
@@ -442,25 +440,26 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint, CertConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
-#       keySize Operator DecimalInteger
+#       keySize Operator KeyLength
 #
 #   Operator:
 #       <= | < | == | != | >= | >
 #
-#   DecimalInteger:
-#       DecimalDigits
+#   KeyLength:
+#       Integer value of the algorithm's key length in bits
 #
-#   DecimalDigits:
-#       DecimalDigit {DecimalDigit}
+#   CAConstraint:
+#       jdkCA
 #
-#   DecimalDigit: one of
-#       1 2 3 4 5 6 7 8 9 0
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
 #
-#   CertConstraint
-#       jdkCA
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
 #
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
@@ -474,27 +473,55 @@
 # that rely on DSA, such as NONEwithDSA, SHA1withDSA.  However, the assertion
 # will not disable algorithms related to "ECDSA".
 #
-# A "Constraint" provides further guidance for the algorithm being specified.
-# The "KeySizeConstraint" requires a key of a valid size range if the
-# "AlgorithmName" is of a key algorithm.  The "DecimalInteger" indicates the
-# key size specified in number of bits.  For example, "RSA keySize <= 1024"
-# indicates that any RSA key with key size less than or equal to 1024 bits
-# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
-# that any RSA key with key size less than 1024 or greater than 2048 should
-# be disabled. Note that the "KeySizeConstraint" only makes sense to key
-# algorithms.
+# A "Constraint" defines restrictions on the keys and/or certificates for
+# a specified AlgorithmName:
 #
-# "CertConstraint" specifies additional constraints for
-# certificates that contain algorithms that are restricted:
+#   KeySizeConstraint:
+#     keySize Operator KeyLength
+#       The constraint requires a key of a valid size range if the
+#       "AlgorithmName" is of a key algorithm.  The "KeyLength" indicates
+#       the key size specified in number of bits.  For example,
+#       "RSA keySize <= 1024" indicates that any RSA key with key size less
+#       than or equal to 1024 bits should be disabled, and
+#       "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key
+#       with key size less than 1024 or greater than 2048 should be disabled.
+#       This constraint is only used on algorithms that have a key size.
 #
-#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
-#     in a certificate chain that terminates at a marked trust anchor in the
-#     lib/security/cacerts keystore.  All other chains are not affected.
-#     If the jdkCA constraint is not set, then all chains using the
-#     specified algorithm are restricted. jdkCA may only be used once in
-#     a DisabledAlgorithm expression.
-#     Example:  To apply this constraint to SHA-1 certificates, include
-#     the following:  "SHA1 jdkCA"
+#   CAConstraint:
+#     jdkCA
+#       This constraint prohibits the specified algorithm only if the
+#       algorithm is used in a certificate chain that terminates at a marked
+#       trust anchor in the lib/security/cacerts keystore.  If the jdkCA
+#       constraint is not set, then all chains using the specified algorithm
+#       are restricted.  jdkCA may only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To apply this constraint to SHA-1 certificates, include
+#       the following:  "SHA1 jdkCA"
+#
+#   DenyAfterConstraint:
+#     denyAfter YYYY-MM-DD
+#       This constraint prohibits a certificate with the specified algorithm
+#       from being used after the date regardless of the certificate's
+#       validity.  JAR files that are signed and timestamped before the
+#       constraint date with certificates containing the disabled algorithm
+#       will not be restricted.  The date is processed in the UTC timezone.
+#       This constraint can only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
+#       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
+#
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
 #
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
@@ -507,6 +534,9 @@
 # before larger keysize constraints of the same algorithm.  For example:
 # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by Oracle's PKIX implementation. It
 # is not guaranteed to be examined and used by other implementations.
 #
@@ -514,9 +544,10 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
-    DSA keySize < 1024, EC keySize < 224
+jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
+    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
+#
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -531,17 +562,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -552,8 +586,11 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
 #
@@ -575,6 +612,9 @@
 # See the specification of "jdk.certpath.disabledAlgorithms" for the
 # syntax of the disabled algorithm string.
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by the JDK Reference implementation.
 # It is not guaranteed to be examined and used by other implementations.
 #
--- a/src/share/lib/security/java.security-solaris	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/lib/security/java.security-solaris	Thu May 18 14:30:18 2017 -0700
@@ -428,9 +428,7 @@
 # describes the mechanism for disabling algorithms based on algorithm name
 # and/or key length.  This includes algorithms used in certificates, as well
 # as revocation information such as CRLs and signed OCSP Responses.
-#
-# The syntax of the disabled algorithm string is described as this Java
-# BNF-style:
+# The syntax of the disabled algorithm string is described as follows:
 #   DisabledAlgorithms:
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
@@ -441,25 +439,26 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint, CertConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
-#       keySize Operator DecimalInteger
+#       keySize Operator KeyLength
 #
 #   Operator:
 #       <= | < | == | != | >= | >
 #
-#   DecimalInteger:
-#       DecimalDigits
+#   KeyLength:
+#       Integer value of the algorithm's key length in bits
 #
-#   DecimalDigits:
-#       DecimalDigit {DecimalDigit}
+#   CAConstraint:
+#       jdkCA
 #
-#   DecimalDigit: one of
-#       1 2 3 4 5 6 7 8 9 0
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
 #
-#   CertConstraint
-#       jdkCA
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
 #
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
@@ -473,27 +472,55 @@
 # that rely on DSA, such as NONEwithDSA, SHA1withDSA.  However, the assertion
 # will not disable algorithms related to "ECDSA".
 #
-# A "Constraint" provides further guidance for the algorithm being specified.
-# The "KeySizeConstraint" requires a key of a valid size range if the
-# "AlgorithmName" is of a key algorithm.  The "DecimalInteger" indicates the
-# key size specified in number of bits.  For example, "RSA keySize <= 1024"
-# indicates that any RSA key with key size less than or equal to 1024 bits
-# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
-# that any RSA key with key size less than 1024 or greater than 2048 should
-# be disabled. Note that the "KeySizeConstraint" only makes sense to key
-# algorithms.
+# A "Constraint" defines restrictions on the keys and/or certificates for
+# a specified AlgorithmName:
 #
-# "CertConstraint" specifies additional constraints for
-# certificates that contain algorithms that are restricted:
+#   KeySizeConstraint:
+#     keySize Operator KeyLength
+#       The constraint requires a key of a valid size range if the
+#       "AlgorithmName" is of a key algorithm.  The "KeyLength" indicates
+#       the key size specified in number of bits.  For example,
+#       "RSA keySize <= 1024" indicates that any RSA key with key size less
+#       than or equal to 1024 bits should be disabled, and
+#       "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key
+#       with key size less than 1024 or greater than 2048 should be disabled.
+#       This constraint is only used on algorithms that have a key size.
 #
-#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
-#     in a certificate chain that terminates at a marked trust anchor in the
-#     lib/security/cacerts keystore.  All other chains are not affected.
-#     If the jdkCA constraint is not set, then all chains using the
-#     specified algorithm are restricted. jdkCA may only be used once in
-#     a DisabledAlgorithm expression.
-#     Example:  To apply this constraint to SHA-1 certificates, include
-#     the following:  "SHA1 jdkCA"
+#   CAConstraint:
+#     jdkCA
+#       This constraint prohibits the specified algorithm only if the
+#       algorithm is used in a certificate chain that terminates at a marked
+#       trust anchor in the lib/security/cacerts keystore.  If the jdkCA
+#       constraint is not set, then all chains using the specified algorithm
+#       are restricted.  jdkCA may only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To apply this constraint to SHA-1 certificates, include
+#       the following:  "SHA1 jdkCA"
+#
+#   DenyAfterConstraint:
+#     denyAfter YYYY-MM-DD
+#       This constraint prohibits a certificate with the specified algorithm
+#       from being used after the date regardless of the certificate's
+#       validity.  JAR files that are signed and timestamped before the
+#       constraint date with certificates containing the disabled algorithm
+#       will not be restricted.  The date is processed in the UTC timezone.
+#       This constraint can only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
+#       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
+#
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
 #
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
@@ -506,6 +533,9 @@
 # before larger keysize constraints of the same algorithm.  For example:
 # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by Oracle's PKIX implementation. It
 # is not guaranteed to be examined and used by other implementations.
 #
@@ -513,9 +543,10 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
-    DSA keySize < 1024, EC keySize < 224
+jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
+    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
+#
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -530,17 +561,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -551,8 +585,11 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
 #
@@ -574,6 +611,9 @@
 # See the specification of "jdk.certpath.disabledAlgorithms" for the
 # syntax of the disabled algorithm string.
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by the JDK Reference implementation.
 # It is not guaranteed to be examined and used by other implementations.
 #
--- a/src/share/lib/security/java.security-windows	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/lib/security/java.security-windows	Thu May 18 14:30:18 2017 -0700
@@ -429,9 +429,7 @@
 # describes the mechanism for disabling algorithms based on algorithm name
 # and/or key length.  This includes algorithms used in certificates, as well
 # as revocation information such as CRLs and signed OCSP Responses.
-#
-# The syntax of the disabled algorithm string is described as this Java
-# BNF-style:
+# The syntax of the disabled algorithm string is described as follows:
 #   DisabledAlgorithms:
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
@@ -442,25 +440,26 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint, CertConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
-#       keySize Operator DecimalInteger
+#       keySize Operator KeyLength
 #
 #   Operator:
 #       <= | < | == | != | >= | >
 #
-#   DecimalInteger:
-#       DecimalDigits
+#   KeyLength:
+#       Integer value of the algorithm's key length in bits
 #
-#   DecimalDigits:
-#       DecimalDigit {DecimalDigit}
+#   CAConstraint:
+#       jdkCA
 #
-#   DecimalDigit: one of
-#       1 2 3 4 5 6 7 8 9 0
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
 #
-#   CertConstraint
-#       jdkCA
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
 #
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
@@ -474,27 +473,55 @@
 # that rely on DSA, such as NONEwithDSA, SHA1withDSA.  However, the assertion
 # will not disable algorithms related to "ECDSA".
 #
-# A "Constraint" provides further guidance for the algorithm being specified.
-# The "KeySizeConstraint" requires a key of a valid size range if the
-# "AlgorithmName" is of a key algorithm.  The "DecimalInteger" indicates the
-# key size specified in number of bits.  For example, "RSA keySize <= 1024"
-# indicates that any RSA key with key size less than or equal to 1024 bits
-# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
-# that any RSA key with key size less than 1024 or greater than 2048 should
-# be disabled. Note that the "KeySizeConstraint" only makes sense to key
-# algorithms.
+# A "Constraint" defines restrictions on the keys and/or certificates for
+# a specified AlgorithmName:
 #
-# "CertConstraint" specifies additional constraints for
-# certificates that contain algorithms that are restricted:
+#   KeySizeConstraint:
+#     keySize Operator KeyLength
+#       The constraint requires a key of a valid size range if the
+#       "AlgorithmName" is of a key algorithm.  The "KeyLength" indicates
+#       the key size specified in number of bits.  For example,
+#       "RSA keySize <= 1024" indicates that any RSA key with key size less
+#       than or equal to 1024 bits should be disabled, and
+#       "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key
+#       with key size less than 1024 or greater than 2048 should be disabled.
+#       This constraint is only used on algorithms that have a key size.
 #
-#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
-#     in a certificate chain that terminates at a marked trust anchor in the
-#     lib/security/cacerts keystore.  All other chains are not affected.
-#     If the jdkCA constraint is not set, then all chains using the
-#     specified algorithm are restricted.  jdkCA may only be used once in
-#     a DisabledAlgorithm expression.
-#     Example:  To apply this constraint to SHA-1 certificates, include
-#     the following:  "SHA1 jdkCA"
+#   CAConstraint:
+#     jdkCA
+#       This constraint prohibits the specified algorithm only if the
+#       algorithm is used in a certificate chain that terminates at a marked
+#       trust anchor in the lib/security/cacerts keystore.  If the jdkCA
+#       constraint is not set, then all chains using the specified algorithm
+#       are restricted.  jdkCA may only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To apply this constraint to SHA-1 certificates, include
+#       the following:  "SHA1 jdkCA"
+#
+#   DenyAfterConstraint:
+#     denyAfter YYYY-MM-DD
+#       This constraint prohibits a certificate with the specified algorithm
+#       from being used after the date regardless of the certificate's
+#       validity.  JAR files that are signed and timestamped before the
+#       constraint date with certificates containing the disabled algorithm
+#       will not be restricted.  The date is processed in the UTC timezone.
+#       This constraint can only be used once in a DisabledAlgorithm
+#       expression.
+#       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
+#       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
+#
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
 #
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
@@ -507,6 +534,9 @@
 # before larger keysize constraints of the same algorithm.  For example:
 # "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by Oracle's PKIX implementation. It
 # is not guaranteed to be examined and used by other implementations.
 #
@@ -514,9 +544,10 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
-    DSA keySize < 1024, EC keySize < 224
+jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
+    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
+#
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -531,17 +562,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -552,8 +586,11 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
 #
@@ -575,6 +612,9 @@
 # See the specification of "jdk.certpath.disabledAlgorithms" for the
 # syntax of the disabled algorithm string.
 #
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
 # Note: This property is currently used by the JDK Reference implementation.
 # It is not guaranteed to be examined and used by other implementations.
 #
--- a/src/share/native/sun/awt/libpng/CHANGES	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/CHANGES	Thu May 18 14:30:18 2017 -0700
@@ -1,28 +1,3 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
 #if 0
 CHANGES - changes for libpng
 
@@ -618,7 +593,7 @@
     with trailing compressed parts easier in the future, and added new functions
     png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
     png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
-  NOTE: Applications that write text chunks MUST define png_text->lang
+    NOTE: Applications that write text chunks MUST define png_text->lang
     before calling png_set_text(). It must be set to NULL if you want to
     write tEXt or zTXt chunks.  If you want your application to be able to
     run with older versions of libpng, use
@@ -5088,7 +5063,8 @@
 Version 1.6.15beta05 [November 5, 2014]
   Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in
     example.c, pngtest.c, and applications in the contrib directory.
-  Avoid out-of-bounds memory access in png_user_version_check().
+  Fixed an out-of-range read in png_user_version_check() (Bug report from
+    Qixue Xiao, CVE-2015-8540).
   Simplified and future-proofed png_user_version_check().
   Fixed GCC unsigned int->float warnings. Various versions of GCC
     seem to generate warnings when an unsigned value is implicitly
@@ -5446,7 +5422,7 @@
 Version 1.6.20beta02 [November 23, 2015]
   Fixed incorrect implementation of png_set_PLTE() that uses png_ptr
     not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126
-    vulnerability.
+    vulnerability.  Fixes CVE-2015-8472.
 
 Version 1.6.20beta03 [November 24, 2015]
   Backported tests from libpng-1.7.0beta69.
@@ -5471,6 +5447,353 @@
 Version 1.6.20 [December 3, 2015]
   No changes.
 
+Version 1.6.21beta01 [December 11, 2015]
+  Fixed syntax "$(command)" in tests/pngstest that some shells other than
+    bash could not parse (Bug report by Nelson Beebe). Use `command` instead.
+
+Version 1.6.21beta02 [December 14, 2015]
+  Moved png_check_keyword() from pngwutil.c to pngset.c
+  Removed LE/BE dependencies in pngvalid, to 'fix' the current problem
+    in the BigEndian tests by not testing it, making the BE code the same 
+    as the LE version.
+  Fixes to pngvalid for various reduced build configurations (eliminate unused
+    statics) and a fix for the case in rgb_to_gray when the digitize option
+    reduces graylo to 0, producing a large error.
+
+Version 1.6.21beta03 [December 18, 2015]
+  Widened the 'limit' check on the internally calculated error limits in
+    the 'DIGITIZE' case (the code used prior to 1.7 for rgb_to_gray error
+    checks) and changed the check to only operate in non-release builds
+    (base build type not RC or RELEASE.)
+  Fixed undefined behavior in pngvalid.c, undefined because
+    (png_byte) << shift is undefined if it changes the signed bit
+    (because png_byte is promoted to int). The libpng exported functions
+    png_get_uint_32 and png_get_uint_16 handle this. (Bug reported by
+    David Drysdale as a result of reports from UBSAN in clang 3.8).
+  This changes pngvalid to use BE random numbers; this used to produce
+    errors but these should not be fixed as a result of the previous changes.
+
+Version 1.6.21rc01 [January 4, 2016]
+  In projects/vstudio, combined readme.txt and WARNING into README.txt
+
+Version 1.6.21rc02 [January 7, 2016]
+  Relocated assert() in contrib/tools/pngfix.c, bug found by American
+    Fuzzy Lop, reported by Brian Carpenter.
+  Marked 'limit' UNUSED in transform_range_check().  This only affects
+    release builds.
+
+Version 1.6.21 [January 15, 2016]
+  Worked around a false-positive Coverity issue in pngvalid.c.
+
+Version 1.6.22beta01 [January 23, 2016]
+  Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate
+    "tmpfile()" implementation in contrib/libtests/pngstest.c
+  Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io()
+    if there is no stdio.h support.
+  Added a png_image_write_to_memory() API and a number of assist macros
+    to allow an application that uses the simplified API write to bypass
+    stdio and write directly to memory.
+  Added some warnings (png.h) and some check code to detect *possible*
+    overflow in the ROW_STRIDE and simplified image SIZE macros.  This
+    disallows image width/height/format that *might* overflow.  This is
+    a quiet API change that limits in-memory image size (uncompressed) to
+    less than 4GByte and image row size (stride) to less than 2GByte.
+  Revised workaround for false-positive Coverity issue in pngvalid.c.
+
+Version 1.6.22beta02 [February 8, 2016]
+  Only use exit(77) in configure builds.
+  Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported
+    the palette size because it failed to take into account that the memory
+    palette has to be expanded to full RGB when it is written to PNG.
+  Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in
+    and test.cmake.in (Roger Leigh).
+  Relaxed limit checks on gamma values in pngrtran.c. As suggested in
+    the comments gamma values outside the range currently permitted
+    by png_set_alpha_mode are useful for HDR data encoding.  These values
+    are already permitted by png_set_gamma so it is reasonable caution to
+    extend the png_set_alpha_mode range as HDR imaging systems are starting
+    to emerge.
+
+Version 1.6.22beta03 [March 9, 2016]
+  Added a common-law trademark notice and export control information
+    to the LICENSE file, png.h, and the man page.
+  Restored "& 0xff" in png_save_uint_16() and png_save_uint_32() that
+    were accidentally removed from libpng-1.6.17. 
+  Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h
+    (Robert C. Seacord).
+  Removed dubious "#if INT_MAX" test from png.h that was added to
+    libpng-1.6.19beta02 (John Bowler).
+  Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok).
+  Updated LICENSE to say files in the contrib directory are not
+    necessarily under the libpng license, and that some makefiles have
+    other copyright owners.
+  Added INTEL-SSE2 support (Mike Klein and Matt Sarett, Google, Inc.).
+  Made contrib/libtests/timepng more robust.  The code no longer gives
+    up/fails on invalid PNG data, it just skips it (with error messages).
+    The code no longer fails on PNG files with data beyond IEND.  Options
+    exist to use png_read_png (reading the whole image, not by row) and, in
+    that case, to apply any of the supported transforms.  This makes for
+    more realistic testing; the decoded data actually gets used in a
+    meaningful fashion (John Bowler).
+  Fixed some misleading indentation (Krishnaraj Bhat).
+
+Version 1.6.22beta04 [April 5, 2016]
+  Force GCC compilation to C89 if needed (Dagobert Michelsen).
+  SSE filter speed improvements for bpp=3:
+    memcpy-free implementations of load3() / store3().
+    call load3() only when needed at the end of a scanline.
+
+Version 1.6.22beta05 [April 27, 2016]
+  Added PNG_FAST_FILTERS macro (defined as
+    PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_UP).
+  Various fixes for contrib/libtests/timepng.c
+  Moved INTEL-SSE code from pngpriv.h into contrib/intel/intel_sse.patch.
+  Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED
+    (Bug report by Y.Ohashik).
+
+Version 1.6.22beta06 [May 5, 2016]
+  Rebased contrib/intel_sse.patch.
+  Quieted two Coverity issues in contrib/libtests/timepng.c.
+  Fixed issues with scripts/genout.cmake.in (David Capello, Nixon Kwok):
+    Added support to use multiple directories in ZLIBINCDIR variable,
+    Fixed CMAKE_C_FLAGS with multiple values when genout is compiled on MSVC,
+    Fixed pnglibconf.c compilation on OS X including the sysroot path.
+
+Version 1.6.22rc01 [May 14, 2016]
+  No changes.
+
+Version 1.6.22rc02 [May 16, 2016]
+  Removed contrib/timepng from default build; it does not build on platforms
+    that don't supply clock_gettime().
+
+Version 1.6.22rc03 [May 17, 2016]
+  Restored contrib/timepng to default build but check for the presence
+    of clock_gettime() in configure.ac and Makefile.am.
+
+Version 1.6.22 [May 26, 2016]
+  No changes.
+
+Version 1.6.23beta01 [May 29, 2016]
+  Stop a potential memory leak in png_set_tRNS() (Bug report by Ted Ying).
+  Fixed the progressive reader to handle empty first IDAT chunk properly
+    (patch by Timothy Nikkel).  This bug was introduced in libpng-1.6.0 and
+    only affected the libpng16 branch.
+  Added tests in pngvalid.c to check zero-length IDAT chunks in various
+    positions.  Fixed the sequential reader to handle these more robustly
+    (John Bowler).
+
+Version 1.6.23rc01 [June 2, 2016]
+  Corrected progressive read input buffer in pngvalid.c. The previous version
+    the code invariably passed just one byte at a time to libpng.  The intent
+    was to pass a random number of bytes in the range 0..511.
+  Moved sse2 prototype from pngpriv.h to contrib/intel/intel_sse.patch.
+  Added missing ")" in pngerror.c (Matt Sarrett).
+
+Version 1.6.23rc02 [June 4, 2016]
+  Fixed undefined behavior in png_push_save_buffer(). Do not call
+    memcpy() with a null source, even if count is zero (Leon Scroggins III).
+
+Version 1.6.23 [June 9, 2016]
+  Fixed bad link to RFC2083 in png.5 (Nikola Forro).
+
+Version 1.6.24beta01 [June 11, 2016]
+  Avoid potential overflow of the PNG_IMAGE_SIZE macro.  This macro
+    is not used within libpng, but is used in some of the examples.
+
+Version 1.6.24beta02 [June 23, 2016]
+  Correct filter heuristic overflow handling. This was broken when the
+    write filter code was moved out-of-line; if there is a single filter and
+    the heuristic sum overflows the calculation of the filtered line is not
+    completed.  In versions prior to 1.6 the code was duplicated in-line
+    and the check not performed, so the filter operation completed; however,
+    in the multi-filter case where the sum is performed the 'none' filter would
+    be selected if all the sums overflowed, even if it wasn't in the filter
+    list.  The fix to the first problem is simply to provide PNG_SIZE_MAX as
+    the current lmins sum value; this means the sum can never exceed it and
+    overflows silently.  A reasonable compiler that does choose to inline
+    the code will simply eliminate the sum check.
+  The fix to the second problem is to use high precision arithmetic (this is
+    implemented in 1.7), however a simple safe fix here is to chose the lowest
+    numbered filter in the list from png_set_filter (this only works if the
+    first problem is also fixed) (John Bowler).
+  Use a more efficient absolute value calculation on SSE2 (Matthieu Darbois).
+  Fixed the case where PNG_IMAGE_BUFFER_SIZE can overflow in the application
+    as a result of the application using an increased 'row_stride'; previously
+    png_image_finish_read only checked for overflow on the base calculation of
+    components.  (I.e. it checked for overflow of a 32-bit number on the total
+    number of pixel components in the output format, not the possibly padded row
+    length and not the number of bytes, which for linear formats is twice the
+    number of components.)
+  MSVC does not like '-(unsigned)', so replaced it with 0U-(unsigned)
+  MSVC does not like (uInt) = -(unsigned) (i.e. as an initializer), unless
+    the conversion is explicitly invoked by a cast.
+  Put the SKIP definition in the correct place. It needs to come after the
+    png.h include (see all the other .c files in contrib/libtests) because it
+    depends on PNG_LIBPNG_VER.
+  Removed the three compile warning options from the individual project
+    files into the zlib.props globals.  It increases the warning level from 4
+    to All and adds a list of the warnings that need to be turned off.  This is
+    semi-documentary; the intent is to tell libpng users which warnings have
+    been examined and judged non-fixable at present.  The warning about
+    structure padding is fixable, but it would be a signficant change (moving
+    structure members around).
+
+Version 1.6.24beta03 [July 4, 2016]
+  Optimized absolute value calculation in filter selection, similar to
+    code in the PAETH decoder in pngrutil.c. Build with PNG_USE_ABS to
+    use this.
+  Added pngcp to the build together with a pngcp.dfa configuration test.
+  Added high resolution timing to pngcp.
+  Added "Common linking failures" section to INSTALL.
+  Relocated misplaced #endif in png.c sRGB profile checking.
+  Fixed two Coverity issues in pngcp.c.
+
+Version 1.6.24beta04 [July 8, 2016]
+  Avoid filter-selection heuristic sum calculations in cases where only one
+    filter is a candidate for selection. This trades off code size (added
+    private png_setup_*_row_only() functions) for speed.
+
+Version 1.6.24beta05 [July 13, 2016]
+  Fixed some indentation to comply with our coding style.
+  Added contrib/tools/reindent.
+
+Version 1.6.24beta06 [July 18, 2016]
+  Fixed more indentation to comply with our coding style.
+  Eliminated unnecessary tests of boolean png_isaligned() vs 0.
+
+Version 1.6.24rc01 [July 25, 2016]
+  No changes.
+
+Version 1.6.24rc02 [August 1, 2016]
+  Conditionally compile SSE2 headers in contrib/intel/intel_sse.patch
+  Conditionally compile png_decompress_chunk().
+
+Version 1.6.24rc03 [August 2, 2016]
+  Conditionally compile ARM_NEON headers in pngpriv.h
+  Updated contrib/intel/intel_sse.patch
+
+Version 1.6.24[August 4, 2016]
+  No changes.
+
+Version 1.6.25beta01 [August 12, 2016]
+  Reject oversized iCCP profile immediately.
+  Cleaned up PNG_DEBUG compile of pngtest.c.
+  Conditionally compile png_inflate().
+
+Version 1.6.25beta02 [August 18, 2016]
+  Don't install pngcp; it conflicts with pngcp in the pngtools package.
+  Minor editing of INSTALL, (whitespace, added copyright line)
+
+Version 1.6.25rc01 [August 24, 2016]
+  No changes.
+
+Version 1.6.25rc02 [August 29, 2016]
+  Added MIPS support (Mandar Sahastrabuddhe <Mandar.Sahastrabuddhe@imgtec.com>).
+  Only the UP filter is currently implemented.
+
+Version 1.6.25rc03 [August 29, 2016]
+  Rebased contrib/intel/intel_sse.patch after the MIPS implementation.
+
+Version 1.6.25rc04 [August 30, 2016]
+  Added MIPS support for SUB, AVG, and PAETH filters (Mandar Sahastrabuddhe).
+
+Version 1.6.25rc05 [August 30, 2016]
+  Rebased contrib/intel/intel_sse.patch after the MIPS implementation update..
+
+Version 1.6.25 [September 1, 2016]
+  No changes.
+
+Version 1.6.26beta01 [September 26, 2016]
+  Fixed handling zero length IDAT in pngfix (bug report by Agostino Sarubbo,
+    bugfix by John Bowler).
+  Do not issue a png_error() on read in png_set_pCAL() because png_handle_pCAL
+    has allocated memory that libpng needs to free.
+  Conditionally compile png_set_benign_errors() in pngread.c and pngtest.c
+  Issue a png_benign_error instead of a png_error on ADLER32 mismatch
+    while decoding compressed data chunks.
+  Changed PNG_ZLIB_VERNUM to ZLIB_VERNUM in pngpriv.h, pngstruct.h, and
+    pngrutil.c.
+  If CRC handling of critical chunks has been set to PNG_CRC_QUIET_USE,
+    ignore the ADLER32 checksum in the IDAT chunk as well as the chunk CRCs.
+  Issue png_benign_error() on ADLER32 checksum mismatch instead of png_error().
+  Add tests/badcrc.png and tests/badadler.png to tests/pngtest.
+  Merged pngtest.c with libpng-1.7.0beta84/pngtest.c
+
+Version 1.6.26beta02 [October 1, 2016]
+  Updated the documentation about CRC and ADLER32 handling.
+  Quieted 117 warnings from clang-3.8 in pngtrans.c, pngread.c,
+     pngwrite.c, pngunknown.c, and pngvalid.c.
+  Quieted 58 (out of 144) -Wconversion compiler warnings by changing
+    flag definitions in pngpriv.h from 0xnnnn to 0xnnnnU and trivial changes
+    in png.c, pngread.c, and pngwutil.c.
+
+Version 1.6.26beta03 [October 2, 2016]
+  Removed contrib/libtests/*.orig and *.rej that slipped into the tarballs.
+  Quieted the 86 remaining -Wconversion compiler warnings by
+    revising the png_isaligned() macro and trivial changes in png.c,
+    pngerror.c, pngget.c, pngmem.c, pngset.c, pngrtran.c, pngrutil.c,
+    pngwtran.c, pngwrite.c, and pngwutil.c.
+
+Version 1.6.26beta04 [October 3, 2016]
+  Quieted (bogus?) clang warnings about "absolute value has no effect"
+    when PNG_USE_ABS is defined.
+  Fixed offsets in contrib/intel/intel_sse.patch
+
+Version 1.6.26beta05 [October 6, 2016]
+  Changed integer constant 4294967294 to unsigned 4294967294U in pngconf.h
+    to avoid a signed/unsigned compare in the preprocessor.
+
+Version 1.6.26beta06 [October 7, 2016]
+  Use zlib-1.2.8.1 inflateValidate() instead of inflateReset2() to
+    optionally avoid ADLER32 evaluation.
+
+Version 1.6.26rc01 [October 12, 2016]
+  No changes.
+
+Version 1.6.26 [October 20, 2016]
+  Cosmetic change, "ptr != 0" to "ptr != NULL" in png.c and pngrutil.c
+  Despammed email addresses (replaced "@" with " at ").
+
+Version 1.6.27beta01 [November 2, 2016]
+  Restrict the new ADLER32-skipping to IDAT chunks.  It broke iCCP chunk
+    handling: an erroneous iCCP chunk would throw a png_error and reject the
+    entire PNG image instead of rejecting just the iCCP chunk with a warning,
+    if built with zlib-1.2.8.1.
+
+Version 1.6.27rc01 [December 27, 2016]
+  Control ADLER32 checking with new PNG_IGNORE_ADLER32 option.
+  Removed the use of a macro containing the pre-processor 'defined'
+    operator.  It is unclear whether this is valid; a macro that
+    "generates" 'defined' is not permitted, but the use of the word
+    "generates" within the C90 standard seems to imply more than simple
+    substitution of an expression itself containing a well-formed defined
+    operation.
+  Added ARM support to CMakeLists.txt (Andreas Franek).
+
+Version 1.6.27 [December 29, 2016]
+  Fixed a potential null pointer dereference in png_set_text_2() (bug report
+    and patch by Patrick Keshishian, CVE-2016-10087).
+
+Version 1.6.28rc01 [January 3, 2017]
+  Fixed arm/aarch64 detection in CMakeLists.txt (Gianfranco Costamagna).
+  Added option to Cmake build allowing a custom location of zlib to be
+    specified in a scenario where libpng is being built as a subproject
+    alongside zlib by another project (Sam Serrels).
+  Changed png_ptr->options from a png_byte to png_uint_32, to accomodate
+    up to 16 options.
+
+Version 1.6.28rc02 [January 4, 2017]
+  Added "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
+  Moved SSE2 optimization code into the main libpng source directory.
+    Configure libpng with "configure --enable-intel-sse" or compile
+    libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
+
+Version 1.6.28rc03 [January 4, 2017]
+  Backed out the SSE optimization and last CMakeLists.txt to allow time for QA.
+
+Version 1.6.28 [January 5, 2017]
+  No changes.
+
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
--- a/src/share/native/sun/awt/libpng/LICENSE	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/LICENSE	Thu May 18 14:30:18 2017 -0700
@@ -10,8 +10,8 @@
 
 This code is released under the libpng license.
 
-libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are
-Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are
+libpng versions 1.0.7, July 1, 2000 through 1.6.28, January 5, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
 derived from libpng-1.0.6, and are distributed according to the same
 disclaimer and license as libpng-1.0.6 with the following individuals
 added to the list of Contributing Authors:
@@ -22,6 +22,7 @@
    Cosmin Truta
    Gilles Vollant
    James Yu
+   Mandar Sahastrabuddhe
 
 and with the following additions to the disclaimer:
 
@@ -32,6 +33,10 @@
    risk of satisfactory quality, performance, accuracy, and effort is with
    the user.
 
+Some files in the "contrib" directory and some configure-generated
+files that are distributed with libpng have other copyright owners and
+are released under other open source licenses.
+
 libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
 Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
 libpng-0.96, and are distributed according to the same disclaimer and
@@ -55,6 +60,9 @@
    Greg Roelofs
    Tom Tanner
 
+Some files in the "scripts" directory have other copyright owners
+but are released under this license.
+
 libpng versions 0.5, May 1995, through 0.88, January 1996, are
 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
 
@@ -95,18 +103,29 @@
 
 END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
 
-A "png_get_copyright" function is available, for convenient use in "about"
-boxes and the like:
+TRADEMARK:
 
-   printf("%s", png_get_copyright(NULL));
+The name "libpng" has not been registered by the Copyright owner
+as a trademark in any jurisdiction.  However, because libpng has
+been distributed and maintained world-wide, continually since 1995,
+the Copyright owner claims "common-law trademark protection" in any
+jurisdiction where common-law trademark is recognized.
 
-Also, the PNG logo (in PNG format, of course) is supplied in the
-files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+OSI CERTIFICATION:
 
 Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
 a certification mark of the Open Source Initiative. OSI has not addressed
 the additional disclaimers inserted at version 1.0.7.
 
+EXPORT CONTROL:
+
+The Copyright owner believes that the Export Control Classification
+Number (ECCN) for libpng is EAR99, which means not subject to export
+controls or International Traffic in Arms Regulations (ITAR) because
+it is open source, publicly available software, that does not contain
+any encryption software.  See the EAR, paragraphs 734.3(b)(3) and
+734.7(b).
+
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-December 3, 2015
+January 5, 2017
--- a/src/share/native/sun/awt/libpng/README	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/README	Thu May 18 14:30:18 2017 -0700
@@ -1,4 +1,4 @@
-README for libpng version 1.6.20 - December 3, 2015 (shared library 16.0)
+README for libpng version 1.6.28 - January 5, 2017 (shared library 16.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
@@ -180,15 +180,18 @@
       pngwutil.c    =>  Write utility functions
       arm           =>  Contains optimized code for the ARM platform
       contrib       =>  Contributions
+       arm-neon         =>  Optimized code for ARM-NEON platform
        examples         =>  Example programs
        gregbook         =>  source code for PNG reading and writing, from
                             Greg Roelofs' "PNG: The Definitive Guide",
                             O'Reilly, 1999
+       intel            =>  Optimized code for INTEL-SSE2 platform
        libtests         =>  Test programs
        pngminim         =>  Minimal decoder, encoder, and progressive decoder
                             programs demonstrating use of pngusr.dfa
        pngminus         =>  Simple pnm2png and png2pnm programs
        pngsuite         =>  Test images
+       testpngs
        tools            =>  Various tools
        visupng          =>  Contains a MSVC workspace for VisualPng
       projects      =>  Contains project files and workspaces for
--- a/src/share/native/sun/awt/libpng/png.c	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/png.c	Thu May 18 14:30:18 2017 -0700
@@ -29,8 +29,8 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.28 [January 5, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -42,7 +42,7 @@
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_20 Your_png_h_is_not_version_1_6_20;
+typedef png_libpng_version_1_6_28 Your_png_h_is_not_version_1_6_28;
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
@@ -113,7 +113,7 @@
    if (items >= (~(png_alloc_size_t)0)/size)
    {
       png_warning (png_voidcast(png_structrp, png_ptr),
-         "Potential overflow in png_zalloc()");
+          "Potential overflow in png_zalloc()");
       return NULL;
    }
 
@@ -200,10 +200,10 @@
 int
 png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
 {
-     /* Libpng versions 1.0.0 and later are binary compatible if the version
-      * string matches through the second '.'; we must recompile any
-      * applications that use any older library version.
-      */
+   /* Libpng versions 1.0.0 and later are binary compatible if the version
+    * string matches through the second '.'; we must recompile any
+    * applications that use any older library version.
+    */
 
    if (user_png_ver != NULL)
    {
@@ -325,7 +325,7 @@
          if (png_user_version_check(&create_struct, user_png_ver) != 0)
          {
             png_structrp png_ptr = png_voidcast(png_structrp,
-               png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+                png_malloc_warn(&create_struct, (sizeof *png_ptr)));
 
             if (png_ptr != NULL)
             {
@@ -374,7 +374,7 @@
     * has always been done in 'example.c'.
     */
    info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
-      (sizeof *info_ptr)));
+       (sizeof *info_ptr)));
 
    if (info_ptr != NULL)
       memset(info_ptr, 0, (sizeof *info_ptr));
@@ -430,7 +430,7 @@
  */
 PNG_FUNCTION(void,PNGAPI
 png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
-   PNG_DEPRECATED)
+    PNG_DEPRECATED)
 {
    png_inforp info_ptr = *ptr_ptr;
 
@@ -445,7 +445,7 @@
       /* The following line is why this API should not be used: */
       free(info_ptr);
       info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
-         (sizeof *info_ptr)));
+          (sizeof *info_ptr)));
       if (info_ptr == NULL)
          return;
       *ptr_ptr = info_ptr;
@@ -458,7 +458,7 @@
 /* The following API is not called internally */
 void PNGAPI
 png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
-   int freer, png_uint_32 mask)
+    int freer, png_uint_32 mask)
 {
    png_debug(1, "in png_data_freer");
 
@@ -477,7 +477,7 @@
 
 void PNGAPI
 png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
-   int num)
+    int num)
 {
    png_debug(1, "in png_free_data");
 
@@ -486,7 +486,7 @@
 
 #ifdef PNG_TEXT_SUPPORTED
    /* Free text item num or (if num == -1) all text items */
-   if (info_ptr->text != 0 &&
+   if (info_ptr->text != NULL &&
        ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -505,6 +505,7 @@
          png_free(png_ptr, info_ptr->text);
          info_ptr->text = NULL;
          info_ptr->num_text = 0;
+         info_ptr->max_text = 0;
       }
    }
 #endif
@@ -569,7 +570,7 @@
 
 #ifdef PNG_sPLT_SUPPORTED
    /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
-   if (info_ptr->splt_palettes != 0 &&
+   if (info_ptr->splt_palettes != NULL &&
        ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -599,7 +600,7 @@
 #endif
 
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-   if (info_ptr->unknown_chunks != 0 &&
+   if (info_ptr->unknown_chunks != NULL &&
        ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -645,7 +646,7 @@
    /* Free any image bits attached to the info structure */
    if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
    {
-      if (info_ptr->row_pointers != 0)
+      if (info_ptr->row_pointers != NULL)
       {
          png_uint_32 row;
          for (row = 0; row < info_ptr->height; row++)
@@ -712,7 +713,7 @@
 void PNGAPI
 png_save_int_32(png_bytep buf, png_int_32 i)
 {
-   png_save_uint_32(buf, i);
+   png_save_uint_32(buf, (png_uint_32)i);
 }
 #  endif
 
@@ -803,14 +804,15 @@
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-      "libpng version 1.6.20 - December 3, 2015" PNG_STRING_NEWLINE \
-      "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+      "libpng version 1.6.28 - January 5, 2017" PNG_STRING_NEWLINE \
+      "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
+      PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
       "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
       PNG_STRING_NEWLINE;
 #  else
-   return "libpng version 1.6.20 - December 3, 2015\
-      Copyright (c) 1998-2015 Glenn Randers-Pehrson\
+   return "libpng version 1.6.28 - January 5, 2017\
+      Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
@@ -1060,7 +1062,7 @@
 #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
 static int
 png_colorspace_check_gamma(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+    png_colorspacerp colorspace, png_fixed_point gAMA, int from)
    /* This is called to check a new gamma value against an existing one.  The
     * routine returns false if the new gamma value should not be written.
     *
@@ -1074,7 +1076,7 @@
    png_fixed_point gtest;
 
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
+       (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
       png_gamma_significant(gtest) != 0))
    {
       /* Either this is an sRGB image, in which case the calculated gamma
@@ -1086,7 +1088,7 @@
       if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
       {
          png_chunk_report(png_ptr, "gamma value does not match sRGB",
-            PNG_CHUNK_ERROR);
+             PNG_CHUNK_ERROR);
          /* Do not overwrite an sRGB value */
          return from == 2;
       }
@@ -1094,7 +1096,7 @@
       else /* sRGB tag not involved */
       {
          png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
-            PNG_CHUNK_WARNING);
+             PNG_CHUNK_WARNING);
          return from == 1;
       }
    }
@@ -1104,7 +1106,7 @@
 
 void /* PRIVATE */
 png_colorspace_set_gamma(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_fixed_point gAMA)
+    png_colorspacerp colorspace, png_fixed_point gAMA)
 {
    /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
     * occur.  Since the fixed point representation is asymetrical it is
@@ -1662,8 +1664,8 @@
 
 static int
 png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
-   int preferred)
+    png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+    int preferred)
 {
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
@@ -1710,7 +1712,7 @@
 
 int /* PRIVATE */
 png_colorspace_set_chromaticities(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_xy *xy, int preferred)
+    png_colorspacerp colorspace, const png_xy *xy, int preferred)
 {
    /* We must check the end points to ensure they are reasonable - in the past
     * color management systems have crashed as a result of getting bogus
@@ -1724,7 +1726,7 @@
    {
       case 0: /* success */
          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
-            preferred);
+             preferred);
 
       case 1:
          /* We can't invert the chromaticities so we can't produce value XYZ
@@ -1747,7 +1749,7 @@
 
 int /* PRIVATE */
 png_colorspace_set_endpoints(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+    png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
 {
    png_XYZ XYZ = *XYZ_in;
    png_xy xy;
@@ -1756,7 +1758,7 @@
    {
       case 0:
          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
-            preferred);
+             preferred);
 
       case 1:
          /* End points are invalid. */
@@ -1813,7 +1815,7 @@
 
 static int
 png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+    png_const_charp name, png_alloc_size_t value, png_const_charp reason)
 {
    size_t pos;
    char message[196]; /* see below for calculation */
@@ -1838,8 +1840,8 @@
          char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
 
          pos = png_safecat(message, (sizeof message), pos,
-            png_format_number(number, number+(sizeof number),
-               PNG_NUMBER_FORMAT_x, value));
+             png_format_number(number, number+(sizeof number),
+             PNG_NUMBER_FORMAT_x, value));
          pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
       }
 #  endif
@@ -1853,7 +1855,7 @@
     * application errors the PNG won't be written.)
     */
    png_chunk_report(png_ptr, message,
-      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+       (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
 
    return 0;
 }
@@ -1862,7 +1864,7 @@
 #ifdef PNG_sRGB_SUPPORTED
 int /* PRIVATE */
 png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   int intent)
+    int intent)
 {
    /* sRGB sets known gamma, end points and (from the chunk) intent. */
    /* IMPORTANT: these are not necessarily the values found in an ICC profile
@@ -1899,10 +1901,10 @@
     */
    if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-         (unsigned)intent, "invalid sRGB rendering intent");
+          (unsigned)intent, "invalid sRGB rendering intent");
 
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
-      colorspace->rendering_intent != intent)
+       colorspace->rendering_intent != intent)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
          (unsigned)intent, "inconsistent rendering intents");
 
@@ -1916,8 +1918,8 @@
     * warn but overwrite the value with the correct one.
     */
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
-      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
-         100))
+       !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+       100))
       png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
          PNG_CHUNK_ERROR);
 
@@ -1925,7 +1927,7 @@
     * returns true when the 'from' argument corresponds to sRGB (2).
     */
    (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
-      2/*from sRGB*/);
+       2/*from sRGB*/);
 
    /* intent: bugs in GCC force 'int' to be used as the parameter type. */
    colorspace->rendering_intent = (png_uint_16)intent;
@@ -1958,21 +1960,55 @@
 static const png_byte D50_nCIEXYZ[12] =
    { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
 
-int /* PRIVATE */
-png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length)
+static int /* bool */
+icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length)
 {
    if (profile_length < 132)
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-         "too short");
+          "too short");
 
    return 1;
 }
 
+#ifdef PNG_READ_iCCP_SUPPORTED
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length)
+{
+   if (!icc_check_length(png_ptr, colorspace, name, profile_length))
+      return 0;
+
+   /* This needs to be here because the 'normal' check is in
+    * png_decompress_chunk, yet this happens after the attempt to
+    * png_malloc_base the required data.  We only need this on read; on write
+    * the caller supplies the profile buffer so libpng doesn't allocate it.  See
+    * the call to icc_check_length below (the write case).
+    */
+#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      else if (png_ptr->user_chunk_malloc_max > 0 &&
+               png_ptr->user_chunk_malloc_max < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds application limits");
+#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
+      else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds libpng limits");
+#  else /* !SET_USER_LIMITS */
+      /* This will get compiled out on all 32-bit and better systems. */
+      else if (PNG_SIZE_MAX < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds system limits");
+#  endif /* !SET_USER_LIMITS */
+
+   return 1;
+}
+#endif /* READ_iCCP */
+
 int /* PRIVATE */
 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length,
-   png_const_bytep profile/* first 132 bytes only */, int color_type)
+    png_const_charp name, png_uint_32 profile_length,
+    png_const_bytep profile/* first 132 bytes only */, int color_type)
 {
    png_uint_32 temp;
 
@@ -1984,18 +2020,18 @@
    temp = png_get_uint_32(profile);
    if (temp != profile_length)
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "length does not match profile");
+          "length does not match profile");
 
    temp = (png_uint_32) (*(profile+8));
    if (temp > 3 && (profile_length & 3))
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-         "invalid length");
+          "invalid length");
 
    temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
    if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
       profile_length < 132+12*temp) /* truncated tag table */
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "tag count too large");
+          "tag count too large");
 
    /* The 'intent' must be valid or we can't store it, ICC limits the intent to
     * 16 bits.
@@ -2003,14 +2039,14 @@
    temp = png_get_uint_32(profile+64);
    if (temp >= 0xffff) /* The ICC limit */
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "invalid rendering intent");
+          "invalid rendering intent");
 
    /* This is just a warning because the profile may be valid in future
     * versions.
     */
    if (temp >= PNG_sRGB_INTENT_LAST)
       (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-         "intent outside defined range");
+          "intent outside defined range");
 
    /* At this point the tag table can't be checked because it hasn't necessarily
     * been loaded; however, various header fields can be checked.  These checks
@@ -2027,7 +2063,7 @@
    temp = png_get_uint_32(profile+36); /* signature 'ascp' */
    if (temp != 0x61637370)
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "invalid signature");
+          "invalid signature");
 
    /* Currently the PCS illuminant/adopted white point (the computational
     * white point) are required to be D50,
@@ -2038,7 +2074,7 @@
     */
    if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
       (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
-         "PCS illuminant is not D50");
+          "PCS illuminant is not D50");
 
    /* The PNG spec requires this:
     * "If the iCCP chunk is present, the image samples conform to the colour
@@ -2066,18 +2102,18 @@
       case 0x52474220: /* 'RGB ' */
          if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
             return png_icc_profile_error(png_ptr, colorspace, name, temp,
-               "RGB color space not permitted on grayscale PNG");
+                "RGB color space not permitted on grayscale PNG");
          break;
 
       case 0x47524159: /* 'GRAY' */
          if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
             return png_icc_profile_error(png_ptr, colorspace, name, temp,
-               "Gray color space not permitted on RGB PNG");
+                "Gray color space not permitted on RGB PNG");
          break;
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "invalid ICC profile color space");
+             "invalid ICC profile color space");
    }
 
    /* It is up to the application to check that the profile class matches the
@@ -2102,7 +2138,7 @@
       case 0x61627374: /* 'abst' */
          /* May not be embedded in an image */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "invalid embedded Abstract ICC profile");
+             "invalid embedded Abstract ICC profile");
 
       case 0x6c696e6b: /* 'link' */
          /* DeviceLink profiles cannot be interpreted in a non-device specific
@@ -2112,7 +2148,7 @@
           * PNG.
           */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "unexpected DeviceLink ICC profile class");
+             "unexpected DeviceLink ICC profile class");
 
       case 0x6e6d636c: /* 'nmcl' */
          /* A NamedColor profile is also device specific, however it doesn't
@@ -2120,7 +2156,7 @@
           * certainly it will fail the tests below.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-            "unexpected NamedColor ICC profile class");
+             "unexpected NamedColor ICC profile class");
          break;
 
       default:
@@ -2130,7 +2166,7 @@
           * understood profiles.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-            "unrecognized ICC profile class");
+             "unrecognized ICC profile class");
          break;
    }
 
@@ -2146,7 +2182,7 @@
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "unexpected ICC PCS encoding");
+             "unexpected ICC PCS encoding");
    }
 
    return 1;
@@ -2154,8 +2190,8 @@
 
 int /* PRIVATE */
 png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length,
-   png_const_bytep profile /* header plus whole tag table */)
+    png_const_charp name, png_uint_32 profile_length,
+    png_const_bytep profile /* header plus whole tag table */)
 {
    png_uint_32 tag_count = png_get_uint_32(profile+128);
    png_uint_32 itag;
@@ -2183,7 +2219,7 @@
           * alignment.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
-            "ICC profile tag start not a multiple of 4");
+             "ICC profile tag start not a multiple of 4");
       }
 
       /* This is a hard error; potentially it can cause read outside the
@@ -2191,7 +2227,7 @@
        */
       if (tag_start > profile_length || tag_length > profile_length - tag_start)
          return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
-            "ICC profile tag outside profile");
+             "ICC profile tag outside profile");
    }
 
    return 1; /* success, maybe with warnings */
@@ -2219,22 +2255,22 @@
     */
    /* adler32, crc32, MD5[4], intent, date, length, file-name */
    PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
-      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
-      "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+       PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+       "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
 
    /* ICC sRGB v2 perceptual no black-compensation: */
    PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
-      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
-      "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+       PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+       "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
 
    PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
-      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
-      "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+       PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+       "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
 
    /* ICC sRGB v4 perceptual */
    PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
-      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
-      "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+       PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+       "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
 
    /* The following profiles have no known MD5 checksum. If there is a match
     * on the (empty) MD5 the other fields are used to attempt a match and
@@ -2242,8 +2278,8 @@
     * which suggests that they were also made by Hewlett Packard.
     */
    PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
-      "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+       "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
 
    /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
     * match the D50 PCS illuminant in the header (it is in fact the D65 values,
@@ -2253,17 +2289,17 @@
     * chromaticAdaptationTag.
     */
    PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
-      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
 
    PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
-      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
 };
 
 static int
 png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
-   png_const_bytep profile, uLong adler)
+    png_const_bytep profile, uLong adler)
 {
    /* The quick check is to verify just the MD5 signature and trust the
     * rest of the data.  Because the profile has already been verified for
@@ -2347,7 +2383,7 @@
                       * which is made irrelevant by this error.
                       */
                      png_chunk_report(png_ptr, "known incorrect sRGB profile",
-                        PNG_CHUNK_ERROR);
+                         PNG_CHUNK_ERROR);
                   }
 
                   /* Warn that this being done; this isn't even an error since
@@ -2357,8 +2393,8 @@
                   else if (png_sRGB_checks[i].have_md5 == 0)
                   {
                      png_chunk_report(png_ptr,
-                        "out-of-date sRGB profile with no signature",
-                        PNG_CHUNK_WARNING);
+                         "out-of-date sRGB profile with no signature",
+                         PNG_CHUNK_WARNING);
                   }
 
                   return 1+png_sRGB_checks[i].is_broken;
@@ -2381,38 +2417,36 @@
 
    return 0; /* no match */
 }
-#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 
 void /* PRIVATE */
 png_icc_set_sRGB(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+    png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
 {
    /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
     * the sRGB information.
     */
-#if PNG_sRGB_PROFILE_CHECKS >= 0
    if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
-#endif
       (void)png_colorspace_set_sRGB(png_ptr, colorspace,
          (int)/*already checked*/png_get_uint_32(profile+64));
 }
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 #endif /* sRGB */
 
 int /* PRIVATE */
 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
-   int color_type)
+    png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+    int color_type)
 {
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
 
-   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
+   if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
        png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
-          color_type) != 0 &&
+           color_type) != 0 &&
        png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
-          profile) != 0)
+           profile) != 0)
    {
-#     ifdef PNG_sRGB_SUPPORTED
+#     if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
          /* If no sRGB support, don't try storing sRGB information */
          png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
 #     endif
@@ -2471,7 +2505,7 @@
          /* Check for an internal error. */
          if (r+g+b != 32768)
             png_error(png_ptr,
-               "internal error handling cHRM coefficients");
+                "internal error handling cHRM coefficients");
 
          else
          {
@@ -2497,7 +2531,7 @@
 static int /* PRIVATE */
 png_gt(size_t a, size_t b)
 {
-    return a > b;
+   return a > b;
 }
 #else
 #   define png_gt(a,b) ((a) > (b))
@@ -2505,9 +2539,9 @@
 
 void /* PRIVATE */
 png_check_IHDR(png_const_structrp png_ptr,
-   png_uint_32 width, png_uint_32 height, int bit_depth,
-   int color_type, int interlace_type, int compression_type,
-   int filter_type)
+    png_uint_32 width, png_uint_32 height, int bit_depth,
+    int color_type, int interlace_type, int compression_type,
+    int filter_type)
 {
    int error = 0;
 
@@ -2524,7 +2558,7 @@
       error = 1;
    }
 
-   if (png_gt(((width + 7) & (~7)),
+   if (png_gt(((width + 7) & (~7U)),
        ((PNG_SIZE_MAX
            - 48        /* big_row_buf hack */
            - 1)        /* filter byte */
@@ -2670,7 +2704,7 @@
 
 int /* PRIVATE */
 png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
-   png_size_tp whereami)
+    png_size_tp whereami)
 {
    int state = *statep;
    png_size_t i = *whereami;
@@ -2935,7 +2969,7 @@
              */
             if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
             {
-               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
+               czero = (unsigned int)(-exp_b10); /* PLUS 2 digits: TOTAL 3 */
                exp_b10 = 0;      /* Dot added below before first output. */
             }
             else
@@ -3113,11 +3147,11 @@
                if (exp_b10 < 0)
                {
                   *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
-                  uexp_b10 = -exp_b10;
+                  uexp_b10 = (unsigned int)(-exp_b10);
                }
 
                else
-                  uexp_b10 = exp_b10;
+                  uexp_b10 = (unsigned int)exp_b10;
 
                cdigits = 0;
 
@@ -3179,9 +3213,9 @@
 
       /* Avoid overflow here on the minimum integer. */
       if (fp < 0)
-         *ascii++ = 45, num = -fp;
+         *ascii++ = 45, num = (png_uint_32)(-fp);
       else
-         num = fp;
+         num = (png_uint_32)fp;
 
       if (num <= 0x80000000) /* else overflowed */
       {
@@ -3833,25 +3867,25 @@
 {
    if (value > 0 && value < 65535)
    {
-#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-         /* The same (unsigned int)->(double) constraints apply here as above,
-          * however in this case the (unsigned int) to (int) conversion can
-          * overflow on an ANSI-C90 compliant system so the cast needs to ensure
-          * that this is not possible.
-          */
-         double r = floor(65535*pow((png_int_32)value/65535.,
-                     gamma_val*.00001)+.5);
-         return (png_uint_16)r;
-#     else
-         png_int_32 lg2 = png_log16bit(value);
-         png_fixed_point res;
-
-         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
-            return png_exp16bit(res);
-
-         /* Overflow. */
-         value = 0;
-#     endif
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+      /* The same (unsigned int)->(double) constraints apply here as above,
+       * however in this case the (unsigned int) to (int) conversion can
+       * overflow on an ANSI-C90 compliant system so the cast needs to ensure
+       * that this is not possible.
+       */
+      double r = floor(65535*pow((png_int_32)value/65535.,
+          gamma_val*.00001)+.5);
+      return (png_uint_16)r;
+# else
+      png_int_32 lg2 = png_log16bit(value);
+      png_fixed_point res;
+
+      if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+         return png_exp16bit(res);
+
+      /* Overflow. */
+      value = 0;
+# endif
    }
 
    return (png_uint_16)value;
@@ -3890,7 +3924,7 @@
  */
 static void
 png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+    PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
 {
    /* Various values derived from 'shift': */
    PNG_CONST unsigned int num = 1U << (8U - shift);
@@ -3967,7 +4001,7 @@
  */
 static void
 png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+    PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
 {
    PNG_CONST unsigned int num = 1U << (8U - shift);
    PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
@@ -4035,7 +4069,7 @@
  */
 static void
 png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
-   PNG_CONST png_fixed_point gamma_val)
+    PNG_CONST png_fixed_point gamma_val)
 {
    unsigned int i;
    png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
@@ -4115,131 +4149,133 @@
 void /* PRIVATE */
 png_build_gamma_table(png_structrp png_ptr, int bit_depth)
 {
-  png_debug(1, "in png_build_gamma_table");
-
-  /* Remove any existing table; this copes with multiple calls to
-   * png_read_update_info.  The warning is because building the gamma tables
-   * multiple times is a performance hit - it's harmless but the ability to call
-   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
-   * to warn if the app introduces such a hit.
-   */
-  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
-  {
-    png_warning(png_ptr, "gamma table being rebuilt");
-    png_destroy_gamma_table(png_ptr);
-  }
-
-  if (bit_depth <= 8)
-  {
-     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
-         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+   png_debug(1, "in png_build_gamma_table");
+
+   /* Remove any existing table; this copes with multiple calls to
+    * png_read_update_info. The warning is because building the gamma tables
+    * multiple times is a performance hit - it's harmless but the ability to
+    * call png_read_update_info() multiple times is new in 1.5.6 so it seems
+    * sensible to warn if the app introduces such a hit.
+    */
+   if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+   {
+      png_warning(png_ptr, "gamma table being rebuilt");
+      png_destroy_gamma_table(png_ptr);
+   }
+
+   if (bit_depth <= 8)
+   {
+      png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+          png_ptr->screen_gamma > 0 ?
+          png_reciprocal2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
-     {
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
-            png_reciprocal(png_ptr->colorspace.gamma));
-
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
-            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
-     }
+      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+      {
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+             png_reciprocal(png_ptr->colorspace.gamma));
+
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+             png_ptr->screen_gamma > 0 ?
+             png_reciprocal(png_ptr->screen_gamma) :
+             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
+   }
 #ifdef PNG_16BIT_SUPPORTED
-  else
-  {
-     png_byte shift, sig_bit;
-
-     if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
-     {
-        sig_bit = png_ptr->sig_bit.red;
-
-        if (png_ptr->sig_bit.green > sig_bit)
-           sig_bit = png_ptr->sig_bit.green;
-
-        if (png_ptr->sig_bit.blue > sig_bit)
-           sig_bit = png_ptr->sig_bit.blue;
-     }
-     else
-        sig_bit = png_ptr->sig_bit.gray;
-
-     /* 16-bit gamma code uses this equation:
-      *
-      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
-      *
-      * Where 'iv' is the input color value and 'ov' is the output value -
-      * pow(iv, gamma).
-      *
-      * Thus the gamma table consists of up to 256 256-entry tables.  The table
-      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
-      * the color value then indexed by the upper 8 bits:
-      *
-      *   table[low bits][high 8 bits]
-      *
-      * So the table 'n' corresponds to all those 'iv' of:
-      *
-      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
-      *
-      */
-     if (sig_bit > 0 && sig_bit < 16U)
-        /* shift == insignificant bits */
-        shift = (png_byte)((16U - sig_bit) & 0xff);
-
-     else
-        shift = 0; /* keep all 16 bits */
-
-     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-     {
-        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
-         * the significant bits in the *input* when the output will
-         * eventually be 8 bits.  By default it is 11.
-         */
-        if (shift < (16U - PNG_MAX_GAMMA_8))
-           shift = (16U - PNG_MAX_GAMMA_8);
-     }
-
-     if (shift > 8U)
-        shift = 8U; /* Guarantees at least one table! */
-
-     png_ptr->gamma_shift = shift;
-
-     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
-      * PNG_COMPOSE).  This effectively smashed the background calculation for
-      * 16-bit output because the 8-bit table assumes the result will be reduced
-      * to 8 bits.
-      */
-     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
-
-     else
-         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+   else
+   {
+      png_byte shift, sig_bit;
+
+      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      {
+         sig_bit = png_ptr->sig_bit.red;
+
+         if (png_ptr->sig_bit.green > sig_bit)
+            sig_bit = png_ptr->sig_bit.green;
+
+         if (png_ptr->sig_bit.blue > sig_bit)
+            sig_bit = png_ptr->sig_bit.blue;
+      }
+      else
+         sig_bit = png_ptr->sig_bit.gray;
+
+      /* 16-bit gamma code uses this equation:
+       *
+       *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+       *
+       * Where 'iv' is the input color value and 'ov' is the output value -
+       * pow(iv, gamma).
+       *
+       * Thus the gamma table consists of up to 256 256-entry tables.  The table
+       * is selected by the (8-gamma_shift) most significant of the low 8 bits
+       * of the color value then indexed by the upper 8 bits:
+       *
+       *   table[low bits][high 8 bits]
+       *
+       * So the table 'n' corresponds to all those 'iv' of:
+       *
+       *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+       *
+       */
+      if (sig_bit > 0 && sig_bit < 16U)
+         /* shift == insignificant bits */
+         shift = (png_byte)((16U - sig_bit) & 0xff);
+
+      else
+         shift = 0; /* keep all 16 bits */
+
+      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+      {
+         /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+          * the significant bits in the *input* when the output will
+          * eventually be 8 bits.  By default it is 11.
+          */
+         if (shift < (16U - PNG_MAX_GAMMA_8))
+            shift = (16U - PNG_MAX_GAMMA_8);
+      }
+
+      if (shift > 8U)
+         shift = 8U; /* Guarantees at least one table! */
+
+      png_ptr->gamma_shift = shift;
+
+      /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+       * PNG_COMPOSE).  This effectively smashed the background calculation for
+       * 16-bit output because the 8-bit table assumes the result will be
+       * reduced to 8 bits.
+       */
+      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+          png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+          png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
+
+      else
+          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+          png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
-     {
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
-            png_reciprocal(png_ptr->colorspace.gamma));
-
-        /* Notice that the '16 from 1' table should be full precision, however
-         * the lookup on this table still uses gamma_shift, so it can't be.
-         * TODO: fix this.
-         */
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
-            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
-     }
+      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+      {
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+             png_reciprocal(png_ptr->colorspace.gamma));
+
+         /* Notice that the '16 from 1' table should be full precision, however
+          * the lookup on this table still uses gamma_shift, so it can't be.
+          * TODO: fix this.
+          */
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+             png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
+   }
 #endif /* 16BIT */
 }
 #endif /* READ_GAMMA */
@@ -4252,11 +4288,11 @@
    if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
       (option & 1) == 0)
    {
-      int mask = 3 << option;
-      int setting = (2 + (onoff != 0)) << option;
-      int current = png_ptr->options;
-
-      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);
+      png_uint_32 mask = 3 << option;
+      png_uint_32 setting = (2 + (onoff != 0)) << option;
+      png_uint_32 current = png_ptr->options;
+
+      png_ptr->options = (png_uint_32)(((current & ~mask) | setting) & 0xff);
 
       return (current & mask) >> option;
    }
--- a/src/share/native/sun/awt/libpng/png.h	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/png.h	Thu May 18 14:30:18 2017 -0700
@@ -29,9 +29,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * libpng version 1.6.20, December 3, 2015
+ * libpng version 1.6.28, January 5, 2017
  *
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -40,7 +40,7 @@
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.20, December 3, 2015:
+ *   libpng versions 0.97, January 1998, through 1.6.28, January 5, 2017:
  *     Glenn Randers-Pehrson.
  *   See also "Contributing Authors", below.
  */
@@ -53,8 +53,8 @@
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are
- * Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.28, January 5, 2017 are
+ * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
  * derived from libpng-1.0.6, and are distributed according to the same
  * disclaimer and license as libpng-1.0.6 with the following individuals
  * added to the list of Contributing Authors:
@@ -65,6 +65,7 @@
  *    Cosmin Truta
  *    Gilles Vollant
  *    James Yu
+ *    Mandar Sahastrabuddhe
  *
  * and with the following additions to the disclaimer:
  *
@@ -75,6 +76,10 @@
  *    risk of satisfactory quality, performance, accuracy, and effort is with
  *    the user.
  *
+ * Some files in the "contrib" directory and some configure-generated
+ * files that are distributed with libpng have other copyright owners and
+ * are released under other open source licenses.
+ *
  * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
  * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
  * libpng-0.96, and are distributed according to the same disclaimer and
@@ -98,6 +103,9 @@
  *    Greg Roelofs
  *    Tom Tanner
  *
+ * Some files in the "scripts" directory have other copyright owners
+ * but are released under this license.
+ *
  * libpng versions 0.5, May 1995, through 0.88, January 1996, are
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
@@ -137,6 +145,29 @@
  * appreciated.
  *
  * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+ *
+ * TRADEMARK:
+ *
+ * The name "libpng" has not been registered by the Copyright owner
+ * as a trademark in any jurisdiction.  However, because libpng has
+ * been distributed and maintained world-wide, continually since 1995,
+ * the Copyright owner claims "common-law trademark protection" in any
+ * jurisdiction where common-law trademark is recognized.
+ *
+ * OSI CERTIFICATION:
+ *
+ * Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
+ * a certification mark of the Open Source Initiative. OSI has not addressed
+ * the additional disclaimers inserted at version 1.0.7.
+ *
+ * EXPORT CONTROL:
+ *
+ * The Copyright owner believes that the Export Control Classification
+ * Number (ECCN) for libpng is EAR99, which means not subject to export
+ * controls or International Traffic in Arms Regulations (ITAR) because
+ * it is open source, publicly available software, that does not contain
+ * any encryption software.  See the EAR, paragraphs 734.3(b)(3) and
+ * 734.7(b).
  */
 
 /*
@@ -150,12 +181,6 @@
  */
 
 /*
- * Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
- * a certification mark of the Open Source Initiative. OSI has not addressed
- * the additional disclaimers inserted at version 1.0.7.
- */
-
-/*
  * The contributing authors would like to thank all those who helped
  * with testing, bug fixes, and patience.  This wouldn't have been
  * possible without all of you.
@@ -210,11 +235,11 @@
  *    ...
  *    1.0.19                  10    10019  10.so.0.19[.0]
  *    ...
- *    1.2.53                  13    10253  12.so.0.53[.0]
+ *    1.2.57                  13    10257  12.so.0.57[.0]
  *    ...
- *    1.5.23                  15    10523  15.so.15.23[.0]
+ *    1.5.28                  15    10527  15.so.15.28[.0]
  *    ...
- *    1.6.20                  16    10620  16.so.16.20[.0]
+ *    1.6.28                  16    10628  16.so.16.28[.0]
  *
  *    Henceforth the source version will match the shared-library major
  *    and minor numbers; the shared-library major version number will be
@@ -242,13 +267,13 @@
  * Y2K compliance in libpng:
  * =========================
  *
- *    December 3, 2015
+ *    January 5, 2017
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *
  *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.20 are Y2K compliant.  It is my belief that
+ *    upward through 1.6.28 are Y2K compliant.  It is my belief that
  *    earlier versions were also Y2K compliant.
  *
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
@@ -310,9 +335,8 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.20"
-#define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.20 - December 3, 2015\n"
+#define PNG_LIBPNG_VER_STRING "1.6.28"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.28 - January 5, 2017\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
@@ -320,7 +344,7 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 20
+#define PNG_LIBPNG_VER_RELEASE 28
 
 /* This should match the numeric part of the final component of
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -351,20 +375,20 @@
  * version 1.0.0 was mis-numbered 100 instead of 10000).  From
  * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
  */
-#define PNG_LIBPNG_VER 10620 /* 1.6.20 */
+#define PNG_LIBPNG_VER 10628 /* 1.6.28 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
  */
 #ifndef PNGLCONF_H
-    /* If pnglibconf.h is missing, you can
-     * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
-     */
+/* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
 #   include "pnglibconf.h"
 #endif
 
 #ifndef PNG_VERSION_INFO_ONLY
-   /* Machine specific configuration. */
+/* Machine specific configuration. */
 #  include "pngconf.h"
 #endif
 
@@ -461,7 +485,7 @@
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_20;
+typedef char* png_libpng_version_1_6_28;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
@@ -654,17 +678,17 @@
  */
 typedef struct png_unknown_chunk_t
 {
-    png_byte name[5]; /* Textual chunk name with '\0' terminator */
-    png_byte *data;   /* Data, should not be modified on read! */
-    png_size_t size;
-
-    /* On write 'location' must be set using the flag values listed below.
-     * Notice that on read it is set by libpng however the values stored have
-     * more bits set than are listed below.  Always treat the value as a
-     * bitmask.  On write set only one bit - setting multiple bits may cause the
-     * chunk to be written in multiple places.
-     */
-    png_byte location; /* mode of operation at read time */
+   png_byte name[5]; /* Textual chunk name with '\0' terminator */
+   png_byte *data;   /* Data, should not be modified on read! */
+   png_size_t size;
+
+   /* On write 'location' must be set using the flag values listed below.
+    * Notice that on read it is set by libpng however the values stored have
+    * more bits set than are listed below.  Always treat the value as a
+    * bitmask.  On write set only one bit - setting multiple bits may cause the
+    * chunk to be written in multiple places.
+    */
+   png_byte location; /* mode of operation at read time */
 }
 png_unknown_chunk;
 
@@ -762,24 +786,22 @@
  * data in the info_struct to be written into the output file.  The values
  * of the PNG_INFO_<chunk> defines should NOT be changed.
  */
-#define PNG_INFO_gAMA 0x0001
-#define PNG_INFO_sBIT 0x0002
-#define PNG_INFO_cHRM 0x0004
-#define PNG_INFO_PLTE 0x0008
-#define PNG_INFO_tRNS 0x0010
-#define PNG_INFO_bKGD 0x0020
-#define PNG_INFO_hIST 0x0040
-#define PNG_INFO_pHYs 0x0080
-#define PNG_INFO_oFFs 0x0100
-#define PNG_INFO_tIME 0x0200
-#define PNG_INFO_pCAL 0x0400
-#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
-#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
-#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
-#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
-#if INT_MAX >= 0x8000 /* else this might break */
-#define PNG_INFO_IDAT 0x8000   /* ESR, 1.0.6 */
-#endif
+#define PNG_INFO_gAMA 0x0001U
+#define PNG_INFO_sBIT 0x0002U
+#define PNG_INFO_cHRM 0x0004U
+#define PNG_INFO_PLTE 0x0008U
+#define PNG_INFO_tRNS 0x0010U
+#define PNG_INFO_bKGD 0x0020U
+#define PNG_INFO_hIST 0x0040U
+#define PNG_INFO_pHYs 0x0080U
+#define PNG_INFO_oFFs 0x0100U
+#define PNG_INFO_tIME 0x0200U
+#define PNG_INFO_pCAL 0x0400U
+#define PNG_INFO_sRGB 0x0800U  /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000U  /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000U  /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
 
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
@@ -1350,7 +1372,7 @@
 #endif
 
 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
+#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
 /* Strip the second byte of information from a 16-bit depth file. */
 PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
 #endif
@@ -1501,8 +1523,8 @@
 #define PNG_FILTER_UP      0x20
 #define PNG_FILTER_AVG     0x40
 #define PNG_FILTER_PAETH   0x80
-#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
-                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
+#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
+#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
 
 /* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
  * These defines should NOT be changed.
@@ -1779,21 +1801,21 @@
 #define PNG_SET_WILL_FREE_DATA 1
 #define PNG_USER_WILL_FREE_DATA 2
 /* Flags for png_ptr->free_me and info_ptr->free_me */
-#define PNG_FREE_HIST 0x0008
-#define PNG_FREE_ICCP 0x0010
-#define PNG_FREE_SPLT 0x0020
-#define PNG_FREE_ROWS 0x0040
-#define PNG_FREE_PCAL 0x0080
-#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_HIST 0x0008U
+#define PNG_FREE_ICCP 0x0010U
+#define PNG_FREE_SPLT 0x0020U
+#define PNG_FREE_ROWS 0x0040U
+#define PNG_FREE_PCAL 0x0080U
+#define PNG_FREE_SCAL 0x0100U
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-#  define PNG_FREE_UNKN 0x0200
+#  define PNG_FREE_UNKN 0x0200U
 #endif
-/*      PNG_FREE_LIST 0x0400    removed in 1.6.0 because it is ignored */
-#define PNG_FREE_PLTE 0x1000
-#define PNG_FREE_TRNS 0x2000
-#define PNG_FREE_TEXT 0x4000
-#define PNG_FREE_ALL  0x7fff
-#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+/*      PNG_FREE_LIST 0x0400U   removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000U
+#define PNG_FREE_TRNS 0x2000U
+#define PNG_FREE_TEXT 0x4000U
+#define PNG_FREE_ALL  0x7fffU
+#define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
 
 #ifdef PNG_USER_MEM_SUPPORTED
 PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
@@ -2299,8 +2321,10 @@
  *    except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
  *    be processed by libpng.
  */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
     int keep, png_const_bytep chunk_list, int num_chunks));
+#endif /* HANDLE_AS_UNKNOWN */
 
 /* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
  * the result is therefore true (non-zero) if special handling is required,
@@ -2308,7 +2332,7 @@
  */
 PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
     png_const_bytep chunk_name));
-#endif
+#endif /* SET_UNKNOWN_CHUNKS */
 
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
 PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
@@ -2529,33 +2553,37 @@
 
  /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
 
-#  define png_composite(composite, fg, alpha, bg)         \
-     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
-           * (png_uint_16)(alpha)                         \
-           + (png_uint_16)(bg)*(png_uint_16)(255          \
-           - (png_uint_16)(alpha)) + 128);                \
-       (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); }
-
-#  define png_composite_16(composite, fg, alpha, bg)       \
-     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \
-           * (png_uint_32)(alpha)                          \
-           + (png_uint_32)(bg)*(65535                      \
-           - (png_uint_32)(alpha)) + 32768);               \
-       (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); }
+#  define png_composite(composite, fg, alpha, bg)        \
+   {                                                     \
+      png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+          * (png_uint_16)(alpha)                         \
+          + (png_uint_16)(bg)*(png_uint_16)(255          \
+          - (png_uint_16)(alpha)) + 128);                \
+      (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
+   }
+
+#  define png_composite_16(composite, fg, alpha, bg)     \
+   {                                                     \
+      png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+          * (png_uint_32)(alpha)                         \
+          + (png_uint_32)(bg)*(65535                     \
+          - (png_uint_32)(alpha)) + 32768);              \
+      (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
+   }
 
 #else  /* Standard method using integer division */
 
-#  define png_composite(composite, fg, alpha, bg)                        \
-     (composite) =                                                       \
-         (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
-         (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
-         127) / 255))
-
-#  define png_composite_16(composite, fg, alpha, bg)                         \
-     (composite) =                                                           \
-         (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
-         (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
-         32767) / 65535))
+#  define png_composite(composite, fg, alpha, bg)                      \
+   (composite) =                                                       \
+       (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
+       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+       127) / 255))
+
+#  define png_composite_16(composite, fg, alpha, bg)                       \
+   (composite) =                                                           \
+       (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+       (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
+       32767) / 65535))
 #endif /* READ_COMPOSITE_NODIV */
 
 #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
@@ -2591,38 +2619,38 @@
  * format for negative values, which is almost certainly true.
  */
 #  define PNG_get_uint_32(buf) \
-     (((png_uint_32)(*(buf)) << 24) + \
-      ((png_uint_32)(*((buf) + 1)) << 16) + \
-      ((png_uint_32)(*((buf) + 2)) << 8) + \
-      ((png_uint_32)(*((buf) + 3))))
+   (((png_uint_32)(*(buf)) << 24) + \
+    ((png_uint_32)(*((buf) + 1)) << 16) + \
+    ((png_uint_32)(*((buf) + 2)) << 8) + \
+    ((png_uint_32)(*((buf) + 3))))
 
    /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
     * function) incorrectly returned a value of type png_uint_32.
     */
 #  define PNG_get_uint_16(buf) \
-     ((png_uint_16) \
-      (((unsigned int)(*(buf)) << 8) + \
-       ((unsigned int)(*((buf) + 1)))))
+   ((png_uint_16) \
+    (((unsigned int)(*(buf)) << 8) + \
+    ((unsigned int)(*((buf) + 1)))))
 
 #  define PNG_get_int_32(buf) \
-     ((png_int_32)((*(buf) & 0x80) \
-      ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
-      : (png_int_32)png_get_uint_32(buf)))
-
-   /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
-    * but defining a macro name prefixed with PNG_PREFIX.
-    */
+   ((png_int_32)((*(buf) & 0x80) \
+    ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
+    : (png_int_32)png_get_uint_32(buf)))
+
+/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
 #  ifndef PNG_PREFIX
-#     define png_get_uint_32(buf) PNG_get_uint_32(buf)
-#     define png_get_uint_16(buf) PNG_get_uint_16(buf)
-#     define png_get_int_32(buf)  PNG_get_int_32(buf)
+#    define png_get_uint_32(buf) PNG_get_uint_32(buf)
+#    define png_get_uint_16(buf) PNG_get_uint_16(buf)
+#    define png_get_int_32(buf)  PNG_get_int_32(buf)
 #  endif
 #else
 #  ifdef PNG_PREFIX
-      /* No macros; revert to the (redefined) function */
-#     define PNG_get_uint_32 (png_get_uint_32)
-#     define PNG_get_uint_16 (png_get_uint_16)
-#     define PNG_get_int_32  (png_get_int_32)
+   /* No macros; revert to the (redefined) function */
+#    define PNG_get_uint_32 (png_get_uint_32)
+#    define PNG_get_uint_16 (png_get_uint_16)
+#    define PNG_get_int_32  (png_get_int_32)
 #  endif
 #endif
 
@@ -2917,12 +2945,19 @@
     * is the minimum 'row stride', the minimum count of components between each
     * row.  For a color-mapped image this is the minimum number of bytes in a
     * row.
+    *
+    * WARNING: this macro overflows for some images with more than one component
+    * and very large image widths.  libpng will refuse to process an image where
+    * this macro would overflow.
     */
 
 #define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
    (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
    /* Return the size, in bytes, of an image buffer given a png_image and a row
     * stride - the number of components to leave space for in each row.
+    *
+    * WARNING: this macro overflows a 32-bit integer for some large PNG images,
+    * libpng will refuse to process an image where such an overflow would occur.
     */
 
 #define PNG_IMAGE_SIZE(image)\
@@ -3043,7 +3078,6 @@
 #endif /* SIMPLIFIED_READ */
 
 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-#ifdef PNG_STDIO_SUPPORTED
 /* WRITE APIS
  * ----------
  * For write you must initialize a png_image structure to describe the image to
@@ -3060,6 +3094,7 @@
  *    values do not correspond to the colors in sRGB.
  * colormap_entries: set to the number of entries in the color-map (0 to 256)
  */
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
 PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
    const char *file, int convert_to_8bit, const void *buffer,
    png_int_32 row_stride, const void *colormap));
@@ -3069,8 +3104,9 @@
    int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
    const void *colormap));
    /* Write the image to the given (FILE*). */
-
-/* With both write APIs if image is in one of the linear formats with 16-bit
+#endif /* SIMPLIFIED_WRITE_STDIO */
+
+/* With all write APIs if image is in one of the linear formats with 16-bit
  * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
  * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
  * encoded PNG file is written.
@@ -3082,13 +3118,103 @@
  *
  * With all APIs row_stride is handled as in the read APIs - it is the spacing
  * from one row to the next in component sized units (1 or 2 bytes) and if
- * negative indicates a bottom-up row layout in the buffer.  If row_stride is zero,
- * libpng will calculate it for you from the image width and number of channels.
+ * negative indicates a bottom-up row layout in the buffer.  If row_stride is
+ * zero, libpng will calculate it for you from the image width and number of
+ * channels.
  *
- * Note that the write API does not support interlacing, sub-8-bit pixels, indexed
- * PNG (color_type 3) or most ancillary chunks.
+ * Note that the write API does not support interlacing, sub-8-bit pixels or
+ * most ancillary chunks.  If you need to write text chunks (e.g. for copyright
+ * notices) you need to use one of the other APIs.
  */
-#endif /* STDIO */
+
+PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
+   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
+   const void *buffer, png_int_32 row_stride, const void *colormap));
+   /* Write the image to the given memory buffer.  The function both writes the
+    * whole PNG data stream to *memory and updates *memory_bytes with the count
+    * of bytes written.
+    *
+    * 'memory' may be NULL.  In this case *memory_bytes is not read however on
+    * success the number of bytes which would have been written will still be
+    * stored in *memory_bytes.  On failure *memory_bytes will contain 0.
+    *
+    * If 'memory' is not NULL it must point to memory[*memory_bytes] of
+    * writeable memory.
+    *
+    * If the function returns success memory[*memory_bytes] (if 'memory' is not
+    * NULL) contains the written PNG data.  *memory_bytes will always be less
+    * than or equal to the original value.
+    *
+    * If the function returns false and *memory_bytes was not changed an error
+    * occured during write.  If *memory_bytes was changed, or is not 0 if
+    * 'memory' was NULL, the write would have succeeded but for the memory
+    * buffer being too small.  *memory_bytes contains the required number of
+    * bytes and will be bigger that the original value.
+    */
+
+#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
+   row_stride, colormap)\
+   png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
+         row_stride, colormap)
+   /* Return the amount of memory in 'size' required to compress this image.
+    * The png_image structure 'image' must be filled in as in the above
+    * function and must not be changed before the actual write call, the buffer
+    * and all other parameters must also be identical to that in the final
+    * write call.  The 'size' variable need not be initialized.
+    *
+    * NOTE: the macro returns true/false, if false is returned 'size' will be
+    * set to zero and the write failed and probably will fail if tried again.
+    */
+
+/* You can pre-allocate the buffer by making sure it is of sufficient size
+ * regardless of the amount of compression achieved.  The buffer size will
+ * always be bigger than the original image and it will never be filled.  The
+ * following macros are provided to assist in allocating the buffer.
+ */
+#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
+   /* The number of uncompressed bytes in the PNG byte encoding of the image;
+    * uncompressing the PNG IDAT data will give this number of bytes.
+    *
+    * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
+    * macro can because of the extra bytes used in the PNG byte encoding.  You
+    * need to avoid this macro if your image size approaches 2^30 in width or
+    * height.  The same goes for the remainder of these macros; they all produce
+    * bigger numbers than the actual in-memory image size.
+    */
+#ifndef PNG_ZLIB_MAX_SIZE
+#  define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
+   /* An upper bound on the number of compressed bytes given 'b' uncompressed
+    * bytes.  This is based on deflateBounds() in zlib; different
+    * implementations of zlib compression may conceivably produce more data so
+    * if your zlib implementation is not zlib itself redefine this macro
+    * appropriately.
+    */
+#endif
+
+#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
+   PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
+   /* An upper bound on the size of the data in the PNG IDAT chunks. */
+
+#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
+   ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
+    (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
+    12U+3U*(image).colormap_entries/*PLTE data*/+\
+    (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
+    12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
+    12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
+   /* A helper for the following macro; if your compiler cannot handle the
+    * following macro use this one with the result of
+    * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
+    * compilers should handle this just fine.)
+    */
+
+#define PNG_IMAGE_PNG_SIZE_MAX(image)\
+   PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
+   /* An upper bound on the total length of the PNG data stream for 'image'.
+    * The result is of type png_alloc_size_t, on 32-bit systems this may
+    * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
+    * run out of buffer space but return a corrected size which should work.
+    */
 #endif /* SIMPLIFIED_WRITE */
 /*******************************************************************************
  *  END OF SIMPLIFIED API
@@ -3122,7 +3248,11 @@
 #endif
 #define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
 #define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
-#define PNG_OPTION_NEXT  6 /* Next option - numbers must be even */
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+#  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
+#endif
+#define PNG_IGNORE_ADLER32 8
+#define PNG_OPTION_NEXT  10 /* Next option - numbers must be even */
 
 /* Return values: NOTE: there are four values and 'off' is *not* zero */
 #define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
@@ -3146,7 +3276,7 @@
  * one to use is one more than this.)
  */
 #ifdef PNG_EXPORT_LAST_ORDINAL
-  PNG_EXPORT_LAST_ORDINAL(244);
+  PNG_EXPORT_LAST_ORDINAL(245);
 #endif
 
 #ifdef __cplusplus
--- a/src/share/native/sun/awt/libpng/pngconf.h	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngconf.h	Thu May 18 14:30:18 2017 -0700
@@ -29,9 +29,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * libpng version 1.6.20, December 3, 2015
+ * libpng version 1.6.28, January 5, 2017
  *
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -216,27 +216,27 @@
    * compatible with GCC or Visual C because of different calling conventions.
    */
 #  if PNG_API_RULE == 2
-    /* If this line results in an error, either because __watcall is not
-     * understood or because of a redefine just below you cannot use *this*
-     * build of the library with the compiler you are using.  *This* build was
-     * build using Watcom and applications must also be built using Watcom!
-     */
+   /* If this line results in an error, either because __watcall is not
+    * understood or because of a redefine just below you cannot use *this*
+    * build of the library with the compiler you are using.  *This* build was
+    * build using Watcom and applications must also be built using Watcom!
+    */
 #    define PNGCAPI __watcall
 #  endif
 
 #  if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
 #    define PNGCAPI __cdecl
 #    if PNG_API_RULE == 1
-       /* If this line results in an error __stdcall is not understood and
-        * PNG_API_RULE should not have been set to '1'.
-        */
+   /* If this line results in an error __stdcall is not understood and
+    * PNG_API_RULE should not have been set to '1'.
+    */
 #      define PNGAPI __stdcall
 #    endif
 #  else
-    /* An older compiler, or one not detected (erroneously) above,
-     * if necessary override on the command line to get the correct
-     * variants for the compiler.
-     */
+   /* An older compiler, or one not detected (erroneously) above,
+    * if necessary override on the command line to get the correct
+    * variants for the compiler.
+    */
 #    ifndef PNGCAPI
 #      define PNGCAPI _cdecl
 #    endif
@@ -253,10 +253,10 @@
 
 #  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
       (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
-    /* older Borland and MSC
-     * compilers used '__export' and required this to be after
-     * the type.
-     */
+   /* older Borland and MSC
+    * compilers used '__export' and required this to be after
+    * the type.
+    */
 #    ifndef PNG_EXPORT_TYPE
 #      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
 #    endif
@@ -272,9 +272,9 @@
 #  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
 #    define PNGAPI _System
 #  else /* !Windows/x86 && !OS/2 */
-    /* Use the defaults, or define PNG*API on the command line (but
-     * this will have to be done for every compile!)
-     */
+   /* Use the defaults, or define PNG*API on the command line (but
+    * this will have to be done for every compile!)
+    */
 #  endif /* other system, !OS/2 */
 #endif /* !Windows/x86 */
 
@@ -295,7 +295,7 @@
  */
 #ifndef PNG_IMPEXP
 #  if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
-     /* This forces use of a DLL, disallowing static linking */
+   /* This forces use of a DLL, disallowing static linking */
 #    define PNG_IMPEXP PNG_DLL_IMPORT
 #  endif
 
@@ -368,7 +368,7 @@
    * less efficient code.
    */
 #  if defined(__clang__) && defined(__has_attribute)
-     /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+   /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
 #    if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
 #      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
 #    endif
@@ -535,9 +535,9 @@
 #  error "libpng requires a signed 32-bit (or more) type"
 #endif
 
-#if UINT_MAX > 4294967294
+#if UINT_MAX > 4294967294U
    typedef unsigned int png_uint_32;
-#elif ULONG_MAX > 4294967294
+#elif ULONG_MAX > 4294967294U
    typedef unsigned long int png_uint_32;
 #else
 #  error "libpng requires an unsigned 32-bit (or more) type"
--- a/src/share/native/sun/awt/libpng/pngdebug.h	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngdebug.h	Thu May 18 14:30:18 2017 -0700
@@ -30,7 +30,7 @@
  * file and, per its terms, should not be removed:
  *
  * Last changed in libpng 1.6.8 [December 19, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
--- a/src/share/native/sun/awt/libpng/pngerror.c	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngerror.c	Thu May 18 14:30:18 2017 -0700
@@ -29,8 +29,8 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -54,7 +54,7 @@
 #ifdef PNG_WARNINGS_SUPPORTED
 static void /* PRIVATE */
 png_default_warning PNGARG((png_const_structrp png_ptr,
-   png_const_charp warning_message));
+    png_const_charp warning_message));
 #endif /* WARNINGS */
 
 /* This function is called whenever there is a fatal error.  This function
@@ -65,14 +65,14 @@
 #ifdef PNG_ERROR_TEXT_SUPPORTED
 PNG_FUNCTION(void,PNGAPI
 png_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    char msg[16];
    if (png_ptr != NULL)
    {
       if ((png_ptr->flags &
-         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0
+         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
       {
          if (*error_message == PNG_LITERAL_SHARP)
          {
@@ -93,18 +93,18 @@
 
             else
                error_message += offset;
+         }
+
+         else
+         {
+            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+            {
+               msg[0] = '0';
+               msg[1] = '\0';
+               error_message = msg;
+            }
+         }
       }
-
-      else
-      {
-         if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
-         {
-            msg[0] = '0';
-            msg[1] = '\0';
-            error_message = msg;
-         }
-       }
-     }
    }
 #endif
    if (png_ptr != NULL && png_ptr->error_fn != NULL)
@@ -138,7 +138,7 @@
  */
 size_t
 png_safecat(png_charp buffer, size_t bufsize, size_t pos,
-   png_const_charp string)
+    png_const_charp string)
 {
    if (buffer != NULL && pos < bufsize)
    {
@@ -159,7 +159,7 @@
  */
 png_charp
 png_format_number(png_const_charp start, png_charp end, int format,
-   png_alloc_size_t number)
+    png_alloc_size_t number)
 {
    int count = 0;    /* number of digits output */
    int mincount = 1; /* minimum number required */
@@ -261,7 +261,7 @@
    }
    if (png_ptr != NULL && png_ptr->warning_fn != NULL)
       (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
-         warning_message + offset);
+          warning_message + offset);
    else
       png_default_warning(png_ptr, warning_message + offset);
 }
@@ -273,7 +273,7 @@
  */
 void
 png_warning_parameter(png_warning_parameters p, int number,
-   png_const_charp string)
+    png_const_charp string)
 {
    if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
       (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
@@ -281,7 +281,7 @@
 
 void
 png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
-   png_alloc_size_t value)
+    png_alloc_size_t value)
 {
    char buffer[PNG_NUMBER_BUFFER_SIZE];
    png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
@@ -289,7 +289,7 @@
 
 void
 png_warning_parameter_signed(png_warning_parameters p, int number, int format,
-   png_int_32 value)
+    png_int_32 value)
 {
    png_alloc_size_t u;
    png_charp str;
@@ -310,7 +310,7 @@
 
 void
 png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
-   png_const_charp message)
+    png_const_charp message)
 {
    /* The internal buffer is just 192 bytes - enough for all our messages,
     * overflow doesn't happen because this code checks!  If someone figures
@@ -419,10 +419,10 @@
 void /* PRIVATE */
 png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
+   if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
+      png_warning(png_ptr, error_message);
+   else
+      png_error(png_ptr, error_message);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
       PNG_UNUSED(error_message)
@@ -432,10 +432,10 @@
 void /* PRIVATE */
 png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
+   if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+      png_warning(png_ptr, error_message);
+   else
+      png_error(png_ptr, error_message);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
       PNG_UNUSED(error_message)
@@ -506,7 +506,7 @@
 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
 PNG_FUNCTION(void,PNGAPI
 png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
    char msg[18+PNG_MAX_ERROR_TEXT];
    if (png_ptr == NULL)
@@ -601,7 +601,7 @@
 {
 #  define fixed_message "fixed point overflow in "
 #  define fixed_message_ln ((sizeof fixed_message)-1)
-   int  iin;
+   unsigned int  iin;
    char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
    memcpy(msg, fixed_message, fixed_message_ln);
    iin = 0;
@@ -648,7 +648,7 @@
       else
       {
          png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
-            png_malloc_warn(png_ptr, jmp_buf_size));
+             png_malloc_warn(png_ptr, jmp_buf_size));
 
          if (png_ptr->jmp_buf_ptr == NULL)
             return NULL; /* new NULL return on OOM */
@@ -737,7 +737,7 @@
  */
 static PNG_FUNCTION(void /* PRIVATE */,
 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
 #ifdef PNG_CONSOLE_IO_SUPPORTED
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -911,7 +911,7 @@
     */
 PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
 png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
    const png_const_structrp png_ptr = png_nonconst_ptr;
    png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
@@ -934,7 +934,7 @@
       /* Missing longjmp buffer, the following is to help debugging: */
       {
          size_t pos = png_safecat(image->message, (sizeof image->message), 0,
-            "bad longjmp: ");
+             "bad longjmp: ");
          png_safecat(image->message, (sizeof image->message), pos,
              error_message);
       }
--- a/src/share/native/sun/awt/libpng/pngget.c	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngget.c	Thu May 18 14:30:18 2017 -0700
@@ -28,9 +28,9 @@
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
- *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -366,7 +366,7 @@
    png_fixed_point result;
    if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
        5000) != 0)
-      return result;
+      return (png_uint_32)result;
 
    /* Overflow. */
    return 0;
@@ -484,11 +484,11 @@
    return (retval);
 }
 #endif /* pHYs */
-#endif  /* INCH_CONVERSIONS */
+#endif /* INCH_CONVERSIONS */
 
 /* png_get_channels really belongs in here, too, but it's been around longer */
 
-#endif  /* EASY_ACCESS */
+#endif /* EASY_ACCESS */
 
 
 png_byte PNGAPI
@@ -514,7 +514,7 @@
 #ifdef PNG_bKGD_SUPPORTED
 png_uint_32 PNGAPI
 png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
-   png_color_16p *background)
+    png_color_16p *background)
 {
    if (png_ptr != NULL && info_ptr != NULL &&
        (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
@@ -554,28 +554,28 @@
 
       if (white_x != NULL)
          *white_x = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+             info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
       if (white_y != NULL)
          *white_y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+             info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
       if (red_x != NULL)
          *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
-            "cHRM red X");
+             "cHRM red X");
       if (red_y != NULL)
          *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
-            "cHRM red Y");
+             "cHRM red Y");
       if (green_x != NULL)
          *green_x = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+             info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
       if (green_y != NULL)
          *green_y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+             info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
       if (blue_x != NULL)
          *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
-            "cHRM blue X");
+             "cHRM blue X");
       if (blue_y != NULL)
          *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
-            "cHRM blue Y");
+             "cHRM blue Y");
       return (PNG_INFO_cHRM);
    }
 
@@ -584,42 +584,42 @@
 
 png_uint_32 PNGAPI
 png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
-   double *red_X, double *red_Y, double *red_Z, double *green_X,
-   double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
-   double *blue_Z)
+    double *red_X, double *red_Y, double *red_Z, double *green_X,
+    double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+    double *blue_Z)
 {
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
    {
       png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
 
       if (red_X != NULL)
          *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
-            "cHRM red X");
+             "cHRM red X");
       if (red_Y != NULL)
          *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
-            "cHRM red Y");
+             "cHRM red Y");
       if (red_Z != NULL)
          *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
-            "cHRM red Z");
+             "cHRM red Z");
       if (green_X != NULL)
          *green_X = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+             info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
       if (green_Y != NULL)
          *green_Y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+             info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
       if (green_Z != NULL)
          *green_Z = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+             info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
       if (blue_X != NULL)
          *blue_X = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+             info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
       if (blue_Y != NULL)
          *blue_Y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+             info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
       if (blue_Z != NULL)
          *blue_Z = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+             info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
       return (PNG_INFO_cHRM);
    }
 
@@ -709,8 +709,8 @@
    png_debug1(1, "in %s retrieval function", "gAMA");
 
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      file_gamma != NULL)
+       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+       file_gamma != NULL)
    {
       *file_gamma = info_ptr->colorspace.gamma;
       return (PNG_INFO_gAMA);
@@ -732,7 +732,7 @@
       file_gamma != NULL)
    {
       *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
-         "png_get_gAMA");
+          "png_get_gAMA");
       return (PNG_INFO_gAMA);
    }
 
@@ -929,7 +929,7 @@
        */
       *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
       *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
-         "sCAL height");
+          "sCAL height");
       return (PNG_INFO_sCAL);
    }
 
@@ -1170,19 +1170,19 @@
       return 0;
 
 #ifdef PNG_WRITE_SUPPORTED
-      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
 #endif
    {
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-         return png_ptr->IDAT_read_size;
+      return png_ptr->IDAT_read_size;
 #else
-         return PNG_IDAT_READ_SIZE;
+      return PNG_IDAT_READ_SIZE;
 #endif
    }
 
 #ifdef PNG_WRITE_SUPPORTED
-      else
-         return png_ptr->zbuffer_size;
+   else
+      return png_ptr->zbuffer_size;
 #endif
 }
 
--- a/src/share/native/sun/awt/libpng/pnginfo.h	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pnginfo.h	Thu May 18 14:30:18 2017 -0700
@@ -30,7 +30,7 @@
  * file and, per its terms, should not be removed:
  *
  * Last changed in libpng 1.6.1 [March 28, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
--- a/src/share/native/sun/awt/libpng/pnglibconf.h	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pnglibconf.h	Thu May 18 14:30:18 2017 -0700
@@ -27,16 +27,15 @@
 /* libpng STANDARD API DEFINITION */
 
 /* pnglibconf.h - library build configuration */
-
 /* This file is available under and governed by the GNU General Public
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  */
 
-/* libpng version 1.6.20, December 3, 2015 */
+/* libpng version 1.6.28, January 5, 2017 */
 
-/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */
+/* Copyright (c) 1998-2016 Glenn Randers-Pehrson */
 
 /* This code is released under the libpng license. */
 /* For conditions of distribution and use, see the disclaimer */
@@ -84,7 +83,7 @@
 #define PNG_READ_BGR_SUPPORTED
 #define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
 #define PNG_READ_COMPOSITE_NODIV_SUPPORTED
-#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
+/*#undef PNG_READ_COMPRESSED_TEXT_SUPPORTED*/
 #define PNG_READ_EXPAND_16_SUPPORTED
 #define PNG_READ_EXPAND_SUPPORTED
 #define PNG_READ_FILLER_SUPPORTED
@@ -116,8 +115,8 @@
 #define PNG_READ_cHRM_SUPPORTED
 #define PNG_READ_gAMA_SUPPORTED
 #define PNG_READ_hIST_SUPPORTED
-#define PNG_READ_iCCP_SUPPORTED
-#define PNG_READ_iTXt_SUPPORTED
+/*#undef PNG_READ_iCCP_SUPPORTED*/
+/*#undef PNG_READ_iTXt_SUPPORTED*/
 #define PNG_READ_oFFs_SUPPORTED
 #define PNG_READ_pCAL_SUPPORTED
 #define PNG_READ_pHYs_SUPPORTED
@@ -128,7 +127,7 @@
 #define PNG_READ_tEXt_SUPPORTED
 #define PNG_READ_tIME_SUPPORTED
 #define PNG_READ_tRNS_SUPPORTED
-#define PNG_READ_zTXt_SUPPORTED
+/*#undef PNG_READ_zTXt_SUPPORTED*/
 /*#undef PNG_SAVE_INT_32_SUPPORTED*/
 #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SEQUENTIAL_READ_SUPPORTED
@@ -141,6 +140,7 @@
 #define PNG_SIMPLIFIED_READ_SUPPORTED
 /*#undef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED*/
 /*#undef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED*/
+/*#undef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED*/
 /*#undef PNG_SIMPLIFIED_WRITE_SUPPORTED*/
 #define PNG_STDIO_SUPPORTED
 #define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
@@ -231,10 +231,10 @@
 #define PNG_QUANTIZE_RED_BITS 5
 #define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
 #define PNG_TEXT_Z_DEFAULT_STRATEGY 0
-#define PNG_USER_CHUNK_CACHE_MAX 0
-#define PNG_USER_CHUNK_MALLOC_MAX 0
-#define PNG_USER_HEIGHT_MAX 1000000
-#define PNG_USER_WIDTH_MAX 1000000
+#define PNG_USER_CHUNK_CACHE_MAX 1000
+#define PNG_USER_CHUNK_MALLOC_MAX 8000000
+#define PNG_USER_HEIGHT_MAX 8000
+#define PNG_USER_WIDTH_MAX 8000
 #define PNG_ZBUF_SIZE 8192
 #define PNG_ZLIB_VERNUM 0
 #define PNG_Z_DEFAULT_COMPRESSION (-1)
--- a/src/share/native/sun/awt/libpng/pngmem.c	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngmem.c	Thu May 18 14:30:18 2017 -0700
@@ -29,8 +29,8 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -94,7 +94,7 @@
  */
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED)
+    PNG_ALLOCATED)
 {
    /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
     * allocators have also been removed in 1.6.0, so any 16-bit system now has
@@ -135,9 +135,9 @@
  */
 static png_voidp
 png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
-   size_t element_size)
+    size_t element_size)
 {
-   png_alloc_size_t req = nelements; /* known to be > 0 */
+   png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
 
    if (req <= PNG_SIZE_MAX/element_size)
       return png_malloc_base(png_ptr, req * element_size);
@@ -148,7 +148,7 @@
 
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_malloc_array,(png_const_structrp png_ptr, int nelements,
-   size_t element_size),PNG_ALLOCATED)
+    size_t element_size),PNG_ALLOCATED)
 {
    if (nelements <= 0 || element_size == 0)
       png_error(png_ptr, "internal error: array alloc");
@@ -158,7 +158,7 @@
 
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
-   int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
+    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
 {
    /* These are internal errors: */
    if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
@@ -171,7 +171,7 @@
    if (add_elements <= INT_MAX - old_elements)
    {
       png_voidp new_array = png_malloc_array_checked(png_ptr,
-         old_elements+add_elements, element_size);
+          old_elements+add_elements, element_size);
 
       if (new_array != NULL)
       {
@@ -182,7 +182,7 @@
             memcpy(new_array, old_array, element_size*(unsigned)old_elements);
 
          memset((char*)new_array + element_size*(unsigned)old_elements, 0,
-            element_size*(unsigned)add_elements);
+             element_size*(unsigned)add_elements);
 
          return new_array;
       }
@@ -215,7 +215,7 @@
 #ifdef PNG_USER_MEM_SUPPORTED
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED PNG_DEPRECATED)
+    PNG_ALLOCATED PNG_DEPRECATED)
 {
    png_voidp ret;
 
@@ -238,7 +238,7 @@
  */
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED)
+    PNG_ALLOCATED)
 {
    if (png_ptr != NULL)
    {
--- a/src/share/native/sun/awt/libpng/pngpread.c	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngpread.c	Thu May 18 14:30:18 2017 -0700
@@ -29,8 +29,8 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -105,11 +105,11 @@
 png_uint_32 PNGAPI
 png_process_data_skip(png_structrp png_ptr)
 {
-  /* TODO: Deprecate and remove this API.
-   * Somewhere the implementation of this seems to have been lost,
-   * or abandoned.  It was only to support some internal back-door access
-   * to png_struct) in libpng-1.4.x.
-   */
+/* TODO: Deprecate and remove this API.
+ * Somewhere the implementation of this seems to have been lost,
+ * or abandoned.  It was only to support some internal back-door access
+ * to png_struct) in libpng-1.4.x.
+ */
    png_app_warning(png_ptr,
 "png_process_data_skip is not implemented in any current version of libpng");
    return 0;
@@ -238,12 +238,14 @@
           (png_ptr->mode & PNG_HAVE_PLTE) == 0)
          png_error(png_ptr, "Missing PLTE before IDAT");
 
-      png_ptr->mode |= PNG_HAVE_IDAT;
       png_ptr->process_mode = PNG_READ_IDAT_MODE;
 
-      if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
-         if (png_ptr->push_length == 0)
-            return;
+      if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+         if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
+            if (png_ptr->push_length == 0)
+               return;
+
+      png_ptr->mode |= PNG_HAVE_IDAT;
 
       if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
          png_benign_error(png_ptr, "Too many IDATs found");
@@ -436,7 +438,7 @@
    {
       PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
-         PNG_HANDLE_CHUNK_AS_DEFAULT);
+          PNG_HANDLE_CHUNK_AS_DEFAULT);
    }
 
    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
@@ -527,7 +529,10 @@
          png_error(png_ptr, "Insufficient memory for save_buffer");
       }
 
-      memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      if (old_buffer)
+         memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      else if (png_ptr->save_buffer_size)
+         png_error(png_ptr, "save_buffer error");
       png_free(png_ptr, old_buffer);
       png_ptr->save_buffer_max = new_max;
    }
@@ -544,7 +549,7 @@
 
 void /* PRIVATE */
 png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
+    png_size_t buffer_length)
 {
    png_ptr->current_buffer = buffer;
    png_ptr->current_buffer_size = buffer_length;
@@ -647,7 +652,7 @@
 
 void /* PRIVATE */
 png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
+    png_size_t buffer_length)
 {
    /* The caller checks for a non-zero buffer length. */
    if (!(buffer_length > 0) || buffer == NULL)
@@ -707,7 +712,12 @@
             png_warning(png_ptr, "Truncated compressed data in IDAT");
 
          else
-            png_error(png_ptr, "Decompression error in IDAT");
+         {
+            if (ret == Z_DATA_ERROR)
+               png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
+            else
+               png_error(png_ptr, "Decompression error in IDAT");
+         }
 
          /* Skip the check on unprocessed input */
          return;
@@ -805,7 +815,7 @@
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
+             png_ptr->transformations);
 
       switch (png_ptr->pass)
       {
@@ -1067,7 +1077,7 @@
 {
    if (png_ptr->row_fn != NULL)
       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
-         (int)png_ptr->pass);
+          (int)png_ptr->pass);
 }
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
--- a/src/share/native/sun/awt/libpng/pngpriv.h	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngpriv.h	Thu May 18 14:30:18 2017 -0700
@@ -29,8 +29,8 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -210,6 +210,35 @@
 #  endif
 #endif /* PNG_ARM_NEON_OPT > 0 */
 
+#ifndef PNG_MIPS_MSA_OPT
+#  if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+#     define PNG_MIPS_MSA_OPT 2
+#  else
+#     define PNG_MIPS_MSA_OPT 0
+#  endif
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
+#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
+#     if defined(__mips_msa)
+#        if defined(__clang__)
+#        elif defined(__GNUC__)
+#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
+#              define PNG_MIPS_MSA_IMPLEMENTATION 2
+#           endif /* no GNUC support */
+#        endif /* __GNUC__ */
+#     else /* !defined __mips_msa */
+#        define PNG_MIPS_MSA_IMPLEMENTATION 2
+#     endif /* __mips_msa */
+#  endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
+
+#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
+#     define PNG_MIPS_MSA_IMPLEMENTATION 1
+#  endif
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+
+
 /* Is this a build of a DLL where compilation of the object modules requires
  * different preprocessor settings to those required for a simple library?  If
  * so PNG_BUILD_DLL must be set.
@@ -448,10 +477,10 @@
 
 #  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
     defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-     /* We need to check that <math.h> hasn't already been included earlier
-      * as it seems it doesn't agree with <fp.h>, yet we should really use
-      * <fp.h> if possible.
-      */
+   /* We need to check that <math.h> hasn't already been included earlier
+    * as it seems it doesn't agree with <fp.h>, yet we should really use
+    * <fp.h> if possible.
+    */
 #    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
 #      include <fp.h>
 #    endif
@@ -459,9 +488,9 @@
 #    include <math.h>
 #  endif
 #  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
-     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
-      * MATH=68881
-      */
+   /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+    * MATH=68881
+    */
 #    include <m68881.h>
 #  endif
 #endif
@@ -532,7 +561,8 @@
 /* This implicitly assumes alignment is always to a power of 2. */
 #ifdef png_alignof
 #  define png_isaligned(ptr, type)\
-   ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
+   (((type)((const char*)ptr-(const char*)0) & \
+   (type)(png_alignof(type)-1)) == 0)
 #else
 #  define png_isaligned(ptr, type) 0
 #endif
@@ -549,92 +579,92 @@
  * are defined in png.h because they need to be visible to applications
  * that call png_set_unknown_chunk().
  */
-/* #define PNG_HAVE_IHDR            0x01 (defined in png.h) */
-/* #define PNG_HAVE_PLTE            0x02 (defined in png.h) */
-#define PNG_HAVE_IDAT               0x04
-/* #define PNG_AFTER_IDAT           0x08 (defined in png.h) */
-#define PNG_HAVE_IEND               0x10
-                   /*               0x20 (unused) */
-                   /*               0x40 (unused) */
-                   /*               0x80 (unused) */
-#define PNG_HAVE_CHUNK_HEADER      0x100
-#define PNG_WROTE_tIME             0x200
-#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
-#define PNG_BACKGROUND_IS_GRAY     0x800
-#define PNG_HAVE_PNG_SIGNATURE    0x1000
-#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
-                   /*             0x4000 (unused) */
-#define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */
+/* #define PNG_HAVE_IHDR            0x01U (defined in png.h) */
+/* #define PNG_HAVE_PLTE            0x02U (defined in png.h) */
+#define PNG_HAVE_IDAT               0x04U
+/* #define PNG_AFTER_IDAT           0x08U (defined in png.h) */
+#define PNG_HAVE_IEND               0x10U
+                   /*               0x20U (unused) */
+                   /*               0x40U (unused) */
+                   /*               0x80U (unused) */
+#define PNG_HAVE_CHUNK_HEADER      0x100U
+#define PNG_WROTE_tIME             0x200U
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
+#define PNG_BACKGROUND_IS_GRAY     0x800U
+#define PNG_HAVE_PNG_SIGNATURE    0x1000U
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
+                   /*             0x4000U (unused) */
+#define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
 
 /* Flags for the transformations the PNG library does on the image data */
-#define PNG_BGR                 0x0001
-#define PNG_INTERLACE           0x0002
-#define PNG_PACK                0x0004
-#define PNG_SHIFT               0x0008
-#define PNG_SWAP_BYTES          0x0010
-#define PNG_INVERT_MONO         0x0020
-#define PNG_QUANTIZE            0x0040
-#define PNG_COMPOSE             0x0080     /* Was PNG_BACKGROUND */
-#define PNG_BACKGROUND_EXPAND   0x0100
-#define PNG_EXPAND_16           0x0200     /* Added to libpng 1.5.2 */
-#define PNG_16_TO_8             0x0400     /* Becomes 'chop' in 1.5.4 */
-#define PNG_RGBA                0x0800
-#define PNG_EXPAND              0x1000
-#define PNG_GAMMA               0x2000
-#define PNG_GRAY_TO_RGB         0x4000
-#define PNG_FILLER              0x8000
-#define PNG_PACKSWAP           0x10000
-#define PNG_SWAP_ALPHA         0x20000
-#define PNG_STRIP_ALPHA        0x40000
-#define PNG_INVERT_ALPHA       0x80000
-#define PNG_USER_TRANSFORM    0x100000
-#define PNG_RGB_TO_GRAY_ERR   0x200000
-#define PNG_RGB_TO_GRAY_WARN  0x400000
-#define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
-#define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */
-#define PNG_ADD_ALPHA        0x1000000 /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS      0x2000000 /* Added to libpng-1.2.9 */
-#define PNG_SCALE_16_TO_8    0x4000000 /* Added to libpng-1.5.4 */
-                       /*    0x8000000 unused */
-                       /*   0x10000000 unused */
-                       /*   0x20000000 unused */
-                       /*   0x40000000 unused */
+#define PNG_BGR                 0x0001U
+#define PNG_INTERLACE           0x0002U
+#define PNG_PACK                0x0004U
+#define PNG_SHIFT               0x0008U
+#define PNG_SWAP_BYTES          0x0010U
+#define PNG_INVERT_MONO         0x0020U
+#define PNG_QUANTIZE            0x0040U
+#define PNG_COMPOSE             0x0080U    /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND   0x0100U
+#define PNG_EXPAND_16           0x0200U    /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8             0x0400U    /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA                0x0800U
+#define PNG_EXPAND              0x1000U
+#define PNG_GAMMA               0x2000U
+#define PNG_GRAY_TO_RGB         0x4000U
+#define PNG_FILLER              0x8000U
+#define PNG_PACKSWAP           0x10000U
+#define PNG_SWAP_ALPHA         0x20000U
+#define PNG_STRIP_ALPHA        0x40000U
+#define PNG_INVERT_ALPHA       0x80000U
+#define PNG_USER_TRANSFORM    0x100000U
+#define PNG_RGB_TO_GRAY_ERR   0x200000U
+#define PNG_RGB_TO_GRAY_WARN  0x400000U
+#define PNG_RGB_TO_GRAY       0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA      0x800000U /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA        0x1000000U /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS      0x2000000U /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8    0x4000000U /* Added to libpng-1.5.4 */
+                       /*    0x8000000U unused */
+                       /*   0x10000000U unused */
+                       /*   0x20000000U unused */
+                       /*   0x40000000U unused */
 /* Flags for png_create_struct */
-#define PNG_STRUCT_PNG   0x0001
-#define PNG_STRUCT_INFO  0x0002
+#define PNG_STRUCT_PNG   0x0001U
+#define PNG_STRUCT_INFO  0x0002U
 
 /* Flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
-#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002 /* Added to libpng-1.6.0 */
-                                  /*      0x0004    unused */
-#define PNG_FLAG_ZSTREAM_ENDED            0x0008 /* Added to libpng-1.6.0 */
-                                  /*      0x0010    unused */
-                                  /*      0x0020    unused */
-#define PNG_FLAG_ROW_INIT                 0x0040
-#define PNG_FLAG_FILLER_AFTER             0x0080
-#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
-#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
-#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
-#define PNG_FLAG_ASSUME_sRGB              0x1000 /* Added to libpng-1.5.4 */
-#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000 /* Added to libpng-1.5.4 */
-#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000 /* Added to libpng-1.5.4 */
-/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000 */
-/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000 */
-#define PNG_FLAG_LIBRARY_MISMATCH        0x20000
-#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000
-#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000
-#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000 /* Added to libpng-1.4.0 */
-#define PNG_FLAG_APP_WARNINGS_WARN      0x200000 /* Added to libpng-1.6.0 */
-#define PNG_FLAG_APP_ERRORS_WARN        0x400000 /* Added to libpng-1.6.0 */
-                                  /*    0x800000    unused */
-                                  /*   0x1000000    unused */
-                                  /*   0x2000000    unused */
-                                  /*   0x4000000    unused */
-                                  /*   0x8000000    unused */
-                                  /*  0x10000000    unused */
-                                  /*  0x20000000    unused */
-                                  /*  0x40000000    unused */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001U
+#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002U /* Added to libpng-1.6.0 */
+                                  /*      0x0004U    unused */
+#define PNG_FLAG_ZSTREAM_ENDED            0x0008U /* Added to libpng-1.6.0 */
+                                  /*      0x0010U    unused */
+                                  /*      0x0020U    unused */
+#define PNG_FLAG_ROW_INIT                 0x0040U
+#define PNG_FLAG_FILLER_AFTER             0x0080U
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100U
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200U
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400U
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800U
+#define PNG_FLAG_ASSUME_sRGB              0x1000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000U /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000U */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000U */
+#define PNG_FLAG_LIBRARY_MISMATCH        0x20000U
+#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000U
+#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000U
+#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000U /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN      0x200000U /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN        0x400000U /* Added to libpng-1.6.0 */
+                                  /*    0x800000U    unused */
+                                  /*   0x1000000U    unused */
+                                  /*   0x2000000U    unused */
+                                  /*   0x4000000U    unused */
+                                  /*   0x8000000U    unused */
+                                  /*  0x10000000U    unused */
+                                  /*  0x20000000U    unused */
+                                  /*  0x40000000U    unused */
 
 #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
                                      PNG_FLAG_CRC_ANCILLARY_NOWARN)
@@ -668,6 +698,24 @@
     ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
     (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
 
+/* This returns the number of trailing bits in the last byte of a row, 0 if the
+ * last byte is completely full of pixels.  It is, in principle, (pixel_bits x
+ * width) % 8, but that would overflow for large 'width'.  The second macro is
+ * the same except that it returns the number of unused bits in the last byte;
+ * (8-TRAILBITS), but 0 when TRAILBITS is 0.
+ *
+ * NOTE: these macros are intended to be self-evidently correct and never
+ * overflow on the assumption that pixel_bits is in the range 0..255.  The
+ * arguments are evaluated only once and they can be signed (e.g. as a result of
+ * the integral promotions).  The result of the expression always has type
+ * (png_uint_32), however the compiler always knows it is in the range 0..7.
+ */
+#define PNG_TRAILBITS(pixel_bits, width) \
+    (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
+
+#define PNG_PADBITS(pixel_bits, width) \
+    ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
+
 /* PNG_OUT_OF_RANGE returns true if value is outside the range
  * ideal-delta..ideal+delta.  Each argument is evaluated twice.
  * "ideal" and "delta" should be constants, normally simple
@@ -1053,7 +1101,7 @@
 #ifdef PNG_WRITE_cHRM_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
     const png_xy *xy), PNG_EMPTY);
-    /* The xy value must have been previously validated */
+   /* The xy value must have been previously validated */
 #endif
 
 #ifdef PNG_WRITE_sRGB_SUPPORTED
@@ -1202,6 +1250,7 @@
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
 
+#if PNG_ARM_NEON_OPT > 0
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
     png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
@@ -1216,6 +1265,24 @@
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
+    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
 
 /* Choose the best filter to use and filter the row data */
 PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
@@ -1243,7 +1310,7 @@
 /* Initialize the row buffers, etc. */
 PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
 
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
 PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
       PNG_EMPTY);
 #  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
@@ -1441,7 +1508,7 @@
 PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
    png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
-     png_bytep row),PNG_EMPTY);
+    png_bytep row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
     png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
@@ -1480,13 +1547,13 @@
 
 PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
     png_inforp info_ptr), PNG_EMPTY);
-    /* Synchronize the info 'valid' flags with the colorspace */
+   /* Synchronize the info 'valid' flags with the colorspace */
 
 PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
     png_inforp info_ptr), PNG_EMPTY);
-    /* Copy the png_struct colorspace to the info_struct and call the above to
-     * synchronize the flags.  Checks for NULL info_ptr and does nothing.
-     */
+   /* Copy the png_struct colorspace to the info_struct and call the above to
+    * synchronize the flags.  Checks for NULL info_ptr and does nothing.
+    */
 #endif
 
 /* Added at libpng version 1.4.0 */
@@ -1520,9 +1587,11 @@
    /* The 'name' is used for information only */
 
 /* Routines for checking parts of an ICC profile. */
+#ifdef PNG_READ_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_charp name,
    png_uint_32 profile_length), PNG_EMPTY);
+#endif /* READ_iCCP */
 PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_charp name,
    png_uint_32 profile_length,
@@ -1941,10 +2010,20 @@
     * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
     * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
     */
+#  if PNG_ARM_NEON_OPT > 0
 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
 #endif
 
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
+   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+#endif
+
+PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
+   png_const_charp key, png_bytep new_key), PNG_EMPTY);
+
 /* Maintainer: Put new private prototypes here ^ */
 
 #include "pngdebug.h"
--- a/src/share/native/sun/awt/libpng/pngread.c	Fri Apr 28 14:28:06 2017 -0700
+++ b/src/share/native/sun/awt/libpng/pngread.c	Thu May 18 14:30:18 2017 -0700
@@ -29,8 +29,8 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -56,10 +56,10 @@
 {
 #ifndef PNG_USER_MEM_SUPPORTED
    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
-      error_fn, warn_fn, NULL, NULL, NULL);
+        error_fn, warn_fn, NULL, NULL, NULL);
 #else
    return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
-       warn_fn, NULL, NULL, NULL);
+        warn_fn, NULL, NULL, NULL);
 }
 
 /* Alternate create PNG structure for reading, and allocate any memory
@@ -71,7 +71,7 @@
     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
 {
    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
-      error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
 #endif /* USER_MEM */
 
    if (png_ptr != NULL)
@@ -155,7 +155,10 @@
       }
 
       else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      {
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
          png_ptr->mode |= PNG_AFTER_IDAT;
+      }
 
       /* This should be a binary subdivision search or a hash for
        * matching the chunk name rather than a linear search.
@@ -277,7 +280,7 @@
 
       else
          png_handle_unknown(png_ptr, info_ptr, length,
-            PNG_HANDLE_CHUNK_AS_DEFAULT);
+             PNG_HANDLE_CHUNK_AS_DEFAULT);
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -304,7 +307,7 @@
       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
       else
          png_app_error(png_ptr,
-            "png_read_update_info/png_start_read_image: duplicate call");
+             "png_read_update_info/png_start_read_image: duplicate call");
    }
 }
 
@@ -327,7 +330,7 @@
       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
       else
          png_app_error(png_ptr,
-            "png_start_read_image/png_read_update_info: duplicate call");
+             "png_start_read_image/png_read_update_info: duplicate call");
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -384,9 +387,9 @@
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 s0   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
             png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
             *(rp    ) = (png_byte)((red >> 8) & 0xff);
@@ -565,7 +568,7 @@
    {
       if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
          png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
-            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
       else
          png_error(png_ptr, "bad adaptive filter value");
    }
@@ -609,7 +612,7 @@
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
+             png_ptr->transformations);
 
       if (dsp_row != NULL)
          png_combine_row(png_ptr, dsp_row, 1/*display*/);
@@ -744,7 +747,7 @@
           * but the caller should do it!
           */
          png_warning(png_ptr, "Interlace handling should be turned on when "
-            "using png_read_image");
+             "using png_read_image");
          /* Make sure this is set correctly */
          png_ptr->num_rows = png_ptr->height;
       }
@@ -804,8 +807,8 @@
 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
    /* Report invalid palette index; added at libng-1.5.10 */
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-      png_ptr->num_palette_max > png_ptr->num_palette)
-     png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+       png_ptr->num_palette_max > png_ptr->num_palette)
+      png_benign_error(png_ptr, "Read palette index exceeding num_palette");
 #endif
 
    do
@@ -813,6 +816,9 @@
       png_uint_32 length = png_read_chunk_header(png_ptr);
       png_uint_32 chunk_name = png_ptr->chunk_name;
 
+      if (chunk_name != png_IDAT)
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
       if (chunk_name == png_IEND)
          png_handle_IEND(png_ptr, info_ptr, length);
 
@@ -827,9 +833,9 @@
       {
          if (chunk_name == png_IDAT)
          {
-            if ((length > 0) ||
-                (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
-               png_benign_error(png_ptr, "Too many IDATs found");
+            if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+                || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+               png_benign_error(png_ptr, ".Too many IDATs found");
          }
          png_handle_unknown(png_ptr, info_ptr, length, keep);
          if (chunk_name == png_PLTE)
@@ -840,10 +846,14 @@
       else if (chunk_name == png_IDAT)
       {
          /* Zero length IDATs are legal after the last IDAT has been
-          * read, but not after other chunks have been read.
+          * read, but not after other chunks have been read.  1.6 does not
+          * always read all the deflate data; specifically it cannot be relied
+          * upon to read the Adler32 at the end.  If it doesn't ignore IDAT
+          * chunks which are longer than zero as well:
           */
-         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
-            png_benign_error(png_ptr, "Too many IDATs found");
+         if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+             || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+            png_benign_error(png_ptr, "..Too many IDATs found");
 
          png_crc_finish(png_ptr, length);
       }
@@ -937,7 +947,7 @@
 
       else
          png_handle_unknown(png_ptr, info_ptr, length,
-            PNG_HANDLE_CHUNK_AS_DEFAULT);
+             PNG_HANDLE_CHUNK_AS_DEFAULT);
    } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
 }
 #endif /* SEQUENTIAL_READ */
@@ -1048,8 +1058,7 @@
 #ifdef PNG_INFO_IMAGE_SUPPORTED
 void PNGAPI
 png_read_png(png_structrp png_ptr, png_inforp info_ptr,
-                           int transforms,
-                           voidp params)
+    int transforms, voidp params)
 {
    if (png_ptr == NULL || info_ptr == NULL)
       return;
@@ -1325,7 +1334,7 @@
          if (info_ptr != NULL)
          {
             png_controlp control = png_voidcast(png_controlp,
-               png_malloc_warn(png_ptr, (sizeof *control)));
+                png_malloc_warn(png_ptr, (sizeof *control)));
 
             if (control != NULL)
             {
@@ -1412,7 +1421,9 @@
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
 
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    png_set_benign_errors(png_ptr, 1/*warn*/);
+#endif
    png_read_info(png_ptr, info_ptr);
 
    /* Do this the fast way; just read directly out of png_struct. */
@@ -1450,7 +1461,7 @@
             break;
 
          case PNG_COLOR_TYPE_PALETTE:
-            cmap_entries = png_ptr->num_palette;
+            cmap_entries = (png_uint_32)png_ptr->num_palette;
             break;
 
          default:
@@ -1488,12 +1499,12 @@
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_stdio: invalid argument");
+             "png_image_begin_read_from_stdio: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1526,12 +1537,12 @@
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_file: invalid argument");
+             "png_image_begin_read_from_file: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1568,7 +1579,7 @@
 }
 
 int PNGAPI png_image_begin_read_from_memory(png_imagep image,
-   png_const_voidp memory, png_size_t size)
+    png_const_voidp memory, png_size_t size)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
@@ -1591,12 +1602,12 @@
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_memory: invalid argument");
+             "png_image_begin_read_from_memory: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1642,12 +1653,12 @@
         * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
         */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
-         NULL, -1);
+           NULL, -1);
 
        /* But do not ignore image data handling chunks */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
-         chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
-    }
+           chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
+   }
 }
 
 #  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
@@ -1714,7 +1725,7 @@
 #ifdef __GNUC__
       default:
          png_error(display->image->opaque->png_ptr,
-            "unexpected encoding (internal error)");
+             "unexpected encoding (internal error)");
 #endif
    }
 
@@ -1723,8 +1734,8 @@
 
 static png_uint_32
 png_colormap_compose(png_image_read_control *display,
-   png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
-   png_uint_32 background, int encoding)
+    png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+    png_uint_32 background, int encoding)
 {
    /* The file value is composed on the background, the background has the given
     * encoding and so does the result, the file is encoded with P_FILE and the
@@ -1760,14 +1771,14 @@
  */
 static void
 png_create_colormap_entry(png_image_read_control *display,
-   png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
-   png_uint_32 alpha, int encoding)
+    png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+    png_uint_32 alpha, int encoding)
 {
    png_imagep image = display->image;
    const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
-      P_LINEAR : P_sRGB;
+       P_LINEAR : P_sRGB;
    const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
-      (red != green || green != blue);
+       (red != green || green != blue);
 
    if (ip > 255)
       png_error(image->opaque->png_ptr, "color-map index out of range");
@@ -1985,7 +1996,7 @@
    for (i=0; i<256; ++i)
       png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
 
-   return i;
+   return (int)i;
 }
 
 static int
@@ -1996,7 +2007,7 @@
    for (i=0; i<256; ++i)
       png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
 
-   return i;
+   return (int)i;
 }
 #define PNG_GRAY_COLORMAP_ENTRIES 256
 
@@ -2047,10 +2058,10 @@
 
       for (g=0; g<6; ++g)
          png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
-            P_sRGB);
+             P_sRGB);
    }
 
-   return i;
+   return (int)i;
 }
 
 #define PNG_GA_COLORMAP_ENTRIES 256
@@ -2071,11 +2082,11 @@
 
          for (b=0; b<6; ++b)
             png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
-               P_sRGB);
+                P_sRGB);
       }
    }
 
-   return i;
+   return (int)i;
 }
 
 #define PNG_RGB_COLORMAP_ENTRIES 216
@@ -2123,7 +2134,7 @@
 
       else if (display->background == NULL /* no way to remove it */)
          png_error(png_ptr,
-            "a background color must be supplied to remove alpha/transparency");
+             "background color must be supplied to remove alpha/transparency");
 
       /* Get a copy of the background color (this avoids repeating the checks
        * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
@@ -2218,7 +2229,7 @@
                 */
                if (i != trans)
                   png_create_colormap_entry(display, i, val, val, val, 255,
-                     P_FILE/*8-bit with file gamma*/);
+                      P_FILE/*8-bit with file gamma*/);
 
                /* Else this entry is transparent.  The colors don't matter if
                 * there is an alpha channel (back_alpha == 0), but it does no
@@ -2230,7 +2241,7 @@
                 */
                else
                   png_create_colormap_entry(display, i, back_r, back_g, back_b,
-                     back_alpha, output_encoding);
+                      back_alpha, output_encoding);
             }
 
             /* We need libpng to preserve the original encoding. */
@@ -2268,7 +2279,7 @@
             if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray[16] color-map: too few entries");
 
-            cmap_entries = make_gray_colormap(display);
+            cmap_entries = (unsigned int)make_gray_colormap(display);
 
             if (png_ptr->num_trans > 0)
             {
@@ -2295,7 +2306,7 @@
                          * matches.
                          */
                         png_create_colormap_entry(display, gray, back_g, back_g,
-                           back_g, 65535, P_LINEAR);
+                            back_g, 65535, P_LINEAR);
                      }
 
                      /* The background passed to libpng, however, must be the
@@ -2309,8 +2320,8 @@
                       * doesn't.
                       */
                      png_set_background_fixed(png_ptr, &c,
-                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                        0/*gamma: not used*/);
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_NONE;
                      break;
@@ -2340,7 +2351,7 @@
                 * background color at full precision.
                 */
                png_create_colormap_entry(display, 254, back_r, back_g, back_b,
-                  back_alpha, output_encoding);
+                   back_alpha, output_encoding);
             }
 
             else
@@ -2366,7 +2377,7 @@
             if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray+alpha color-map: too few entries");
 
-            cmap_entries = make_ga_colormap(display);
+            cmap_entries = (unsigned int)make_ga_colormap(display);
 
             background_index = PNG_CMAP_GA_BACKGROUND;
             output_processing = PNG_CMAP_GA;
@@ -2400,7 +2411,7 @@
                if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "gray-alpha color-map: too few entries");
 
-               cmap_entries = make_gray_colormap(display);
+               cmap_entries = (unsigned int)make_gray_colormap(display);
 
                if (output_encoding == P_LINEAR)
                {
@@ -2408,7 +2419,7 @@
 
                   /* And make sure the corresponding palette entry matches. */
                   png_create_colormap_entry(display, gray, back_g, back_g,
-                     back_g, 65535, P_LINEAR);
+                      back_g, 65535, P_LINEAR);
                }
 
                /* The background passed to libpng, however, must be the sRGB
@@ -2418,8 +2429,8 @@
                c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
 
                png_set_background_fixed(png_ptr, &c,
-                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                  0/*gamma: not used*/);
+                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                   0/*gamma: not used*/);
 
                output_processing = PNG_CMAP_NONE;
             }
@@ -2439,7 +2450,7 @@
                {
                   png_uint_32 gray = (i * 256 + 115) / 231;
                   png_create_colormap_entry(display, i++, gray, gray, gray,
-                     255, P_sRGB);
+                      255, P_sRGB);
                }
 
                /* NOTE: this preserves the full precision of the application
@@ -2448,13 +2459,13 @@
                background_index = i;
                png_create_colormap_entry(display, i++, back_r, back_g, back_b,
 #ifdef __COVERITY__
-                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
-                  * here.
-                  */ 255U,
+                   /* Coverity claims that output_encoding
+                    * cannot be 2 (P_LINEAR) here.
+                    */ 255U,
 #else
-                  output_encoding == P_LINEAR ? 65535U : 255U,
+                    output_encoding == P_LINEAR ? 65535U : 255U,
 #endif
-                  output_encoding);
+                    output_encoding);
 
                /* For non-opaque input composite on the sRGB background - this
                 * requires inverting the encoding for each component.  The input
@@ -2492,9 +2503,9 @@
                      png_uint_32 gray = png_sRGB_table[g*51] * alpha;
 
                      png_create_colormap_entry(display, i++,
-                        PNG_sRGB_FROM_LINEAR(gray + back_rx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_gx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+                         PNG_sRGB_FROM_LINEAR(gray + back_rx),
+                         PNG_sRGB_FROM_LINEAR(gray + back_gx),
+                         PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
                   }
                }
 
@@ -2520,7 +2531,7 @@
              * png_set_tRNS_to_alpha before png_set_background_fixed.
              */
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
-               -1);
+                -1);
             data_encoding = P_sRGB;
 
             /* The output will now be one or two 8-bit gray or gray+alpha
@@ -2539,7 +2550,7 @@
                if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "rgb[ga] color-map: too few entries");
 
-               cmap_entries = make_ga_colormap(display);
+               cmap_entries = (unsigned int)make_ga_colormap(display);
                background_index = PNG_CMAP_GA_BACKGROUND;
                output_processing = PNG_CMAP_GA;
             }
@@ -2565,12 +2576,12 @@
                   png_ptr->num_trans > 0) &&
                   png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
                {
-                  cmap_entries = make_gray_file_colormap(display);
+                  cmap_entries = (unsigned int)make_gray_file_colormap(display);
                   data_encoding = P_FILE;
                }
 
                else
-                  cmap_entries = make_gray_colormap(display);
+                  cmap_entries = (unsigned int)make_gray_colormap(display);
 
                /* But if the input has alpha or transparency it must be removed
                 */
@@ -2596,13 +2607,13 @@
                         gray = png_sRGB_table[gray]; /* now P_LINEAR */
 
                      gray = PNG_DIV257(png_gamma_16bit_correct(gray,
-                        png_ptr->colorspace.gamma)); /* now P_FILE */
+                         png_ptr->colorspace.gamma)); /* now P_FILE */
 
                      /* And make sure the corresponding palette entry contains
                       * exactly the required sRGB value.
                       */
                      png_create_colormap_entry(display, gray, back_g, back_g,
-                        back_g, 0/*unused*/, output_encoding);
+                         back_g, 0/*unused*/, output_encoding);
                   }
 
                   else if (output_encoding == P_LINEAR)
@@ -2627,8 +2638,8 @@
                    */
                   expand_tRNS = 1;
                   png_set_background_fixed(png_ptr, &c,
-                     PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                     0/*gamma: not used*/);
+                      PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                      0/*gamma: not used*/);
                }
 
                output_processing = PNG_CMAP_NONE;
@@ -2658,11 +2669,11 @@
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb+alpha color-map: too few entries");
 
-                  cmap_entries = make_rgb_colormap(display);
+                  cmap_entries = (unsigned int)make_rgb_colormap(display);
 
                   /* Add a transparent entry. */
                   png_create_colormap_entry(display, cmap_entries, 255, 255,
-                     255, 0, P_sRGB);
+                      255, 0, P_sRGB);
 
                   /* This is stored as the background index for the processing
                    * algorithm.
@@ -2683,7 +2694,7 @@
                          */
                         for (b=0; b<256; b = (b << 1) | 0x7f)
                            png_create_colormap_entry(display, cmap_entries++,
-                              r, g, b, 128, P_sRGB);
+                               r, g, b, 128, P_sRGB);
                      }
                   }
 
@@ -2707,10 +2718,10 @@
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb-alpha color-map: too few entries");
 
-                  cmap_entries = make_rgb_colormap(display);
+                  cmap_entries = (unsigned int)make_rgb_colormap(display);
 
                   png_create_colormap_entry(display, cmap_entries, back_r,
-                        back_g, back_b, 0/*unused*/, output_encoding);
+                      back_g, back_b, 0/*unused*/, output_encoding);
 
                   if (output_encoding == P_LINEAR)
                   {
@@ -2732,9 +2743,9 @@
                    * index.
                    */
                   if (memcmp((png_const_bytep)display->colormap +
-                        sample_size * cmap_entries,
-                     (png_const_bytep)display->colormap +
-                        sample_size * PNG_RGB_INDEX(r,g,b),
+                      sample_size * cmap_entries,
+                      (png_const_bytep)display->colormap +
+                          sample_size * PNG_RGB_INDEX(r,g,b),
                      sample_size) != 0)
                   {
                      /* The background color must be added. */
@@ -2752,13 +2763,13 @@
                             */
                            for (b=0; b<256; b = (b << 1) | 0x7f)
                               png_create_colormap_entry(display, cmap_entries++,
-                                 png_colormap_compose(display, r, P_sRGB, 128,
-                                    back_r, output_encoding),
-                                 png_colormap_compose(display, g, P_sRGB, 128,
-                                    back_g, output_encoding),
-                                 png_colormap_compose(display, b, P_sRGB, 128,
-                                    back_b, output_encoding),
-                                 0/*unused*/, output_encoding);
+                                  png_colormap_compose(display, r, P_sRGB, 128,
+                                      back_r, output_encoding),
+                                  png_colormap_compose(display, g, P_sRGB, 128,
+                                      back_g, output_encoding),
+                                  png_colormap_compose(display, b, P_sRGB, 128,
+                                      back_b, output_encoding),
+                                  0/*unused*/, output_encoding);
                         }
                      }
 
@@ -2776,8 +2787,8 @@
                      c.blue = (png_uint_16)back_b;
 
                      png_set_background_fixed(png_ptr, &c,
-                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                        0/*gamma: not used*/);
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_RGB;
                   }
@@ -2792,7 +2803,7 @@
                if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "rgb color-map: too few entries");
 
-               cmap_entries = make_rgb_colormap(display);
+               cmap_entries = (unsigned int)make_rgb_colormap(display);
                output_processing = PNG_CMAP_RGB;
             }
          }
@@ -2816,11 +2827,11 @@
 
             output_processing = PNG_CMAP_NONE;
             data_encoding = P_FILE; /* Don't change from color-map indices */
-            cmap_entries = png_ptr->num_palette;
+            cmap_entries = (unsigned int)png_ptr->num_palette;
             if (cmap_entries > 256)
                cmap_entries = 256;
 
-            if (cmap_entries > image->colormap_entries)
+            if (cmap_entries > (unsigned int)image->colormap_entries)
                png_error(png_ptr, "palette color-map: too few entries");
 
             for (i=0; i < cmap_entries; ++i)
@@ -2829,7 +2840,7 @@
                {
                   if (trans[i] == 0)
                      png_create_colormap_entry(display, i, back_r, back_g,
-                        back_b, 0, output_encoding);
+                         back_b, 0, output_encoding);
 
                   else
                   {
@@ -2837,22 +2848,22 @@
                       * on the sRGB color in 'back'.
                       */
                      png_create_colormap_entry(display, i,
-                        png_colormap_compose(display, colormap[i].red, P_FILE,
-                           trans[i], back_r, output_encoding),
-                        png_colormap_compose(display, colormap[i].green, P_FILE,
-                           trans[i], back_g, output_encoding),
-                        png_colormap_compose(display, colormap[i].blue, P_FILE,
-                           trans[i], back_b, output_encoding),
-                        output_encoding == P_LINEAR ? trans[i] * 257U :
-                           trans[i],
-                        output_encoding);
+                         png_colormap_compose(display, colormap[i].red,
+                             P_FILE, trans[i], back_r, output_encoding),
+                         png_colormap_compose(display, colormap[i].green,
+                             P_FILE, trans[i], back_g, output_encoding),
+                         png_colormap_compose(display, colormap[i].blue,
+                             P_FILE, trans[i], back_b, output_encoding),
+                         output_encoding == P_LINEAR ? trans[i] * 257U :
+                             trans[i],
+                         output_encoding);
                   }
                }
 
                else
                   png_create_colormap_entry(display, i, colormap[i].red,
-                     colormap[i].green, colormap[i].blue,
-                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+                      colormap[i].green, colormap[i].blue,
+                      i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
             }
 
             /* The PNG data may have indices packed in fewer than 8 bits, it
@@ -2932,7 +2943,7 @@
          png_error(png_ptr, "bad background index (internal error)");
    }
 
-   display->colormap_processing = output_processing;
+   display->colormap_processing = (int)output_processing;
 
    return 1/*ok*/;
 }
@@ -2942,7 +2953,7 @@
 png_image_read_and_map(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    int passes;
@@ -3079,7 +3090,7 @@
 
                      if (alpha >= 196)
                         *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
-                           inrow[2]);
+                            inrow[2]);
 
                      else if (alpha < 64)
                         *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
@@ -3131,7 +3142,7 @@
 png_image_read_colormapped(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_controlp control = image->opaque;
    png_structrp png_ptr = control->png_ptr;
@@ -3241,14 +3252,14 @@
 
    else
    {
-      png_alloc_size_t row_bytes = display->row_bytes;
+      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
 
       while (--passes >= 0)
       {
          png_uint_32      y = image->height;
          png_bytep        row = png_voidcast(png_bytep, display->first_row);
 
-         while (y-- > 0)
+         for (; y > 0; --y)
          {
             png_read_row(png_ptr, row, NULL);
             row += row_bytes;
@@ -3264,7 +3275,7 @@
 png_image_read_composite(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    int passes;
@@ -3391,7 +3402,7 @@
 png_image_read_background(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -3451,8 +3462,7 @@
 
             for (pass = 0; pass < passes; ++pass)
             {
-               png_bytep        row = png_voidcast(png_bytep,
-                                                   display->first_row);
+               png_bytep row = png_voidcast(png_bytep, display->first_row);
                unsigned int     startx, stepx, stepy;
                png_uint_32      y;
 
@@ -3480,7 +3490,7 @@
                   for (; y<height; y += stepy)
                   {
                      png_bytep inrow = png_voidcast(png_bytep,
-                        display->local_row);
+                         display->local_row);
                      png_bytep outrow = first_row + y * step_row;
                      png_const_bytep end_row = outrow + width;
 
@@ -3525,7 +3535,7 @@
                   for (; y<height; y += stepy)
                   {
                      png_bytep inrow = png_voidcast(png_bytep,
-                        display->local_row);
+                         display->local_row);
                      png_bytep outrow = first_row + y * step_row;
                      png_const_bytep end_row = outrow + width;
 
@@ -3572,13 +3582,14 @@
           */
          {
             png_uint_16p first_row = png_voidcast(png_uint_16p,
-               display->first_row);
+                display->first_row);
             /* The division by two is safe because the caller passed in a
              * stride which was multiplied by 2 (below) to get row_bytes.
              */
             ptrdiff_t    step_row = display->row_bytes / 2;
-            int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
-            unsigned int outchannels = 1+preserve_alpha;
+            unsigned int preserve_alpha = (image->format &
+                PNG_FORMAT_FLAG_ALPHA) != 0;
+            unsigned int outchannels = 1U+preserve_alpha;
             int swap_alpha = 0;
 
 #           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
@@ -3622,7 +3633,7 @@
 
                   /* Read the row, which is packed: */
                   png_read_row(png_ptr, png_voidcast(png_bytep,
-                     display->local_row), NULL);
+                      display->local_row), NULL);
                   inrow = png_voidcast(png_const_uint_16p, display->local_row);
 
                   /* Now do the pre-multiplication on each pixel in this row.
@@ -3671,7 +3682,7 @@
 png_image_read_direct(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -3722,7 +3733,7 @@
                do_local_background = 1/*maybe*/;
 
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
-               PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+                PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
          }
 
          change &= ~PNG_FORMAT_FLAG_COLOR;
@@ -3781,7 +3792,7 @@
           * final value.
           */
          if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
-               PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+             PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
             do_local_background = 0;
 
          else if (mode == PNG_ALPHA_STANDARD)
@@ -3844,8 +3855,8 @@
                 * pixels.
                 */
                png_set_background_fixed(png_ptr, &c,
-                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                  0/*gamma: not used*/);
+                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                   0/*gamma: not used*/);
             }
 
             else /* compose on row: implemented below. */
@@ -3876,16 +3887,16 @@
             else
                filler = 255;
 
-#           ifdef PNG_FORMAT_AFIRST_SUPPORTED
-               if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
-               {
-                  where = PNG_FILLER_BEFORE;
-                  change &= ~PNG_FORMAT_FLAG_AFIRST;
-               }
-
-               else
-#           endif
-               where = PNG_FILLER_AFTER;
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+            if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+            {
+               where = PNG_FILLER_BEFORE;
+               change &= ~PNG_FORMAT_FLAG_AFIRST;
+            }
+
+            else
+#endif
+            where = PNG_FILLER_AFTER;
 
             png_set_add_alpha(png_ptr, filler, where);
          }
@@ -3993,12 +4004,12 @@
       if (info_ptr->bit_depth == 16)
          info_format |= PNG_FORMAT_FLAG_LINEAR;
 
-#     ifdef PNG_FORMAT_BGR_SUPPORTED
-         if ((png_ptr->transformations & PNG_BGR) != 0)
-            info_format |= PNG_FORMAT_FLAG_BGR;
-#     endif
-
-#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+      if ((png_ptr->transformations & PNG_BGR) != 0)
+         info_format |= PNG_FORMAT_FLAG_BGR;
+#endif
+
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
          if (do_local_background == 2)
          {
             if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
@@ -4075,14 +4086,14 @@