[java-plugin-shibd] branch main updated: JSHIBD-25 - Develop necessary CredentialResolvers for SP service

Codeberg noreply at shibboleth.net
Tue Sep 1 19:08:05 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-plugin-shibd.

View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd/commit/4765a66b2e1a1a2513bfd4dd435389516a91b5c7

The following commit(s) were added to refs/heads/main by this push:
     new 4765a66  JSHIBD-25 - Develop necessary CredentialResolvers for SP service
4765a66 is described below

commit 4765a66b2e1a1a2513bfd4dd435389516a91b5c7
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Tue Sep 1 15:07:53 2026 -0400

    JSHIBD-25 - Develop necessary CredentialResolvers for SP service
    
    https://shibboleth.atlassian.net/browse/JSHIBD-25
    
    Extend file-based storage service with base64 encoding option.
    Add Keystore-based resolver.
---
 .../META-INF/net.shibboleth.idp/postconfig.xml     |   7 +
 .../impl/X509CredentialStorageServiceResolver.java |  12 +-
 .../impl/X509KeyStoreStorageServiceResolver.java   | 204 +++++++++++++++++++++
 .../sp/storage/impl/FilesystemStorageService.java  |  41 ++++-
 .../X509CredentialStorageServiceResolverTest.java  |   2 +-
 .../X509KeyStoreStorageServiceResolverTest.java    | 195 ++++++++++++++++++++
 6 files changed, 450 insertions(+), 11 deletions(-)

diff --git a/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index d7561f0..be74e9f 100644
--- a/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/sp-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -75,6 +75,13 @@
     <bean id="shibboleth.FilesystemStorageService.ReadWrite"
         class="net.shibboleth.sp.storage.impl.FilesystemStorageService" abstract="true"
         p:readOnly="false" />
+    <bean id="shibboleth.FilesystemStorageService.ReadOnly.Binary"
+        class="net.shibboleth.sp.storage.impl.FilesystemStorageService" abstract="true"
+        p:encodeData="true" />
+    <bean id="shibboleth.FilesystemStorageService.ReadWrite.Binary"
+        class="net.shibboleth.sp.storage.impl.FilesystemStorageService" abstract="true"
+        p:readOnly="false"
+        p:encodeData="true" />
     
     <bean id="shibboleth.RemotedHttpServletRequestSupplier" class="net.shibboleth.sp.messaging.impl.RemotedHttpServletRequestSupplier" />
     <bean id="shibboleth.RemotedHttpServletResponseSupplier" class="net.shibboleth.sp.messaging.impl.RemotedlHttpServletResponseSupplier" />
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolver.java b/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolver.java
index f4e8e2f..7f53b07 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolver.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolver.java
@@ -59,13 +59,13 @@ public class X509CredentialStorageServiceResolver extends AbstractStorageService
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(X509CredentialStorageServiceResolver.class);
     
-    /** Suffix added to storage key when searching for the private key. */
+    /** Template used to construct the storage key for the private key. */
     @Nonnull private String privateKeyTemplateString;
 
-    /** Suffix added to storage key when searching for the public key certificate(s). */
+    /** Template used to construct the storage key for the public key certificate(s). */
     @Nonnull private String certificateTemplateString;
 
-    /** Suffix added to storage key when searching for the CRL(s). */
+    /** Template used to construct the storage key for the CRL(s). */
     @Nullable private String crlTemplateString;
     
     /** Password for private key(s). */
@@ -93,7 +93,7 @@ public class X509CredentialStorageServiceResolver extends AbstractStorageService
     /**
      * Sets the Velocity template string for the private key's storage key.
      * 
-     * <p>Defaults to "sp$usage.key", which punts any other decoration to the storage context.</p>
+     * <p>Defaults to "sp${usage}.key", which punts any other decoration to the storage context.</p>
      * 
      * @param template template string
      */
