Path: blob/master/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java
41154 views
/*1* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.*;24import java.math.BigInteger;25import java.security.*;26import java.security.cert.*;27import java.time.*;28import java.util.*;29import javax.net.ssl.*;30import sun.security.validator.Validator;31import sun.security.validator.ValidatorException;3233import jdk.test.lib.security.SecurityUtils;3435/**36* @test37* @bug 8207258 821628038* @summary Check that TLS Server certificates chaining back to distrusted39* Symantec roots are invalid40* @library /test/lib41* @modules java.base/sun.security.validator42* @run main/othervm Distrust after policyOn invalid43* @run main/othervm Distrust after policyOff valid44* @run main/othervm Distrust before policyOn valid45* @run main/othervm Distrust before policyOff valid46*/4748public class Distrust {4950private static final String TEST_SRC = System.getProperty("test.src", ".");51private static CertificateFactory cf;5253// Each of the roots have a test certificate chain stored in a file54// named "<root>-chain.pem".55private static String[] rootsToTest = new String[] {56"geotrustglobalca", "geotrustprimarycag2", "geotrustprimarycag3",57"geotrustuniversalca", "thawteprimaryrootca", "thawteprimaryrootcag2",58"thawteprimaryrootcag3", "verisignclass3g3ca", "verisignclass3g4ca",59"verisignclass3g5ca", "verisignuniversalrootca" };6061// Each of the subCAs with a delayed distrust date have a test certificate62// chain stored in a file named "<subCA>-chain.pem".63private static String[] subCAsToTest = new String[] {64"appleistca2g1", "appleistca8g1" };6566// A date that is after the restrictions take affect67private static final Date APRIL_17_2019 =68Date.from(LocalDate.of(2019, 4, 17)69.atStartOfDay(ZoneOffset.UTC)70.toInstant());7172// A date that is a second before the restrictions take affect73private static final Date BEFORE_APRIL_17_2019 =74Date.from(LocalDate.of(2019, 4, 17)75.atStartOfDay(ZoneOffset.UTC)76.minusSeconds(1)77.toInstant());7879// A date that is after the subCA restrictions take affect80private static final Date JANUARY_1_2020 =81Date.from(LocalDate.of(2020, 1, 1)82.atStartOfDay(ZoneOffset.UTC)83.toInstant());8485// A date that is a second before the subCA restrictions take affect86private static final Date BEFORE_JANUARY_1_2020 =87Date.from(LocalDate.of(2020, 1, 1)88.atStartOfDay(ZoneOffset.UTC)89.minusSeconds(1)90.toInstant());9192public static void main(String[] args) throws Exception {9394cf = CertificateFactory.getInstance("X.509");9596boolean before = args[0].equals("before");97boolean policyOn = args[1].equals("policyOn");98boolean isValid = args[2].equals("valid");99100if (!policyOn) {101// disable policy (default is on)102Security.setProperty("jdk.security.caDistrustPolicies", "");103}104105Date notBefore = before ? BEFORE_APRIL_17_2019 : APRIL_17_2019;106107X509TrustManager pkixTM = getTMF("PKIX", null);108X509TrustManager sunX509TM = getTMF("SunX509", null);109for (String test : rootsToTest) {110System.err.println("Testing " + test);111X509Certificate[] chain = loadCertificateChain(test);112113testTM(sunX509TM, chain, notBefore, isValid);114testTM(pkixTM, chain, notBefore, isValid);115}116117// test chain if params are passed to TrustManager118System.err.println("Testing verisignuniversalrootca with params");119testTM(getTMF("PKIX", getParams()),120loadCertificateChain("verisignuniversalrootca"),121notBefore, isValid);122123// test code-signing chain (should be valid as restrictions don't apply)124System.err.println("Testing verisignclass3g5ca code-signing chain");125Validator v = Validator.getInstance(Validator.TYPE_PKIX,126Validator.VAR_CODE_SIGNING,127getParams());128// set validation date so this will still pass when cert expires129v.setValidationDate(new Date(1544197375493l));130v.validate(loadCertificateChain("verisignclass3g5ca-codesigning"));131132// test chains issued through subCAs133notBefore = before ? BEFORE_JANUARY_1_2020 : JANUARY_1_2020;134for (String test : subCAsToTest) {135System.err.println("Testing " + test);136X509Certificate[] chain = loadCertificateChain(test);137138testTM(sunX509TM, chain, notBefore, isValid);139testTM(pkixTM, chain, notBefore, isValid);140}141}142143private static X509TrustManager getTMF(String type,144PKIXBuilderParameters params) throws Exception {145TrustManagerFactory tmf = TrustManagerFactory.getInstance(type);146if (params == null) {147tmf.init((KeyStore)null);148} else {149tmf.init(new CertPathTrustManagerParameters(params));150}151TrustManager[] tms = tmf.getTrustManagers();152for (TrustManager tm : tms) {153X509TrustManager xtm = (X509TrustManager)tm;154return xtm;155}156throw new Exception("No TrustManager for " + type);157}158159private static PKIXBuilderParameters getParams() throws Exception {160PKIXBuilderParameters pbp =161new PKIXBuilderParameters(SecurityUtils.getCacertsKeyStore(),162new X509CertSelector());163pbp.setRevocationEnabled(false);164return pbp;165}166167private static void testTM(X509TrustManager xtm, X509Certificate[] chain,168Date notBefore, boolean valid) throws Exception {169// Check if TLS Server certificate (the first element of the chain)170// is issued after the specified notBefore date (should be rejected171// unless distrust property is false). To do this, we need to172// fake the notBefore date since none of the test certs are issued173// after then.174chain[0] = new DistrustedTLSServerCert(chain[0], notBefore);175176try {177xtm.checkServerTrusted(chain, "ECDHE_RSA");178if (!valid) {179throw new Exception("chain should be invalid");180}181} catch (CertificateException ce) {182if (valid) {183throw new Exception("Unexpected exception, chain " +184"should be valid", ce);185}186if (ce instanceof ValidatorException) {187ValidatorException ve = (ValidatorException)ce;188if (ve.getErrorType() != ValidatorException.T_UNTRUSTED_CERT) {189throw new Exception("Unexpected exception: " + ce);190}191} else {192throw new Exception("Unexpected exception: " + ce);193}194}195}196197private static X509Certificate[] loadCertificateChain(String name)198throws Exception {199try (InputStream in = new FileInputStream(TEST_SRC + File.separator +200name + "-chain.pem")) {201Collection<X509Certificate> certs =202(Collection<X509Certificate>)cf.generateCertificates(in);203return certs.toArray(new X509Certificate[0]);204}205}206207private static class DistrustedTLSServerCert extends X509Certificate {208private final X509Certificate cert;209private final Date notBefore;210DistrustedTLSServerCert(X509Certificate cert, Date notBefore) {211this.cert = cert;212this.notBefore = notBefore;213}214public Set<String> getCriticalExtensionOIDs() {215return cert.getCriticalExtensionOIDs();216}217public byte[] getExtensionValue(String oid) {218return cert.getExtensionValue(oid);219}220public Set<String> getNonCriticalExtensionOIDs() {221return cert.getNonCriticalExtensionOIDs();222}223public boolean hasUnsupportedCriticalExtension() {224return cert.hasUnsupportedCriticalExtension();225}226public void checkValidity() throws CertificateExpiredException,227CertificateNotYetValidException {228// always pass229}230public void checkValidity(Date date) throws CertificateExpiredException,231CertificateNotYetValidException {232// always pass233}234public int getVersion() { return cert.getVersion(); }235public BigInteger getSerialNumber() { return cert.getSerialNumber(); }236public Principal getIssuerDN() { return cert.getIssuerDN(); }237public Principal getSubjectDN() { return cert.getSubjectDN(); }238public Date getNotBefore() { return notBefore; }239public Date getNotAfter() { return cert.getNotAfter(); }240public byte[] getTBSCertificate() throws CertificateEncodingException {241return cert.getTBSCertificate();242}243public byte[] getSignature() { return cert.getSignature(); }244public String getSigAlgName() { return cert.getSigAlgName(); }245public String getSigAlgOID() { return cert.getSigAlgOID(); }246public byte[] getSigAlgParams() { return cert.getSigAlgParams(); }247public boolean[] getIssuerUniqueID() {248return cert.getIssuerUniqueID();249}250public boolean[] getSubjectUniqueID() {251return cert.getSubjectUniqueID();252}253public boolean[] getKeyUsage() { return cert.getKeyUsage(); }254public int getBasicConstraints() { return cert.getBasicConstraints(); }255public byte[] getEncoded() throws CertificateEncodingException {256return cert.getEncoded();257}258public void verify(PublicKey key) throws CertificateException,259InvalidKeyException, NoSuchAlgorithmException,260NoSuchProviderException, SignatureException {261cert.verify(key);262}263public void verify(PublicKey key, String sigProvider) throws264CertificateException, InvalidKeyException, NoSuchAlgorithmException,265NoSuchProviderException, SignatureException {266cert.verify(key, sigProvider);267}268public PublicKey getPublicKey() { return cert.getPublicKey(); }269public String toString() { return cert.toString(); }270}271}272273274