1/* 2 * Copyright (c) 2000, 2012, 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.provider.certpath; 27 28import java.security.InvalidAlgorithmParameterException; 29import java.security.cert.Certificate; 30import java.security.cert.CRL; 31import java.util.Collection; 32import java.util.ConcurrentModificationException; 33import java.util.HashSet; 34import java.security.cert.CertSelector; 35import java.security.cert.CertStore; 36import java.security.cert.CertStoreException; 37import java.security.cert.CertStoreParameters; 38import java.security.cert.CollectionCertStoreParameters; 39import java.security.cert.CRLSelector; 40import java.security.cert.CertStoreSpi; 41 42/** 43 * A <code>CertStore</code> that retrieves <code>Certificates</code> and 44 * <code>CRL</code>s from a <code>Collection</code>. 45 * <p> 46 * Before calling the {@link #engineGetCertificates engineGetCertificates} or 47 * {@link #engineGetCRLs engineGetCRLs} methods, the 48 * {@link #CollectionCertStore(CertStoreParameters) 49 * CollectionCertStore(CertStoreParameters)} constructor is called to 50 * create the <code>CertStore</code> and establish the 51 * <code>Collection</code> from which <code>Certificate</code>s and 52 * <code>CRL</code>s will be retrieved. If the specified 53 * <code>Collection</code> contains an object that is not a 54 * <code>Certificate</code> or <code>CRL</code>, that object will be 55 * ignored. 56 * <p> 57 * <b>Concurrent Access</b> 58 * <p> 59 * As described in the javadoc for <code>CertStoreSpi</code>, the 60 * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods 61 * must be thread-safe. That is, multiple threads may concurrently 62 * invoke these methods on a single <code>CollectionCertStore</code> 63 * object (or more than one) with no ill effects. 64 * <p> 65 * This is achieved by requiring that the <code>Collection</code> passed to 66 * the {@link #CollectionCertStore(CertStoreParameters) 67 * CollectionCertStore(CertStoreParameters)} constructor (via the 68 * <code>CollectionCertStoreParameters</code> object) must have fail-fast 69 * iterators. Simultaneous modifications to the <code>Collection</code> can thus be 70 * detected and certificate or CRL retrieval can be retried. The fact that 71 * <code>Certificate</code>s and <code>CRL</code>s must be thread-safe is also 72 * essential. 73 * 74 * @see java.security.cert.CertStore 75 * 76 * @since 1.4 77 * @author Steve Hanna 78 */ 79public class CollectionCertStore extends CertStoreSpi { 80 81 private Collection<?> coll; 82 83 /** 84 * Creates a <code>CertStore</code> with the specified parameters. 85 * For this class, the parameters object must be an instance of 86 * <code>CollectionCertStoreParameters</code>. The <code>Collection</code> 87 * included in the <code>CollectionCertStoreParameters</code> object 88 * must be thread-safe. 89 * 90 * @param params the algorithm parameters 91 * @exception InvalidAlgorithmParameterException if params is not an 92 * instance of <code>CollectionCertStoreParameters</code> 93 */ 94 public CollectionCertStore(CertStoreParameters params) 95 throws InvalidAlgorithmParameterException 96 { 97 super(params); 98 if (!(params instanceof CollectionCertStoreParameters)) 99 throw new InvalidAlgorithmParameterException( 100 "parameters must be CollectionCertStoreParameters"); 101 coll = ((CollectionCertStoreParameters) params).getCollection(); 102 } 103 104 /** 105 * Returns a <code>Collection</code> of <code>Certificate</code>s that 106 * match the specified selector. If no <code>Certificate</code>s 107 * match the selector, an empty <code>Collection</code> will be returned. 108 * 109 * @param selector a <code>CertSelector</code> used to select which 110 * <code>Certificate</code>s should be returned. Specify <code>null</code> 111 * to return all <code>Certificate</code>s. 112 * @return a <code>Collection</code> of <code>Certificate</code>s that 113 * match the specified selector 114 * @throws CertStoreException if an exception occurs 115 */ 116 @Override 117 public Collection<Certificate> engineGetCertificates 118 (CertSelector selector) throws CertStoreException { 119 if (coll == null) { 120 throw new CertStoreException("Collection is null"); 121 } 122 // Tolerate a few ConcurrentModificationExceptions 123 for (int c = 0; c < 10; c++) { 124 try { 125 HashSet<Certificate> result = new HashSet<>(); 126 if (selector != null) { 127 for (Object o : coll) { 128 if ((o instanceof Certificate) && 129 selector.match((Certificate) o)) 130 result.add((Certificate)o); 131 } 132 } else { 133 for (Object o : coll) { 134 if (o instanceof Certificate) 135 result.add((Certificate)o); 136 } 137 } 138 return(result); 139 } catch (ConcurrentModificationException e) { } 140 } 141 throw new ConcurrentModificationException("Too many " 142 + "ConcurrentModificationExceptions"); 143 } 144 145 /** 146 * Returns a <code>Collection</code> of <code>CRL</code>s that 147 * match the specified selector. If no <code>CRL</code>s 148 * match the selector, an empty <code>Collection</code> will be returned. 149 * 150 * @param selector a <code>CRLSelector</code> used to select which 151 * <code>CRL</code>s should be returned. Specify <code>null</code> 152 * to return all <code>CRL</code>s. 153 * @return a <code>Collection</code> of <code>CRL</code>s that 154 * match the specified selector 155 * @throws CertStoreException if an exception occurs 156 */ 157 @Override 158 public Collection<CRL> engineGetCRLs(CRLSelector selector) 159 throws CertStoreException 160 { 161 if (coll == null) 162 throw new CertStoreException("Collection is null"); 163 164 // Tolerate a few ConcurrentModificationExceptions 165 for (int c = 0; c < 10; c++) { 166 try { 167 HashSet<CRL> result = new HashSet<>(); 168 if (selector != null) { 169 for (Object o : coll) { 170 if ((o instanceof CRL) && selector.match((CRL) o)) 171 result.add((CRL)o); 172 } 173 } else { 174 for (Object o : coll) { 175 if (o instanceof CRL) 176 result.add((CRL)o); 177 } 178 } 179 return result; 180 } catch (ConcurrentModificationException e) { } 181 } 182 throw new ConcurrentModificationException("Too many " 183 + "ConcurrentModificationExceptions"); 184 } 185} 186