3

I'm trying to build an existing JavaEE project using Wildfly Swarm, but I keep running into an issue in one of my libraries. It is supposed to load a public key in PEM format from a server and use it to verify signatures. However, I keep getting this:

2017-06-08 20:55:59,229 ERROR [stderr] (default task-3) java.security.NoSuchProviderException: no such provider: BC
2017-06-08 20:55:59,234 ERROR [stderr] (default task-3)     at sun.security.jca.GetInstance.getService(GetInstance.java:83)
2017-06-08 20:55:59,238 ERROR [stderr] (default task-3)     at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
2017-06-08 20:55:59,238 ERROR [stderr] (default task-3)     at java.security.KeyFactory.getInstance(KeyFactory.java:211)
2017-06-08 20:55:59,239 ERROR [stderr] (default task-3)     at enterprises.mccollum.wmapp.ssauthclient.PublicKeySingleton.loadPubKey(PublicKeySingleton.java:83)
2017-06-08 20:55:59,239 ERROR [stderr] (default task-3)     at enterprises.mccollum.wmapp.ssauthclient.PublicKeySingleton.init(PublicKeySingleton.java:57)

The code that causes the trouble is here:

PublicKeySingleton.java snippet:
81:    PemObject pemPubKey = ldPemFromServer();
82:    if(pemPubKey != null){
83:    KeyFactory kf = KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
84:    PublicKey lPubKey =  kf.generatePublic(new X509EncodedKeySpec(pemPubKey.getContent()));
85:    Logger.getLogger(SSAuthClient.SUBSYSTEM_NAME).log(Level.INFO, "Read public key from url successfully");
86:    return lPubKey;

Here's the pom.xml for the library with the above code:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>enterprises.mccollum.wmapp</groupId>
    <artifactId>ssauthclient</artifactId>
    <version>1.0.5-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>enterprises.mccollum.utils</groupId>
            <artifactId>genericentityejb</artifactId>
            <version>1.0.5</version>
        </dependency>
        <dependency>
            <groupId>enterprises.mccollum.jee</groupId>
            <artifactId>urlutils</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.56</version>
            <!-- Tried changing the version to 1.52, as used by Swarm itself, but to no avail -->
        </dependency>
    </dependencies>
    <build>
        <finalName>ssauthclient</finalName>
        <extensions>
            <extension>
                <groupId>org.apache.maven.wagon</groupId>
                <artifactId>wagon-webdav</artifactId>
                <version>1.0-beta-2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <executions>
                    <execution>
                    <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

And here is the pom.xml for the Swarm project:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ie.countries.cdn</groupId>
    <artifactId>cbook</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <version.wildfly.swarm>2017.6.0</version.wildfly.swarm>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.wildfly.swarm</groupId>
                <artifactId>bom</artifactId>
                <version>${version.wildfly.swarm}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>enterprises.mccollum.wmapp</groupId>
            <artifactId>ssauthclient</artifactId>
            <version>1.0.5-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.1</version>
        </dependency>
        <dependency>
            <groupId>org.ocpsoft.rewrite</groupId>
            <artifactId>rewrite-servlet</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.ocpsoft.rewrite</groupId>
            <artifactId>rewrite-config-prettyfaces</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces.themes</groupId>
            <artifactId>bootstrap</artifactId>
            <version>1.0.10</version>
        </dependency>
        <dependency>
            <groupId>org.omnifaces</groupId>
            <artifactId>omnifaces</artifactId>
            <version>2.6.2</version>
        </dependency>
        <!-- WildFly Swarm Fractions -->
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>cdi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>ejb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>management</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>datasources</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.195</version>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>management-console</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>cdi-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>jsf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>jaxrs</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>cbook</finalName>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>META-INF/persistence.xml</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.wildfly.swarm</groupId>
                <artifactId>wildfly-swarm-plugin</artifactId>
                <version>${version.wildfly.swarm}</version>

                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

I'm very confused as to why this wouldn't work, especially when both the uberjar and war produced by mvn package include the bouncycastle provider dependency as a jar.

What is going wrong? Is this a bug in Swarm or am I missing a trick I need to do to get it to work?

KG6ZVP
  • 3,610
  • 4
  • 26
  • 45

2 Answers2

5

The provider is not in the JVM by default (you can check the list of providers in $JAVA_HOME/jre/lib/security/java.security or using Security.getProviders()).

You must add it using the Security class:

import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

Security.addProvider(new BouncyCastleProvider());

Some people prefer to check if the provider is already there, and add only if it's not:

// if provider is not present, add it
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
    // insert at specific position
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
}

The difference between the methods above is that addProvider adds the provider at the end of the providers list (the one returned by getProviders), and insertProviderAt adds it in the specified position (and the others are shifted).

Another alternative is to edit the $JAVA_HOME/jre/lib/security/java.security file and add the provider at the desired position:

security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider

More details about this method can be found here.

  • What makes this different from a regular Wildly instance? I can run the same application on a regular Java EE app server without going to that extra trouble. Or, should that not work and it's a bug? – KG6ZVP Jun 09 '17 at 12:03
  • Some servers might already load BouncyCastle at startup, or already have it configured somewhere. But it's not guaranteed that all servers will do that, so you'll have to add it by hand. You can use `getProvider` method to check if it's already loaded, and add it accordingly. –  Jun 09 '17 at 12:08
  • 1
    Thank you. I have corrected the library to do so and now have it working. – KG6ZVP Jun 09 '17 at 12:09
0

You need to install BouncyCastle as a provider. Two ways: First in pure java:

Security.addProvider(new BouncyCastleProvider());

Second method statically as an entry to the java.security file:

security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider

You need it in your classpath obviously.

JEY
  • 6,973
  • 1
  • 36
  • 51