Java tutorial
/* * Copyright 1999-2010 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * * See the License for the specific language governing permissions and limitations under the License. */ package org.globus.gsi; import org.globus.gsi.util.CertificateUtil; import org.globus.gsi.util.KeyStoreUtil; import org.globus.gsi.stores.ResourceSigningPolicyStore; import org.globus.gsi.stores.ResourceSigningPolicyStoreParameters; import org.globus.gsi.stores.Stores; import org.globus.gsi.provider.GlobusProvider; import org.globus.gsi.provider.KeyStoreParametersFactory; import javax.security.auth.x500.X500Principal; import java.security.cert.CertStore; import java.security.cert.Certificate; import java.security.cert.X509CertSelector; import java.security.KeyStore; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; import java.util.Map; import java.util.Set; import java.util.Vector; import java.util.HashMap; import java.util.HashSet; import java.util.StringTokenizer; import java.util.Collection; import java.util.Iterator; import java.io.File; import java.io.FilenameFilter; import org.globus.common.CoGProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.Serializable; import java.io.IOException; // COMMENT: What is the replacement for this? // COMMENT: We lost the refresh functionality: Currently an entirely new store is loaded upon load() /** * Class that reads in and maintains trusted certificates and signing * policy associated with the CAs. * @deprecated */ public class TrustedCertificates implements Serializable { private static Log logger = LogFactory.getLog(TrustedCertificates.class.getName()); static { new ProviderLoader(); } public static final CertFilter certFileFilter = new CertFilter(); private static TrustedCertificates trustedCertificates = null; // DN is in the format in certificates private Map certSubjectDNMap; // DN is in Globus format here, without any reversal. private Map policyDNMap; // Vector of X.509 Certificate objects private Vector certList; private final Set<X500Principal> invalidPolicies = new HashSet<X500Principal>(); private boolean changed; /** * Default signing policy suffix. The files are expected to be * <caHash>.signing_policy in the same directory as the trusted * certificates. */ public final static String SIGNING_POLICY_FILE_SUFFIX = ".signing_policy"; private static KeyStore ms_trustStore = null; private static CertStore ms_crlStore = null; private static ResourceSigningPolicyStore ms_sigPolStore = null; protected TrustedCertificates() { } public TrustedCertificates(X509Certificate[] certs) { this(certs, null); } public TrustedCertificates(X509Certificate[] certs, SigningPolicy[] policies) { // JGLOBUS-91 this.certSubjectDNMap = new HashMap(); for (int i = 0; i < certs.length; i++) { if (certs[i] != null) { String dn = certs[i].getSubjectDN().toString(); this.certSubjectDNMap.put(dn, certs[i]); } } if (policies != null) { this.policyDNMap = new HashMap(); for (int i = 0; i < policies.length; i++) { if (policies[i] != null) { this.policyDNMap.put(CertificateUtil.toGlobusID(policies[i].getCASubjectDN()), policies[i]); } } } } // COMMENT: BCB: removed getX509CertList() which used PureTLS. Needed by GlobusGSSContextImpl // so moved some things over to there public X509Certificate[] getCertificates() { if (this.certSubjectDNMap == null) { return null; } Collection certs = this.certSubjectDNMap.values(); return (X509Certificate[]) certs.toArray(new X509Certificate[certs.size()]); } public X509Certificate getCertificate(String subject) { if (this.certSubjectDNMap == null) { return null; } return (X509Certificate) this.certSubjectDNMap.get(subject); } /** * Returns all signing policies */ public SigningPolicy[] getSigningPolicies() { if (this.policyDNMap == null) { return null; } Collection values = this.policyDNMap.values(); return (SigningPolicy[]) this.policyDNMap.values().toArray(new SigningPolicy[values.size()]); } /** * Returns signing policy associated with the given CA subject. * * @param subject * CA's subject DN for which signing policy is * required. The DN should be in Globus format (with slashes) and * not reversed. See CertificateUtil.toGlobusID(); * @return * Signing policy object associated with the CA's DN. Null * if no policy was configured. SigningPolicy object might not * have any applicable policy if none was configured or none was * found in the policy file configured. */ public SigningPolicy getSigningPolicy(String subject) { if (this.policyDNMap == null) { return null; } return (SigningPolicy) this.policyDNMap.get(subject); } /** * Loads X509 certificates and signing policy files from specified * locations. The locations can be either files or * directories. The directories will be automatically traversed * and all files in the form of <i>hashcode.number</i> and will be * loaded automatically as trusted certificates. An attempt will * be made to load signing policy for the CA associated with * that hashcode from <hashcode>.signing_policy. If policy file is * not found, no error will be thrown, only path validation code * enforces the signing policy requirement. * * @param locations a list of certificate files/directories to load * the certificates from. The locations are comma * separated. * * @return <code>java.security.cert.X509Certificate</code> an array * of loaded certificates */ public static X509Certificate[] loadCertificates(String locations) { TrustedCertificates tc = TrustedCertificates.load(locations); return (tc == null) ? null : tc.getCertificates(); } public static TrustedCertificates load(String locations) { TrustedCertificates tc = new TrustedCertificates(); tc.reload(locations); return tc; } public static FilenameFilter getCertFilter() { return certFileFilter; } public static class CertFilter implements FilenameFilter { public boolean accept(File dir, String file) { int length = file.length(); if (length > 2 && file.charAt(length - 2) == '.' && file.charAt(length - 1) >= '0' && file.charAt(length - 1) <= '9') return true; return false; } } public synchronized void reload(String locations) { if (locations == null) { return; } this.changed = false; StringTokenizer tokens = new StringTokenizer(locations, ","); File caDir = null; Map newCertSubjectDNMap = new HashMap(); Map newSigningDNMap = new HashMap(); while (tokens.hasMoreTokens()) { caDir = new File(tokens.nextToken().toString().trim()); if (!caDir.canRead()) { logger.debug("Cannot read: " + caDir.getAbsolutePath()); continue; } String caCertLocation = "file:" + caDir.getAbsolutePath(); // String sigPolPattern = caCertLocation + "/*.signing_policy"; // if (!caDir.isDirectory()) { // sigPolPattern = getPolicyFileName(caCertLocation); // } try { ms_trustStore = Stores.getTrustStore(caCertLocation + "/" + Stores.getDefaultCAFilesPattern()); Collection<? extends Certificate> caCerts = KeyStoreUtil.getTrustedCertificates(ms_trustStore, new X509CertSelector()); Iterator iter = caCerts.iterator(); while (iter.hasNext()) { X509Certificate cert = (X509Certificate) iter.next(); if (!newCertSubjectDNMap.containsKey(cert.getSubjectDN().toString())) newCertSubjectDNMap.put(cert.getSubjectDN().toString(), cert); } } catch (Exception e) { logger.warn("Failed to create trust store", e); } try { ms_sigPolStore = Stores .getSigningPolicyStore(caCertLocation + "/" + Stores.getDefaultSigningPolicyFilesPattern()); } catch (GeneralSecurityException e) { logger.warn("Failed to create signing_policy store", e); } try { ms_sigPolStore = Stores .getSigningPolicyStore(caCertLocation + "/" + Stores.getDefaultSigningPolicyFilesPattern()); Collection<? extends Certificate> caCerts = KeyStoreUtil.getTrustedCertificates(ms_trustStore, new X509CertSelector()); Iterator iter = caCerts.iterator(); while (iter.hasNext()) { X509Certificate cert = (X509Certificate) iter.next(); X500Principal principal = cert.getSubjectX500Principal(); if (!newCertSubjectDNMap.containsKey(cert.getSubjectDN().toString())) { continue; } SigningPolicy policy; try { policy = ms_sigPolStore.getSigningPolicy(principal); } catch (Exception e) { if (!invalidPolicies.contains(principal)) { logger.warn("Invalid signing policy for CA certificate; skipping"); logger.debug("Invalid signing policy for CA certificate; skipping", e); invalidPolicies.add(principal); } continue; } if (policy != null) { newSigningDNMap.put(CertificateUtil.toGlobusID(policy.getCASubjectDN()), policy); } else { if (!invalidPolicies.contains(principal)) { logger.warn("no signing policy for ca cert " + cert.getSubjectDN()); invalidPolicies.add(principal); } } } } catch (Exception e) { logger.warn("Failed to create signing policy store", e); } } this.changed = true; this.certSubjectDNMap = newCertSubjectDNMap; this.policyDNMap = newSigningDNMap; if (this.changed) { this.certList = null; } } /** * Signing policy name is created as <hashcode>.signing_policy. */ private String getPolicyFileName(String caFileName) { return caFileName.substring(0, caFileName.lastIndexOf(".")) + SIGNING_POLICY_FILE_SUFFIX; } /** * Indicates if the last reload caused new certificates to be loaded or * existing certificates to be reloaded or any certificates removed */ public boolean isChanged() { return this.changed; } /** * Obtains the default set of trusted certificates and signing policy * * @return TrustedCertificates object. */ public static synchronized TrustedCertificates getDefaultTrustedCertificates() { return getDefault(); } /** * Sets the default set of trusted certificates to use. * * @param trusted the new set of trusted certificates to use. */ public static void setDefaultTrustedCertificates(TrustedCertificates trusted) { trustedCertificates = trusted; } /** * Obtains the default set of trusted certificates and signing policy * * @return TrustedCertificates object. */ public static synchronized TrustedCertificates getDefault() { if (trustedCertificates == null) { trustedCertificates = new DefaultTrustedCertificates(); } return trustedCertificates; } public static KeyStore getTrustStore() { return ms_trustStore; } public static CertStore getcrlStore() { return ms_crlStore; } public static ResourceSigningPolicyStore getsigPolStore() { return ms_sigPolStore; } private static class DefaultTrustedCertificates extends TrustedCertificates { public void refresh() { reload(CoGProperties.getDefault().getCaCertLocations()); } } public String toString() { String returnStr = ""; if (this.certSubjectDNMap == null) { returnStr = "Certificate list is empty."; } else { returnStr = this.certSubjectDNMap.toString(); } if (this.policyDNMap == null) { returnStr = returnStr + "Signing policy list is empty."; } else { returnStr = returnStr + this.policyDNMap.toString(); } return returnStr; } }