@@ -107,7 +107,7 @@ public class X509CredentialStorageServiceResolver extends AbstractStorageService
     /**
      * Sets the Velocity template string for the certificate's storage key.
      * 
-     * <p>Defaults to "sp$usage.crt", which punts any other decoration to the storage context.</p>
+     * <p>Defaults to "sp${usage}.crt", which punts any other decoration to the storage context.</p>
      * 
      * @param template template string
      */
@@ -188,7 +188,7 @@ public class X509CredentialStorageServiceResolver extends AbstractStorageService
         }
         
         if (privateKeyData == null && certificateData == null) {
-            log.debug("{}: No private key or certificate data resolved", getId());
+            log.debug("Credential Resolver {}: No private key or certificate data resolved", getId());
             return CollectionSupport.emptyList();
         }
         
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509KeyStoreStorageServiceResolver.java b/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509KeyStoreStorageServiceResolver.java
new file mode 100644
index 0000000..71712d7
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/credential/impl/X509KeyStoreStorageServiceResolver.java
@@ -0,0 +1,204 @@
+/*
+ * 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 net.shibboleth.sp.credential.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyStore;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.exception.VelocityException;
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.security.x509.impl.KeyStoreX509CredentialAdapter;
+import org.opensaml.storage.StorageRecord;
+import org.slf4j.Logger;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.codec.Base64Support;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+import net.shibboleth.shared.velocity.Template;
+import net.shibboleth.sp.credential.AbstractStorageServiceCredentialResolver;
+
+/**
+ * A specialized storage-based resolver that can resolve the {@link X509Credential} type
+ * from a {@link KeyStore}, typically though not inherently the "PKCS12" type.
+ * 
+ * <p>Additional settings are required to specify how to locate the various components such as
+ * the keystore data and alias to use. A keystore password may be configured but must be usable for any
+ * resolved keys.</p>
+ */
+public class X509KeyStoreStorageServiceResolver extends AbstractStorageServiceCredentialResolver<X509Credential> {
+
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(X509KeyStoreStorageServiceResolver.class);
+    
+    @Nonnull private String keyStoreType;
+    
+    /** Template used to construct the storage key for the keystore. */
+    @Nonnull private String keyStoreTemplateString;
+
+    /** Template used to construct the keystore alias to load. */
+    @Nonnull private String aliasTemplateString;
+    
+    /** Password for private key(s). */
+    @Nullable private char[] privateKeyPassword;
+
+    /** Velocity template for keystore storage key. */
+    @NonnullAfterInit Template keyStoreTemplate;
+        
+    /** Velocity template for certificate storage key. */
+    @NonnullAfterInit Template aliasTemplate;
+    
+    /**
+     * Constructor.
+     */
+    public X509KeyStoreStorageServiceResolver() {
+        super(X509Credential.class);
+        
+        keyStoreType = "PKCS12";
+        
+        keyStoreTemplateString = "sp-keystore.p12";
+        aliasTemplateString = "${agentID}${usage}";
+    }
+    
+    /**
+     * Sets the {@link KeyStore} type.
+     * 
+     * <p>Defaults to "PKCS12".</p>
+     * 
+     * @param type keystore type
+     */
+    public void setKeyStoreType(@Nonnull @NotEmpty final String type) {
+        checkSetterPreconditions();
+        
+        keyStoreType = Constraint.isNotNull(StringSupport.trimOrNull(type), "KeyStore type cannot be null or empty");
+    }
+
+    /**
+     * Sets the Velocity template string for the keystore's storage key.
+     * 
+     * <p>Defaults to "sp-keystore.p12", which punts any other decoration to the storage context
+     * and assumes a fixed keystore with potentially multiple key entries.</p>
+     * 
+     * @param template template string
+     */
+    public void setKeyStoreTemplate(@Nonnull @NotEmpty final String template) {
+        checkSetterPreconditions();
+        
+        keyStoreTemplateString = Constraint.isNotNull(StringSupport.trimOrNull(template),
+                "KeyStore template cannot be null or empty");
+    }
+    
+    /**
+     * Sets the Velocity template string for the {@link KeyStore} alias to load.
+     * 
+     * <p>Defaults to "${agentID}${usage}", which assumes per-Agent entries
+     * discriminated by usage.</p>
+     * 
+     * @param template template string
+     */
+    public void setAliasTemplate(@Nonnull @NotEmpty final String template) {
+        checkSetterPreconditions();
+        
+        aliasTemplateString = Constraint.isNotNull(StringSupport.trimOrNull(template),
+                "KeyStore alias template cannot be null or empty");
+    }
+
+    /**
+     * Sets the password to apply to the keystore and any resolved entries.
+     * 
+     * @param password keystore password
+     */
+    public void setPassword(@Nullable final String password) {
+        checkSetterPreconditions();
+        
+        privateKeyPassword = password != null ? password.toCharArray() : null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        
+        keyStoreTemplate = Template.fromTemplate(getVelocityEngine(), keyStoreTemplateString,
+                StandardCharsets.UTF_8);
+        aliasTemplate = Template.fromTemplate(getVelocityEngine(), aliasTemplateString,
+                StandardCharsets.UTF_8);
+    }
+    
+    /** {@inheritDoc} 
+     * @throws ResolverException */
+    @Override
+    @Nonnull @NotLive @Unmodifiable protected Iterable<Credential> doResolve(@Nonnull VelocityContext velocityContext,
+            @Nullable final CriteriaSet criteria, @Nonnull final String storageContext) throws ResolverException {
+ 
+        final StorageRecord<String> keyStoreData;
+        final String alias;
+
+        try {
+            final String keyStoreStorage = keyStoreTemplate.merge(velocityContext);
+            alias = aliasTemplate.merge(velocityContext);
+
+            log.debug("CredentialResolver {}: Resolved storage key for keystore ({}), alias ({})", getId(),
+                    keyStoreStorage, alias);
+            
+            keyStoreData = getStorageService().read(storageContext, keyStoreStorage);
+            
+        } catch (final VelocityException e) {
+            throw new ResolverException("Error executing storage key template", e);
+        } catch (final IOException e) {
+            throw new ResolverException("I/O exception retrieving KeyStore data", e);
+        }
+        
+        if (keyStoreData == null || alias == null) {
+            log.debug("CredentialResolver {}: No KeyStore or alias resolved", getId());
+            return CollectionSupport.emptyList();
+        }
+        
+        log.debug("CredentialResolver {}: Resolved data for KeyStore and alias {}", getId(), alias);
+
+        try (final ByteArrayInputStream input = new ByteArrayInputStream(Base64Support.decode(keyStoreData.getValue()))) {
+            final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+            keyStore.load(input, privateKeyPassword);
+            
+            if (!keyStore.containsAlias(alias)) {
+                log.debug("CredentialResolver {}: KeyStore did not contain alias: {}", getId(), alias);
+                return CollectionSupport.emptyList();
+            }
+            
+            final KeyStoreX509CredentialAdapter credential =
+                    new KeyStoreX509CredentialAdapter(keyStore, alias, privateKeyPassword);
+            log.debug("CredentialResolver {}: Resolved X509Credential for caller", getId());
+            return CollectionSupport.singletonList(credential);
+        } catch (final Exception e) {
+            throw new ResolverException("Exception during creation of X509Credential object", e);
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/storage/impl/FilesystemStorageService.java b/sp-server-impl/src/main/java/net/shibboleth/sp/storage/impl/FilesystemStorageService.java
index 598c15d..1b51c81 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/storage/impl/FilesystemStorageService.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/storage/impl/FilesystemStorageService.java
@@ -31,6 +31,7 @@ import org.opensaml.storage.VersionMismatchException;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.codec.Base64Support;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
@@ -47,6 +48,9 @@ public class FilesystemStorageService extends AbstractStorageService {
     /** Whether service is read only. */
     private boolean readOnly;
     
+    /** Whether to treat data as binary, using base64 to encoder/decode across String boundary. */
+    private boolean encodeData;
+    
     /** Base location of storage tree in filesystem. */
     @NonnullAfterInit private String storageBase;
     
@@ -81,6 +85,21 @@ public class FilesystemStorageService extends AbstractStorageService {
         readOnly = flag;
     }
     
+    /**
+     * Sets whether the service should operate on binary data, encoding to base64 after reads
+     * and decoding from base64 on writes.
+     * 
+     * <p>Defaults to false.</p>
+     * 
+     * @param flag flag to set
+     */
+    public void setEncodeData(final boolean flag) {
+        checkSetterPreconditions();
+        
+        encodeData = flag;
+    }
+    
+    
     /**
      * Sets the base/root directory under which objects will be created and deleted.
      * 
@@ -141,7 +160,14 @@ public class FilesystemStorageService extends AbstractStorageService {
             
             final Path parentFolder = fullPath.getParent();
             Files.createDirectories(parentFolder);
-            Files.writeString(fullPath, value, StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
+            
+            if (encodeData) {
+                final byte[] decoded = Base64Support.decode(value);
+                Files.write(fullPath, decoded, StandardOpenOption.CREATE_NEW);
+            } else {
+                Files.writeString(fullPath, value, StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
+            }
+            
             return true;
         } catch (final Exception e) {
             throw new IOException(e);
@@ -159,9 +185,16 @@ public class FilesystemStorageService extends AbstractStorageService {
                 return null;
             }
             
-            final String value = Files.readString(fullPath);
-            if (value != null) {
-                return new StorageRecord<T>(value, null);
+            if (encodeData) {
+                final String encoded = Base64Support.encode(Files.readAllBytes(fullPath), false);
+                if (encoded != null) {
+                    return new StorageRecord<T>(encoded, null);
+                }
+            } else {
+                final String value = Files.readString(fullPath);
+                if (value != null) {
+                    return new StorageRecord<T>(value, null);
+                }
             }
             
             return null;
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolverTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolverTest.java
index 2d18b49..e1387ad 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolverTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509CredentialStorageServiceResolverTest.java
@@ -277,7 +277,7 @@ public class X509CredentialStorageServiceResolverTest {
     private void generateKeyPair(@Nonnull final Path key, @Nonnull final Path cert, @Nonnull final String hostname,
             @Nullable final String entityID) throws Exception {
         final SelfSignedCertificateGenerator generator = new SelfSignedCertificateGenerator();
-        generator.setKeySize(1024);
+        generator.setKeySize(2048);
         generator.setHostName(hostname);
         if (entityID != null) {
             generator.setURISubjectAltNames(CollectionSupport.singletonList(entityID));
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509KeyStoreStorageServiceResolverTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509KeyStoreStorageServiceResolverTest.java
new file mode 100644
index 0000000..9d8ecb7
--- /dev/null
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/credential/impl/X509KeyStoreStorageServiceResolverTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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 net.shibboleth.sp.credential.impl;
+
+import java.io.IOException;
+import java.nio.file.DirectoryNotEmptyException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.criteria.UsageCriterion;
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.security.x509.X509Credential;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.security.impl.SelfSignedCertificateGenerator;
+import net.shibboleth.shared.testing.VelocityEngine;
+import net.shibboleth.sp.criteria.AgentIDCriterion;
+import net.shibboleth.sp.criteria.ApplicationIDCriterion;
+import net.shibboleth.sp.storage.impl.FilesystemStorageService;
+
+/**
+ * Unit tests for {@link X509KeyStoreStorageServiceResolver}.
+ */
+ at SuppressWarnings("javadoc")
+public class X509KeyStoreStorageServiceResolverTest {
+
+    private Path testRoot;
+
+    @BeforeMethod
+    public void setUp() throws IOException {
+        testRoot = Files.createTempDirectory("test-pkcs12-resolver");
+    }
+ 
+    private void tearDownWorker() throws IOException {
+        if (testRoot != null) {
+            Files.walkFileTree(testRoot, new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException
+                {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir, IOException e)
+                    throws IOException
+                {
+                    if (e == null) {
+                        Files.delete(dir);
+                        return FileVisitResult.CONTINUE;
+                    }
+                    // directory iteration failed
+                    throw e;
+                }
+            });
+            testRoot = null;
+        }
+    }
+
+    @AfterMethod
+    public void tearDown() throws IOException, InterruptedException {
+        try {
+            tearDownWorker();
+        } catch (final DirectoryNotEmptyException ex) {
+            // We hates the Microsoft Defender.  (it pins files so directories cannot be deleted)
+            Thread.sleep(10);
+            tearDownWorker();
+        }
+    }
+    
+    @Test
+    public void testOneEntry() throws Exception {
+        
+        // Prep directories for agents.
+        Files.createDirectories(Path.of(testRoot.toString(), "agents"));
+        
+        // Generate keypairs for testing.
+        generateKeyPair(Path.of(testRoot.toString(), "agents", "sp-keystore.p12"), "changeit", "localhost", null);
+        
+        final FilesystemStorageService storage = new FilesystemStorageService();
+        storage.setId("test");
+        storage.setReadOnly(true);
+        storage.setEncodeData(true);
+        storage.setStorageBase(testRoot.toString());
+        storage.initialize();
+        
+        final X509KeyStoreStorageServiceResolver resolver = new X509KeyStoreStorageServiceResolver();
+        resolver.setId("test");
+        resolver.setStorageService(storage);
+        resolver.setVelocityEngine(VelocityEngine.newVelocityEngine());
+        resolver.setContextTemplate("agents");
+        resolver.setAliasTemplate("${agentID}");
+        resolver.setPassword("changeit");
+        resolver.initialize();
+        
+        final X509Credential credential = (X509Credential) resolver.resolveSingle(
+                buildCriteriaSet("localhost", "default", "https://idp.example.org/idp", UsageType.SIGNING));
+        assert credential != null;
+        
+        final PrivateKey key = credential.getPrivateKey();
+        assert key != null;
+        
+        final X509Certificate cert = credential.getEntityCertificate();
+        assert cert != null;
+
+        Assert.assertTrue(KeySupport.matchKeyPair(cert.getPublicKey(), key));
+        Assert.assertEquals(cert.getSubjectAlternativeNames(), CollectionSupport.singletonList(
+                CollectionSupport.listOf(Integer.valueOf(2), "localhost")));
+    }
+    
+    /**
+     * Generate a self-signed keypair in a PKCS12 file.
+     * 
+     * @param keystore keystore file
+     * @param password keystore password
+     * @param hostname hostname for subject and DNS sAN (and keystore alias)
+     * @param entityID URI for URI sAN
+     * 
+     * @throws Exception on errors
+     */
+    private void generateKeyPair(@Nonnull final Path keystore, @Nonnull String password,
+            @Nonnull final String hostname, @Nullable final String entityID) throws Exception {
+        final SelfSignedCertificateGenerator generator = new SelfSignedCertificateGenerator();
+        generator.setKeySize(2048);
+        generator.setHostName(hostname);
+        if (entityID != null) {
+            generator.setURISubjectAltNames(CollectionSupport.singletonList(entityID));
+        }
+        generator.setKeystoreFile(keystore.toFile());
+        generator.setKeystorePassword(password);
+        generator.generate();
+    }
+    
+    /**
+     * Builds a set of criteria for the resolver.
+     * 
+     * @param agentID agent ID
+     * @param applicationID application ID
+     * @param entityID entityID
+     * @param usage usage type
+     * 
+     * @return built criteria
+     */
+    @Nonnull private CriteriaSet buildCriteriaSet(@Nullable final String agentID, @Nullable final String applicationID,
+            @Nullable final String entityID, @Nullable final UsageType usage) {
+        
+        final CriteriaSet criteria = new CriteriaSet();
+        
+        if (agentID != null) {
+            criteria.add(new AgentIDCriterion(agentID));
+        }
+
+        if (applicationID != null) {
+            criteria.add(new ApplicationIDCriterion(applicationID));
+        }
+        
+        if (entityID != null) {
+            criteria.add(new EntityIdCriterion(entityID));
+        }
+        
+        if (usage != null) {
+            criteria.add(new UsageCriterion(usage));
+        }
+        
+        return criteria;
+    }
+    
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list