1/* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.security.util; 27 28import java.io.File; 29import java.io.FileInputStream; 30import java.security.AccessController; 31import java.security.KeyStore; 32import java.security.PrivilegedAction; 33import java.security.cert.X509Certificate; 34import java.util.Enumeration; 35import java.util.HashSet; 36 37import sun.security.x509.X509CertImpl; 38 39/** 40 * The purpose of this class is to determine the trust anchor certificates is in 41 * the cacerts file. This is used for PKIX CertPath checking. 42 */ 43public class AnchorCertificates { 44 45 private static final Debug debug = Debug.getInstance("certpath"); 46 private static final String HASH = "SHA-256"; 47 private static HashSet<String> certs; 48 49 static { 50 AccessController.doPrivileged(new PrivilegedAction<Void>() { 51 @Override 52 public Void run() { 53 File f = new File(System.getProperty("java.home"), 54 "lib/security/cacerts"); 55 KeyStore cacerts; 56 try { 57 cacerts = KeyStore.getInstance("JKS"); 58 try (FileInputStream fis = new FileInputStream(f)) { 59 cacerts.load(fis, null); 60 certs = new HashSet<>(); 61 Enumeration<String> list = cacerts.aliases(); 62 String alias; 63 while (list.hasMoreElements()) { 64 alias = list.nextElement(); 65 // Check if this cert is labeled a trust anchor. 66 if (alias.contains(" [jdk")) { 67 X509Certificate cert = (X509Certificate) cacerts 68 .getCertificate(alias); 69 certs.add(X509CertImpl.getFingerprint(HASH, cert)); 70 } 71 } 72 } 73 } catch (Exception e) { 74 if (debug != null) { 75 debug.println("Error parsing cacerts"); 76 } 77 e.printStackTrace(); 78 } 79 return null; 80 } 81 }); 82 } 83 84 /** 85 * Checks if a certificate is a trust anchor. 86 * 87 * @param cert the certificate to check 88 * @return true if the certificate is trusted. 89 */ 90 public static boolean contains(X509Certificate cert) { 91 String key = X509CertImpl.getFingerprint(HASH, cert); 92 boolean result = certs.contains(key); 93 if (result && debug != null) { 94 debug.println("AnchorCertificate.contains: matched " + 95 cert.getSubjectDN()); 96 } 97 return result; 98 } 99 100 private AnchorCertificates() {} 101} 102