Some work on making the StorageResolvers thread-safe
git-svn-id: https://svn.apache.org/repos/asf/santuario/xml-security-java/trunk@1872762 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java b/src/main/java/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java
index e07dc3a..290473a 100644
--- a/src/main/java/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java
+++ b/src/main/java/org/apache/xml/security/keys/keyresolver/KeyResolverSpi.java
@@ -43,6 +43,8 @@
* <KeyResolver URI="http://www.w3.org/2000/09/xmldsig#KeyValue"
* JAVACLASS="MyPackage.MyKeyValueImpl"//gt;
* </PRE>
+ *
+ * Extensions of this class must be thread-safe.
*/
public abstract class KeyResolverSpi {
diff --git a/src/main/java/org/apache/xml/security/keys/storage/StorageResolver.java b/src/main/java/org/apache/xml/security/keys/storage/StorageResolver.java
index 3232444..aca08a2 100644
--- a/src/main/java/org/apache/xml/security/keys/storage/StorageResolver.java
+++ b/src/main/java/org/apache/xml/security/keys/storage/StorageResolver.java
@@ -38,7 +38,7 @@
org.slf4j.LoggerFactory.getLogger(StorageResolver.class);
/** Field storageResolvers */
- private List<StorageResolverSpi> storageResolvers;
+ private final List<StorageResolverSpi> storageResolvers = new ArrayList<>();
/**
* Constructor StorageResolver
@@ -61,9 +61,6 @@
* @param resolver
*/
public void add(StorageResolverSpi resolver) {
- if (storageResolvers == null) {
- storageResolvers = new ArrayList<>();
- }
this.storageResolvers.add(resolver);
}
@@ -122,10 +119,10 @@
static class StorageResolverIterator implements Iterator<Certificate> {
/** Field resolvers */
- Iterator<StorageResolverSpi> resolvers = null;
+ private final Iterator<StorageResolverSpi> resolvers;
/** Field currentResolver */
- Iterator<Certificate> currentResolver = null;
+ private Iterator<Certificate> currentResolver;
/**
* Constructor StorageResolverIterator
diff --git a/src/main/java/org/apache/xml/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java b/src/main/java/org/apache/xml/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java
index fe7523d..f7c0746 100644
--- a/src/main/java/org/apache/xml/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java
+++ b/src/main/java/org/apache/xml/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java
@@ -31,8 +31,10 @@
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.NoSuchElementException;
import org.apache.xml.security.keys.storage.StorageResolverException;
import org.apache.xml.security.keys.storage.StorageResolverSpi;
@@ -49,11 +51,8 @@
CertsInFilesystemDirectoryResolver.class
);
- /** Field merlinsCertificatesDir */
- private String merlinsCertificatesDir;
-
/** Field certs */
- private List<X509Certificate> certs = new ArrayList<>();
+ private final List<X509Certificate> certs;
/**
* @param directoryName
@@ -61,19 +60,8 @@
*/
public CertsInFilesystemDirectoryResolver(String directoryName)
throws StorageResolverException {
- this.merlinsCertificatesDir = directoryName;
- this.readCertsFromHarddrive();
- }
-
- /**
- * Method readCertsFromHarddrive
- *
- * @throws StorageResolverException
- */
- private void readCertsFromHarddrive() throws StorageResolverException {
-
- File certDir = new File(this.merlinsCertificatesDir);
+ File certDir = new File(directoryName);
List<String> al = new ArrayList<>();
String[] names = certDir.list();
@@ -88,13 +76,13 @@
}
CertificateFactory cf = null;
-
try {
cf = CertificateFactory.getInstance("X.509");
} catch (CertificateException ex) {
throw new StorageResolverException(ex);
}
+ List<X509Certificate> tmpCerts = new ArrayList<>();
for (int i = 0; i < al.size(); i++) {
String filename = certDir.getAbsolutePath() + File.separator + al.get(i);
boolean added = false;
@@ -106,7 +94,7 @@
//add to ArrayList
cert.checkValidity();
- this.certs.add(cert);
+ tmpCerts.add(cert);
dn = cert.getSubjectX500Principal().getName();
added = true;
@@ -136,6 +124,8 @@
LOG.debug("Added certificate: {}", dn);
}
}
+
+ certs = Collections.unmodifiableList(tmpCerts);
}
/** {@inheritDoc} */
@@ -149,7 +139,7 @@
private static class FilesystemIterator implements Iterator<Certificate> {
/** Field certs */
- private List<X509Certificate> certs;
+ private final List<X509Certificate> certs;
/** Field i */
private int i;
@@ -171,7 +161,11 @@
/** {@inheritDoc} */
public Certificate next() {
- return this.certs.get(this.i++);
+ if (hasNext()) {
+ return this.certs.get(this.i++);
+ }
+
+ throw new NoSuchElementException();
}
/**
diff --git a/src/main/java/org/apache/xml/security/keys/storage/implementations/KeyStoreResolver.java b/src/main/java/org/apache/xml/security/keys/storage/implementations/KeyStoreResolver.java
index 294720f..2b6b784 100644
--- a/src/main/java/org/apache/xml/security/keys/storage/implementations/KeyStoreResolver.java
+++ b/src/main/java/org/apache/xml/security/keys/storage/implementations/KeyStoreResolver.java
@@ -21,8 +21,11 @@
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.List;
import java.util.NoSuchElementException;
import org.apache.xml.security.keys.storage.StorageResolverException;
@@ -34,8 +37,11 @@
*/
public class KeyStoreResolver extends StorageResolverSpi {
+ private static final org.slf4j.Logger LOG =
+ org.slf4j.LoggerFactory.getLogger(KeyStoreResolver.class);
+
/** Field keyStore */
- private KeyStore keyStore;
+ private final KeyStore keyStore;
/**
* Constructor KeyStoreResolver
@@ -63,14 +69,9 @@
*/
static class KeyStoreIterator implements Iterator<Certificate> {
- /** Field keyStore */
- KeyStore keyStore = null;
+ private final List<Certificate> certs;
- /** Field aliases */
- Enumeration<String> aliases = null;
-
- /** Field nextCert */
- Certificate nextCert = null;
+ private int i;
/**
* Constructor KeyStoreIterator
@@ -78,45 +79,37 @@
* @param keyStore
*/
public KeyStoreIterator(KeyStore keyStore) {
+
+ List<Certificate> tmpCerts = new ArrayList<>();
try {
- this.keyStore = keyStore;
- this.aliases = this.keyStore.aliases();
+ Enumeration<String> aliases = keyStore.aliases();
+ while (aliases.hasMoreElements()) {
+ String alias = aliases.nextElement();
+ Certificate cert = keyStore.getCertificate(alias);
+ if (cert != null) {
+ tmpCerts.add(cert);
+ }
+ }
} catch (KeyStoreException ex) {
- // empty Enumeration
- this.aliases = new Enumeration<String>() {
- public boolean hasMoreElements() {
- return false;
- }
- public String nextElement() {
- return null;
- }
- };
+ LOG.debug("Error reading certificates: {}", ex.getMessage());
}
+
+ certs = Collections.unmodifiableList(tmpCerts);
+ this.i = 0;
}
/** {@inheritDoc} */
public boolean hasNext() {
- if (nextCert == null) {
- nextCert = findNextCert();
- }
-
- return nextCert != null;
+ return this.i < this.certs.size();
}
/** {@inheritDoc} */
public Certificate next() {
- if (nextCert == null) {
- // maybe caller did not call hasNext()
- nextCert = findNextCert();
-
- if (nextCert == null) {
- throw new NoSuchElementException();
- }
+ if (hasNext()) {
+ return this.certs.get(this.i++);
}
- Certificate ret = nextCert;
- nextCert = null;
- return ret;
+ throw new NoSuchElementException();
}
/**
@@ -126,24 +119,6 @@
throw new UnsupportedOperationException("Can't remove keys from KeyStore");
}
- // Find the next entry that contains a certificate and return it.
- // In particular, this skips over entries containing symmetric keys.
- private Certificate findNextCert() {
- while (this.aliases.hasMoreElements()) {
- String alias = this.aliases.nextElement();
- try {
- Certificate cert = this.keyStore.getCertificate(alias);
- if (cert != null) {
- return cert;
- }
- } catch (KeyStoreException ex) {
- return null;
- }
- }
-
- return null;
- }
-
}
}
diff --git a/src/main/java/org/apache/xml/security/keys/storage/implementations/SingleCertificateResolver.java b/src/main/java/org/apache/xml/security/keys/storage/implementations/SingleCertificateResolver.java
index 5d77acc..34f6b50 100644
--- a/src/main/java/org/apache/xml/security/keys/storage/implementations/SingleCertificateResolver.java
+++ b/src/main/java/org/apache/xml/security/keys/storage/implementations/SingleCertificateResolver.java
@@ -32,7 +32,7 @@
public class SingleCertificateResolver extends StorageResolverSpi {
/** Field certificate */
- private X509Certificate certificate;
+ private final X509Certificate certificate;
/**
* @param x509cert the single {@link X509Certificate}
@@ -52,10 +52,10 @@
static class InternalIterator implements Iterator<Certificate> {
/** Field alreadyReturned */
- boolean alreadyReturned = false;
+ private boolean alreadyReturned;
/** Field certificate */
- X509Certificate certificate = null;
+ private final X509Certificate certificate;
/**
* Constructor InternalIterator