Path: blob/master/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java
66646 views
/*1* Copyright (c) 2018, 2022, 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"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[]{"appleistca8g1"};6465// A date that is after the restrictions take affect66private static final Date APRIL_17_2019 =67Date.from(LocalDate.of(2019, 4, 17)68.atStartOfDay(ZoneOffset.UTC)69.toInstant());7071// A date that is a second before the restrictions take affect72private static final Date BEFORE_APRIL_17_2019 =73Date.from(LocalDate.of(2019, 4, 17)74.atStartOfDay(ZoneOffset.UTC)75.minusSeconds(1)76.toInstant());7778// A date that is after the subCA restrictions take affect79private static final Date JANUARY_1_2020 =80Date.from(LocalDate.of(2020, 1, 1)81.atStartOfDay(ZoneOffset.UTC)82.toInstant());8384// A date that is a second before the subCA restrictions take affect85private static final Date BEFORE_JANUARY_1_2020 =86Date.from(LocalDate.of(2020, 1, 1)87.atStartOfDay(ZoneOffset.UTC)88.minusSeconds(1)89.toInstant());9091public static void main(String[] args) throws Exception {9293cf = CertificateFactory.getInstance("X.509");9495boolean before = args[0].equals("before");96boolean policyOn = args[1].equals("policyOn");97boolean isValid = args[2].equals("valid");9899if (!policyOn) {100// disable policy (default is on)101Security.setProperty("jdk.security.caDistrustPolicies", "");102}103104Date notBefore = before ? BEFORE_APRIL_17_2019 : APRIL_17_2019;105106X509TrustManager pkixTM = getTMF("PKIX", null);107X509TrustManager sunX509TM = getTMF("SunX509", null);108for (String test : rootsToTest) {109System.err.println("Testing " + test);110X509Certificate[] chain = loadCertificateChain(test);111112testTM(sunX509TM, chain, notBefore, isValid);113testTM(pkixTM, chain, notBefore, isValid);114}115116// test chain if params are passed to TrustManager117System.err.println("Testing verisignuniversalrootca with params");118testTM(getTMF("PKIX", getParams()),119loadCertificateChain("verisignuniversalrootca"),120notBefore, isValid);121122// test code-signing chain (should be valid as restrictions don't apply)123System.err.println("Testing verisignclass3g5ca code-signing chain");124Validator v = Validator.getInstance(Validator.TYPE_PKIX,125Validator.VAR_CODE_SIGNING,126getParams());127// set validation date so this will still pass when cert expires128v.setValidationDate(new Date(1544197375493l));129v.validate(loadCertificateChain("verisignclass3g5ca-codesigning"));130131// test chains issued through subCAs132notBefore = before ? BEFORE_JANUARY_1_2020 : JANUARY_1_2020;133for (String test : subCAsToTest) {134System.err.println("Testing " + test);135X509Certificate[] chain = loadCertificateChain(test);136137testTM(sunX509TM, chain, notBefore, isValid);138testTM(pkixTM, chain, notBefore, isValid);139}140}141142private static X509TrustManager getTMF(String type,143PKIXBuilderParameters params) throws Exception {144TrustManagerFactory tmf = TrustManagerFactory.getInstance(type);145if (params == null) {146tmf.init((KeyStore)null);147} else {148tmf.init(new CertPathTrustManagerParameters(params));149}150TrustManager[] tms = tmf.getTrustManagers();151for (TrustManager tm : tms) {152X509TrustManager xtm = (X509TrustManager)tm;153return xtm;154}155throw new Exception("No TrustManager for " + type);156}157158private static PKIXBuilderParameters getParams() throws Exception {159PKIXBuilderParameters pbp =160new PKIXBuilderParameters(SecurityUtils.getCacertsKeyStore(),161new X509CertSelector());162pbp.setRevocationEnabled(false);163return pbp;164}165166private static void testTM(X509TrustManager xtm, X509Certificate[] chain,167Date notBefore, boolean valid) throws Exception {168// Check if TLS Server certificate (the first element of the chain)169// is issued after the specified notBefore date (should be rejected170// unless distrust property is false). To do this, we need to171// fake the notBefore date since none of the test certs are issued172// after then.173chain[0] = new DistrustedTLSServerCert(chain[0], notBefore);174175try {176xtm.checkServerTrusted(chain, "ECDHE_RSA");177if (!valid) {178throw new Exception("chain should be invalid");179}180} catch (CertificateException ce) {181// expired TLS certificates should not be treated as failure182if (expired(ce)) {183System.err.println("Test is N/A, chain is expired");184return;185}186if (valid) {187throw new Exception("Unexpected exception, chain " +188"should be valid", ce);189}190if (ce instanceof ValidatorException) {191ValidatorException ve = (ValidatorException)ce;192if (ve.getErrorType() != ValidatorException.T_UNTRUSTED_CERT) {193ce.printStackTrace(System.err);194throw new Exception("Unexpected exception: " + ce);195}196} else {197throw new Exception("Unexpected exception: " + ce);198}199}200}201202// check if a cause of exception is an expired cert203private static boolean expired(CertificateException ce) {204if (ce instanceof CertificateExpiredException) {205return true;206}207Throwable t = ce.getCause();208while (t != null) {209if (t instanceof CertificateExpiredException) {210return true;211}212t = t.getCause();213}214return false;215}216217private static X509Certificate[] loadCertificateChain(String name)218throws Exception {219try (InputStream in = new FileInputStream(TEST_SRC + File.separator +220name + "-chain.pem")) {221Collection<X509Certificate> certs =222(Collection<X509Certificate>)cf.generateCertificates(in);223return certs.toArray(new X509Certificate[0]);224}225}226227private static class DistrustedTLSServerCert extends X509Certificate {228private final X509Certificate cert;229private final Date notBefore;230DistrustedTLSServerCert(X509Certificate cert, Date notBefore) {231this.cert = cert;232this.notBefore = notBefore;233}234public Set<String> getCriticalExtensionOIDs() {235return cert.getCriticalExtensionOIDs();236}237public byte[] getExtensionValue(String oid) {238return cert.getExtensionValue(oid);239}240public Set<String> getNonCriticalExtensionOIDs() {241return cert.getNonCriticalExtensionOIDs();242}243public boolean hasUnsupportedCriticalExtension() {244return cert.hasUnsupportedCriticalExtension();245}246public void checkValidity() throws CertificateExpiredException,247CertificateNotYetValidException {248// always pass249}250public void checkValidity(Date date) throws CertificateExpiredException,251CertificateNotYetValidException {252// always pass253}254public int getVersion() { return cert.getVersion(); }255public BigInteger getSerialNumber() { return cert.getSerialNumber(); }256public Principal getIssuerDN() { return cert.getIssuerDN(); }257public Principal getSubjectDN() { return cert.getSubjectDN(); }258public Date getNotBefore() { return notBefore; }259public Date getNotAfter() { return cert.getNotAfter(); }260public byte[] getTBSCertificate() throws CertificateEncodingException {261return cert.getTBSCertificate();262}263public byte[] getSignature() { return cert.getSignature(); }264public String getSigAlgName() { return cert.getSigAlgName(); }265public String getSigAlgOID() { return cert.getSigAlgOID(); }266public byte[] getSigAlgParams() { return cert.getSigAlgParams(); }267public boolean[] getIssuerUniqueID() {268return cert.getIssuerUniqueID();269}270public boolean[] getSubjectUniqueID() {271return cert.getSubjectUniqueID();272}273public boolean[] getKeyUsage() { return cert.getKeyUsage(); }274public int getBasicConstraints() { return cert.getBasicConstraints(); }275public byte[] getEncoded() throws CertificateEncodingException {276return cert.getEncoded();277}278public void verify(PublicKey key) throws CertificateException,279InvalidKeyException, NoSuchAlgorithmException,280NoSuchProviderException, SignatureException {281cert.verify(key);282}283public void verify(PublicKey key, String sigProvider) throws284CertificateException, InvalidKeyException, NoSuchAlgorithmException,285NoSuchProviderException, SignatureException {286cert.verify(key, sigProvider);287}288public PublicKey getPublicKey() { return cert.getPublicKey(); }289public String toString() { return cert.toString(); }290}291}292293294