18b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak/* 28b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 38b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 48b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * 58b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * This code is free software; you can redistribute it and/or modify it 68b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * under the terms of the GNU General Public License version 2 only, as 78b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * published by the Free Software Foundation. Oracle designates this 88b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * particular file as subject to the "Classpath" exception as provided 98b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * by Oracle in the LICENSE file that accompanied this code. 108b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * 118b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * This code is distributed in the hope that it will be useful, but WITHOUT 128b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 138b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 148b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * version 2 for more details (a copy is included in the LICENSE file that 158b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * accompanied this code). 168b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * 178b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * You should have received a copy of the GNU General Public License version 188b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * 2 along with this work; if not, write to the Free Software Foundation, 198b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 208b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * 218b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 228b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * or visit www.oracle.com if you need additional information or have any 238b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * questions. 248b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak */ 258b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 268b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakpackage sun.security.util; 278b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 288b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.io.File; 298b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.io.FileInputStream; 308b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.security.AccessController; 318b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.security.KeyStore; 328b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.security.PrivilegedAction; 338b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.security.cert.X509Certificate; 348b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.util.Enumeration; 358b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport java.util.HashSet; 368b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 378b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakimport sun.security.x509.X509CertImpl; 388b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 398b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak/** 408b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * The purpose of this class is to determine the trust anchor certificates is in 418b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * the cacerts file. This is used for PKIX CertPath checking. 428b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak */ 438b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniakpublic class AnchorCertificates { 448b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 458b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak private static final Debug debug = Debug.getInstance("certpath"); 468b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak private static final String HASH = "SHA-256"; 478b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak private static HashSet<String> certs; 488b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 498b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak static { 508b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak AccessController.doPrivileged(new PrivilegedAction<Void>() { 518b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak @Override 528b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak public Void run() { 538b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak File f = new File(System.getProperty("java.home"), 548b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak "lib/security/cacerts"); 558b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak KeyStore cacerts; 568b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak try { 578b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak cacerts = KeyStore.getInstance("JKS"); 588b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak try (FileInputStream fis = new FileInputStream(f)) { 5967d67e686df79ac3ec14b04dda1115f3c097d9c2Przemyslaw Szczepaniak cacerts.load(fis, null); 608b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak certs = new HashSet<>(); 618b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak Enumeration<String> list = cacerts.aliases(); 628b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak String alias; 638b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak while (list.hasMoreElements()) { 648b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak alias = list.nextElement(); 658b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak // Check if this cert is labeled a trust anchor. 668b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak if (alias.contains(" [jdk")) { 678b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak X509Certificate cert = (X509Certificate) cacerts 688b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak .getCertificate(alias); 698b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak certs.add(X509CertImpl.getFingerprint(HASH, cert)); 708b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 718b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 728b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 738b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } catch (Exception e) { 748b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak if (debug != null) { 758b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak debug.println("Error parsing cacerts"); 768b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 778b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak e.printStackTrace(); 788b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 798b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak return null; 808b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 818b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak }); 828b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 838b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 848b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak /** 858b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * Checks if a certificate is a trust anchor. 868b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * 878b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * @param cert the certificate to check 888b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak * @return true if the certificate is trusted. 898b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak */ 908b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak public static boolean contains(X509Certificate cert) { 918b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak String key = X509CertImpl.getFingerprint(HASH, cert); 928b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak boolean result = certs.contains(key); 938b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak if (result && debug != null) { 948b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak debug.println("AnchorCertificate.contains: matched " + 958b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak cert.getSubjectDN()); 968b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 978b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak return result; 988b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak } 998b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak 1008b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak private AnchorCertificates() {} 1018b5ba217ca0e811a8e8602666b10f3b3e0bcc62cPrzemyslaw Szczepaniak} 102