[java-idp-integration-tests] 02/02: Work on OIDC tests

Tom Zeller tzeller at dragonacea.biz
Thu Jul 11 21:21:35 UTC 2024


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

tzeller pushed a commit to branch main
in repository java-idp-integration-tests.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-integration-tests.git;a=commit;h=93f0bc3980062e01c807e3ff74eea26ae81ccc4d

commit 93f0bc3980062e01c807e3ff74eea26ae81ccc4d
Author: Tom Zeller <tzeller at dragonacea.biz>
AuthorDate: Thu Jul 11 16:21:23 2024 -0500

    Work on OIDC tests
    
    Extract TLS cert and key for OIDC RP from P12 keystore and inject into
    Docker container
    
    Optionally download Let's Encrypt keystore for idp.tests.shibboleth.net
    
    Support Tomcat
---
 pom.xml                                            | 143 +++++++------
 .../idp/integration/tests/oidc/OIDCTest.java       |  74 +++++--
 .../idp/integration/tests/oidc/RPContainer.java    | 223 +++++++++++++--------
 3 files changed, 288 insertions(+), 152 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6bb037a..22cd64f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -195,7 +195,7 @@
                                     <type>test-jar</type>
                                     <classifier>tests</classifier>
                                     <includes>credentials/*</includes>
-                                    <excludes>credentials/idp-userfacing.p12</excludes>
+                                    <excludes>credentials/idp-userfacing.p12,credentials/idp-backchannel.p12</excludes>
                                 </artifactItem>
                             </artifactItems>
                             <outputDirectory>${idp-to-be-tested.directory}</outputDirectory>
@@ -440,30 +440,45 @@
                                     <outputDirectory>${test-distributions.directory}</outputDirectory>
                                 </configuration>
                             </execution>
-                            <!-- Copy credentials from idp-conf-impl or idp-conf test jar to jetty-base. -->
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <!-- Copy testbed deployment descriptor to jetty-base. -->
                             <execution>
-                                <id>copy-credentials-to-jetty-base</id>
+                                <id>copy-testbed-deployment-descriptor-to-jetty-base</id>
                                 <phase>compile</phase>
                                 <goals>
-                                    <goal>unpack</goal>
+                                    <goal>copy-resources</goal>
                                 </goals>
                                 <configuration>
-                                    <artifactItems>
-                                        <artifactItem>
-                                            <groupId>net.shibboleth.idp</groupId>
-                                            <artifactId>${idp-conf.artifactId}</artifactId>
-                                            <version>${idp-to-be-tested.version}</version>
-                                            <type>jar</type>
-                                            <classifier>tests</classifier>
-                                            <includes>credentials/idp-userfacing.p12,credentials/idp-backchannel.p12</includes>
-                                        </artifactItem>
-                                    </artifactItems>
                                     <outputDirectory>${test-distributions.directory}/jetty-base/</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>src/test/jetty-base/</directory>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                            <!-- Copy self-signed credentials to jetty-base. -->
+                            <execution>
+                                <id>copy-self-signed-credentials-to-jetty-base</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>copy-resources</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${test-distributions.directory}/jetty-base/credentials</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>src/test/credentials</directory>
+                                        </resource>
+                                    </resources>
                                 </configuration>
                             </execution>
                         </executions>
                     </plugin>
-
                     <!-- Set up *.tests.shibboleth.net wildcard cert -->
                     <plugin>
                         <groupId>org.apache.maven.plugins</groupId>
@@ -471,7 +486,7 @@
                         <version>3.1.0</version>
                         <executions>
                             <execution>
-                                <id>set-up-tests-pfx</id>
+                                <id>set-up-shib-tests-wildcard-cert</id>
                                 <phase>compile</phase>
                                 <goals>
                                     <goal>run</goal>
@@ -479,13 +494,12 @@
                                 <configuration>
                                     <!-- Run only if environment variable is "true" -->
                                     <target if="${env.shib_tests_p12}">
-                                        <!-- Copy p12 file -->
-                                        <copy
-                                            file="${env.shib_tests_op_tls_p12}"
-                                            tofile="${test-distributions.directory}/jetty-base/credentials/idp-userfacing.p12"
-                                            failonerror="true"
-                                            overwrite="true"
-                                            preservelastmodified="true" />
+                                        <!-- Download p12 file with authn using password from environment -->
+                                        <get src="https://build.shibboleth.net/jenkins-helpers/tls/tests.shibboleth.net.pfx"
+                                             dest="${test-distributions.directory}/jetty-base/credentials/idp-userfacing.p12"
+                                             username="jenkins"
+                                             password="${env.shib_jenkins_helper_pwd}"
+                                             verbose="true" />
                                         <!-- Replace p12 password -->
                                         <replace
                                             file="${test-distributions.directory}/jetty-base/start.d/idp.ini"
@@ -497,29 +511,6 @@
                             </execution>
                         </executions>
                     </plugin>
-
-                    <plugin>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <executions>
-                            <!-- Copy testbed deployment descriptor. -->
-                            <execution>
-                                <id>copy-resources</id>
-                                <phase>compile</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${test-distributions.directory}/jetty-base/</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>src/test/jetty-base/</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-
                 </plugins>
             </build>
         </profile>
@@ -609,25 +600,57 @@
                                     <outputDirectory>${test-distributions.directory}/tomcat-base/</outputDirectory>
                                 </configuration>
                             </execution>
-                            <!-- Copy credentials from idp-conf-impl or idp-conf test jar to tomcat-base. -->
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <!-- Copy self-signed credentials to tomcat-base. -->
                             <execution>
-                                <id>copy-credentials-to-tomcat-base</id>
+                                <id>copy-self-signed-credentials-to-tomcat-base</id>
                                 <phase>compile</phase>
                                 <goals>
-                                    <goal>unpack</goal>
+                                    <goal>copy-resources</goal>
                                 </goals>
                                 <configuration>
-                                    <artifactItems>
-                                        <artifactItem>
-                                            <groupId>net.shibboleth.idp</groupId>
-                                            <artifactId>${idp-conf.artifactId}</artifactId>
-                                            <version>${idp-to-be-tested.version}</version>
-                                            <type>jar</type>
-                                            <classifier>tests</classifier>
-                                            <includes>credentials/idp-userfacing.p12,credentials/idp-backchannel.p12</includes>
-                                        </artifactItem>
-                                    </artifactItems>
-                                    <outputDirectory>${test-distributions.directory}/tomcat-base/</outputDirectory>
+                                    <outputDirectory>${test-distributions.directory}/tomcat-base/credentials</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>src/test/credentials</directory>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!-- Set up *.tests.shibboleth.net wildcard cert -->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <version>3.1.0</version>
+                        <executions>
+                            <execution>
+                                <id>set-up-shib-tests-wildcard-cert</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <!-- Run only if environment variable is "true" -->
+                                    <target if="${env.shib_tests_p12}">
+                                        <!-- Download p12 file with authn using password from environment -->
+                                        <get src="https://build.shibboleth.net/jenkins-helpers/tls/tests.shibboleth.net.pfx"
+                                             dest="${test-distributions.directory}/tomcat-base/credentials/idp-userfacing.p12"
+                                             username="jenkins"
+                                             password="${env.shib_jenkins_helper_pwd}"
+                                             verbose="true" />
+                                        <!-- Replace p12 password -->
+                                        <replace
+                                            file="${test-distributions.directory}/tomcat-base/conf/catalina.properties"
+                                            token="changeit"
+                                            value="${env.shib_tests_op_tls_pwd}"
+                                            summary="true" />
+                                    </target>
                                 </configuration>
                             </execution>
                         </executions>
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java b/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java
index 859b22e..00d58c4 100644
--- a/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java
+++ b/src/test/java/net/shibboleth/idp/integration/tests/oidc/OIDCTest.java
@@ -40,7 +40,9 @@ import net.shibboleth.idp.integration.tests.BaseIntegrationTest;
 import net.shibboleth.idp.integration.tests.BrowserData;
 import net.shibboleth.shared.component.ComponentInitializationException;
 
-// WIP
+/**
+ * Test the OIDC OP plugin for the IdP.
+ */
 public class OIDCTest extends BaseIntegrationTest {
 
     /** Class logger. */
@@ -289,12 +291,13 @@ public class OIDCTest extends BaseIntegrationTest {
     /**
      * Set up static/openid-configuration.json.
      * 
-     * Set up dynamic publication by enabling the Jetty 'rewrite' module.
+     * For Jetty, set up dynamic publication using the Jetty 'rewrite'.
+     * 
+     * For Tomcat, set up dynamic publication using the rewrite Valve.
      * 
      * @throws IOException
      *             if an error occurs
      */
-    // TODO Jetty only
     protected void enableOIDCDiscovery() throws IOException {
 
         // static/openid-configuration.json
@@ -312,16 +315,36 @@ public class OIDCTest extends BaseIntegrationTest {
                 "\"issuer\":\"https://idp.tests.shibboleth.net:" + securePort + "\"", //
                 "\"issuer\":\"https://idp.tests.shibboleth.net\"");
 
-        enableJettyModule("rewrite");
+        // Jetty
+        if (pathToJettyBase != null) {
+
+            enableJettyModule("rewrite");
+
+            final Path pathToSourceRewriteRulesXML = Paths.get("src", "test", "oidc", "jetty-base", "etc",
+                    "rewrite-rules.xml");
 
-        final Path pathToSourceRewriteRulesXML = Paths.get("src", "test", "oidc", "jetty-base", "etc",
-                "rewrite-rules.xml");
+            assert pathToSourceRewriteRulesXML.toFile().exists() : "Path to rewrite-rules.xml not found";
+
+            final Path pathToTargetRewriteRulesXML = pathToJettyBase.resolve(Paths.get("etc", "rewrite-rules.xml"));
+
+            Files.copy(pathToSourceRewriteRulesXML, pathToTargetRewriteRulesXML, StandardCopyOption.REPLACE_EXISTING);
+        }
 
-        assert pathToSourceRewriteRulesXML.toFile().exists() : "Path to rewrite-rules.xml not found";
+        // Tomcat
+        if (pathToTomcatBase != null) {
 
-        final Path pathToTargetRewriteRulesXML = pathToJettyBase.resolve(Paths.get("etc", "rewrite-rules.xml"));
+            final Path pathToServerXML = pathToTomcatBase.resolve(Paths.get("conf", "server.xml"));
 
-        Files.copy(pathToSourceRewriteRulesXML, pathToTargetRewriteRulesXML, StandardCopyOption.REPLACE_EXISTING);
+            final String rewriteValve = "<Valve className=\"org.apache.catalina.valves.rewrite.RewriteValve\" />\n";
+
+            replaceFile(pathToServerXML, "</Host>", rewriteValve + "</Host>");
+
+            final Path pathToRewriteConfig = pathToTomcatBase.resolve(Paths.get("conf", "Catalina", "localhost", "rewrite.config"));
+
+            final String rewriteRule = "RewriteRule ^/\\.well-known/openid-configuration$ /idp/profile/oidc/configuration";
+
+            Files.write(pathToRewriteConfig, rewriteRule.getBytes());
+        }
     }
 
     /**
@@ -357,6 +380,23 @@ public class OIDCTest extends BaseIntegrationTest {
         replaceFile(pathToOIDCProperties, "https://your.issuer.example.org", "https://idp.tests.shibboleth.net");
     }
 
+    /**
+     * Set path to RP keystore to be credentials/idp-userfacing.p12 in either
+     * jetty-base/ or tomcat-base/ directories.
+     * 
+     * @param rp
+     *            the RP container
+     */
+    protected void setUpRPKeyStore(final RPContainer rp) {
+        final Path pathToContainerBase = pathToJettyBase != null ? pathToJettyBase : pathToTomcatBase;
+
+        final Path pathToKeyStore = pathToContainerBase.resolve((Paths.get("credentials", "idp-userfacing.p12")));
+
+        log.debug("Path to key store '{}'", pathToKeyStore);
+
+        rp.setKeyStore(pathToKeyStore.toAbsolutePath().toString());
+    }
+
     /**
      * Start RP.
      * 
@@ -381,6 +421,8 @@ public class OIDCTest extends BaseIntegrationTest {
 
         rp.setOPPort(securePort.toString());
 
+        setUpRPKeyStore(rp);
+
         rp.initialize();
 
         rp.start();
@@ -460,12 +502,20 @@ public class OIDCTest extends BaseIntegrationTest {
         Assert.assertTrue(response.contains(expectedIssuer), "Expected issuer not found");
     }
 
+    /**
+     * Test the IdP + OP plugin with 2 Docker OIDC RPs.
+     * 
+     * @param browserData
+     *            browser/os/version triplet provided by data provider
+     * @throws Exception
+     *             if an error occurs
+     */
     @Test(dataProvider = "sauceOnDemandBrowserDataProvider", enabled = false)
     public void testSSO(@Nullable final BrowserData browserData) throws Exception {
 
-        // Only run on Linux with Jetty
-        if (isWindows() || isTomcat()) {
-            log.debug("Skipping OIDC test, only runs on Linux with Jetty");
+        // Only run if IdP V5 or later on Linux
+        if (isWindows() || idpVersion.startsWith("4")) {
+            log.debug("Skipping OIDC test, only runs IdP V5 on Linux with Jetty");
             return;
         }
 
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java b/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java
index 0f88b06..4b5bd8f 100644
--- a/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java
+++ b/src/test/java/net/shibboleth/idp/integration/tests/oidc/RPContainer.java
@@ -17,22 +17,35 @@
 
 package net.shibboleth.idp.integration.tests.oidc;
 
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.Enumeration;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.Lifecycle;
 import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.containers.wait.strategy.Wait;
 import org.testcontainers.images.builder.ImageFromDockerfile;
+import org.testcontainers.images.builder.Transferable;
 import org.testcontainers.utility.MountableFile;
+import org.testng.Assert;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
@@ -45,8 +58,9 @@ import net.shibboleth.shared.logic.Constraint;
  * Default ServerName is rp.tests.shibboleth.net, may be overridden as system
  * property.
  * 
- * TLS cert and key should be copied to etc/pki/tls/ or path overridden as
- * environment variables.
+ * The TLS cert and key for the RP are extracted from a P12 keystore. The path
+ * to the keystore must be set and the password provided as an environment
+ * variable.
  * 
  * See src/test/docker/shib-tests-rp for Dockerfile and container files.
  */
@@ -73,6 +87,7 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
     public Integer httpsPort;
 
     /** Name of Docker image. */
+    @Nonnull
     public String image = "shib-tests-rp";
 
     /** Path to RP directory. */
@@ -80,20 +95,23 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
     private Path pathToRP;
 
     /** Port used by the OP. */
-    @NonnullAfterInit
+    @Nonnull
     private String opPort = "443";
 
-    /** RP client ID, defaults to 'test_oidc_rp'. */
+    /** RP client ID, default 'test_oidc_rp'. */
+    @Nonnull
     private String clientID = "test_oidc_rp";
 
-    /** RP redirect URI, defaults to '/redirect_uri'. */
+    /** RP redirect URI, default '/redirect_uri'. */
+    @Nonnull
     private String redirectURI = "/redirect_uri";
-
-    /** Environment variable path to TLS cert. */
-    final static String pathToTLSCertEnvVar = "shib_tests_rp_tls_crt";
     
-    /** Environment variable path to TLS key. */
-    final static String pathToTLSKeyEnvVar = "shib_tests_rp_tls_key";
+    /** Path to TLS keystore in P12 format. */
+    @NonnullAfterInit
+    private Path pathToKeyStore;
+
+    /** Environment variable containing TLS keystore password. */
+    final static String keyStorePasswordEnvVar = "shib_tests_op_tls_pwd";
 
     /**
      * Path to RP directory.
@@ -133,56 +151,6 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         return pathToDockerfile;
     }
 
-    /**
-     * Path to TLS cert.
-     * 
-     * Default path may be overridden using the {@link #pathToTLSCertEnvVar}
-     * environment variable.
-     * 
-     * @return path to TLS cert
-     */
-    protected Path pathToCert() {
-
-        final String defaultPathToCert = pathToRP().toString() + "/etc/pki/tls/certs/fullchain.cer";
-
-        final String envVarPathToCert = System.getenv(pathToTLSCertEnvVar);
-
-        final String pathToCert = envVarPathToCert != null ? envVarPathToCert : defaultPathToCert;
-
-        final Path path = Paths.get(pathToCert);
-
-        log.debug("{} Path to cert '{}'", getLogPrefix(), pathToCert);
-
-        assert path.toFile().exists() : "Path to TLS cert " + path + " does not exist";
-
-        return path;
-    }
-
-    /**
-     * Path to TLS key.
-     * 
-     * Default path may be overridden using the {@link #pathToTLSKeyEnvVar}
-     * environment variable.
-     * 
-     * @return path to TLS key
-     */
-    protected Path pathToKey() {
-
-        final String defaultPathToKey = pathToRP().toString() + "/etc/pki/tls/private/tests.shibboleth.net.key";
-
-        final String envVarPathToKey = System.getenv(pathToTLSKeyEnvVar);
-
-        final String pathToKey = envVarPathToKey != null ? envVarPathToKey : defaultPathToKey;
-
-        final Path path = Paths.get(pathToKey);
-
-        log.debug("{} Path to key '{}'", getLogPrefix(), pathToKey);
-
-        assert path.toFile().exists() : "Path to TLS key " + path + " does not exist";
-
-        return path;
-    }
-
     /**
      * Path to mod_auth_openidc configuration file.
      * 
@@ -230,6 +198,15 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         if (opPort == null) {
             throw new ComponentInitializationException("OP port cannot be null");
         }
+        
+        if (pathToKeyStore == null) {
+            throw new ComponentInitializationException("Path to keystore cannot be null");
+        }
+        
+        final String keyStorePassword = System.getenv(keyStorePasswordEnvVar);
+        if (keyStorePassword == null) {
+            throw new ComponentInitializationException("Keystore password environment variable not set");
+        }
 
         log.debug("{} Initializing", getLogPrefix());
 
@@ -239,11 +216,10 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         log.debug("{} Initializing with image '{}'", getLogPrefix(), imageFromDockerfile);
         container = new GenericContainer<>(imageFromDockerfile);
 
-        // Copy TLS cert and key to container
-        final MountableFile cert = MountableFile.forHostPath(pathToCert());
-        final MountableFile key = MountableFile.forHostPath(pathToKey());
-        container.withCopyFileToContainer(cert, "/etc/pki/tls/certs/localhost.crt");
-        container.withCopyFileToContainer(key, "/etc/pki/tls/private/localhost.key");
+        // Copy TLS certificate and key to container from P12 keystore
+        final Pair<String,String> certAndKey = extractCertAndKey(pathToKeyStore, keyStorePassword);        
+        container.withCopyToContainer(Transferable.of(certAndKey.getFirst()), "/etc/pki/tls/certs/localhost.crt");
+        container.withCopyToContainer(Transferable.of(certAndKey.getSecond()), "/etc/pki/tls/private/localhost.key");
 
         // Copy OpenID Connect configuration to container
         final MountableFile conf = MountableFile.forHostPath(pathToOpenIDCConf());
@@ -295,21 +271,6 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         return "https://" + getId() + ":" + httpsPort.toString();
     }
 
-    /**
-     * Return a prefix for logging messages for this component.
-     * 
-     * @return a string for insertion at the beginning of any log messages
-     */
-    @Nonnull
-    @NotEmpty
-    protected String getLogPrefix() {
-        if (logPrefix == null) {
-            logPrefix = "RP '" + getId() + "' :";
-        }
-        assert logPrefix != null;
-        return logPrefix;
-    }
-
     /**
      * Get the OIDC client ID.
      * 
@@ -349,6 +310,18 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         opPort = port;
     }
 
+    /**
+     * Set the path to the TLS keystore.
+     * 
+     * @param path
+     *            path to TLS keystore
+     */
+    public void setKeyStore(@Nonnull final String path) {
+        pathToKeyStore = Paths.get(path);
+        log.debug("{} Path to TLS keystore '{}'", getLogPrefix(), pathToKeyStore);
+        assert pathToKeyStore.toFile().exists() : "Path to TLS keystore " + path + " does not exist";
+    }
+
     /**
      * Set the OIDC client ID.
      * 
@@ -413,4 +386,94 @@ public class RPContainer extends AbstractIdentifiableInitializableComponent impl
         return isRunning;
     }
 
+    /**
+     * Extract the certificate and private key from a keystore in P12 format and
+     * return them in PEM format as strings.
+     * 
+     * @param pathToKeyStore
+     *            path to keystore
+     * @param password
+     *            keystore password
+     * @return pair consisting of the certificate and private key in PEM format
+     */
+    public static Pair<String, String> extractCertAndKey(@Nonnull final Path pathToKeyStore, @Nonnull final String password) {
+        try {
+            // Load the keystore
+            final KeyStore keyStore = KeyStore.getInstance("PKCS12");
+            keyStore.load(Files.newInputStream(pathToKeyStore), password.toCharArray());
+
+            // Keystore should contain only 1 alias
+            final Enumeration<String> aliases = keyStore.aliases();
+            Assert.assertTrue(aliases.hasMoreElements());
+            final String alias = aliases.nextElement();
+            Assert.assertFalse(aliases.hasMoreElements());
+
+            // Extract certificate
+            final Certificate certificate = keyStore.getCertificate(alias);
+            final String certtext = getCertificateAsPEM(certificate);
+
+            // Extract private key
+            final Key key = keyStore.getKey(alias, password.toCharArray());
+            final String keyText = getPrivateKeyAsPEM(key);
+
+            return new Pair<String, String>(certtext, keyText);
+        } catch (final Exception e) {
+            Assert.fail("Unable to extract certificate and key from P12 keystore", e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Get certificate as text in PEM format.
+     * 
+     * @param certificate
+     *            the certificate to convert
+     * @return certificate text in PEM format
+     * @throws CertificateEncodingException
+     *             if an error occurs
+     * @throws IOException
+     *             if an error occurs
+     */
+    public static String getCertificateAsPEM(@Nonnull final Certificate certificate)
+            throws CertificateEncodingException, IOException {
+        final StringWriter writer = new StringWriter();
+        final PemWriter pemWriter = new PemWriter(writer);
+        pemWriter.writeObject(new PemObject("CERTIFICATE", certificate.getEncoded()));
+        pemWriter.flush();
+        pemWriter.close();
+        return writer.toString();
+    }
+
+    /**
+     * Get private key as text in PEM format.
+     * 
+     * @param key
+     *            the key to convert
+     * @return the key as text in PEM format
+     * @throws IOException
+     *             if an error occurs
+     */
+    public static String getPrivateKeyAsPEM(@Nonnull final Key key) throws IOException {
+        final StringWriter writer = new StringWriter();
+        final PemWriter pemWriter = new PemWriter(writer);
+        pemWriter.writeObject(new PemObject("PRIVATE KEY", key.getEncoded()));
+        pemWriter.flush();
+        pemWriter.close();
+        return writer.toString();
+    }
+
+    /**
+     * Return a prefix for logging messages for this component.
+     * 
+     * @return a string for insertion at the beginning of any log messages
+     */
+    @Nonnull
+    @NotEmpty
+    protected String getLogPrefix() {
+        if (logPrefix == null) {
+            logPrefix = "RP '" + getId() + "' :";
+        }
+        assert logPrefix != null;
+        return logPrefix;
+    }
 }

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


More information about the commits mailing list