Skip to content

Instantly share code, notes, and snippets.

@p7cq
Last active March 20, 2024 08:20
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save p7cq/d8922d81279dddb3c9e5eb3c7e7be5eb to your computer and use it in GitHub Desktop.
Save p7cq/d8922d81279dddb3c9e5eb3c7e7be5eb to your computer and use it in GitHub Desktop.
EJBCA CE & Nitrokey HSM - A lab PKI

EJBCA CE & Nitrokey HSM - A lab PKI

Configuration steps for a lab CA, created using EJBCA CE and Nitrokey HSM.

Installation details

Hardware: Raspberry Pi 4 Model B

Crypto token: Nitrokey HSM 2

OS: Fedora

Host name: ca.example.com

Host IP: 10.10.10.10

DB: MySQL 8.0.31

DB host: mysql.example.com

OS user: pki

Host configuration

All commands are run as a regular user (pki), unless prefixed with #.

Operating system

Fedora 37 Server, AARCH64, minimal installation.

Create user

# useradd -d /home/pki -m -s /bin/bash pki

Directory layout

The software stack will be installed under the following directory structure:

<EJBCA Base>
    ejbca
    ejbca-custom
    java
	    ant
	    jdk
    library
    middleware

Create EJBCA base directory structure and give necessary permissions to pki

# mkdir -p /local/pki/{ejbca,java,library,middleware,ejbca-custom}
# chown -R pki:pki /local/pki

User environment configuration

Login as pki, create file .bashrc.d/ejbca.environment, add the variables below then reload environment.

umask 027

export EJBCA_BASE=/local/pki
export EJBCA_HOME=$EJBCA_BASE/ejbca
export JAVA_HOME=$EJBCA_BASE/java/jdk
export ANT_HOME=$EJBCA_BASE/java/ant
export APPSRV_HOME=$EJBCA_BASE/middleware/home

export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$APPSRV_HOME/bin:$EJBCA_HOME/bin:$PATH

Prepare system for HSM

Skip if no HSM is used.

Install software

Nitrokey HSM
# dnf install opensc -y
SoftHSM
# dnf install softhsm -y

Give pki user permissions to use the HSM

# usermod -aG ods pki

Re-login to activate changes.

Initialize HSM

The HSM must be initialized before use.

Nitrokey HSM

If the HSM is not initialized, see this for details.

SoftHSM

Initialize HSM:

softhsm2-util --init-token --free --label soft-hsm
Slot 0 has a free/uninitialized token.
=== SO PIN (4-255 characters) ===
Please enter SO PIN: *******
Please reenter SO PIN: *******
=== User PIN (4-255 characters) ===
Please enter user PIN: *******
Please reenter user PIN: *******
The token has been initialized and is reassigned to slot 1741639722

Install Java tools

The recommended JDK version is Java 11, but I was unable to generate keys on Nitrokey HSM due to what appears to be a bug in EJBCA CE. The workaround I found was to use Java 8, which is also supported.

Note: I tested recently with EJBCA 8.0 CE and Java 17.0.8.0.2, issue is fixed. See Generate keys on Nitrokey HSM for details.

Download, extract and move Java 8 and Apache Ant to $EJBCA_BASE/java/jdk and $EJBCA_BASE/java/ant, respectively.

If using Java 8 also download Java 11 as it will be needed later to bootstrap the application server.

Database configuration

Create needed configuration

CREATE DATABASE ejbca CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ejbca'@'10.10.10.10' IDENTIFIED BY 'changeit';
GRANT ALL PRIVILEGES ON ejbca.* TO 'ejbca'@'10.10.10.10';
CREATE USER 'ocsp'@'10.10.10.10' IDENTIFIED BY 'changeit';
GRANT SELECT ON ejbca.* TO 'ocsp'@'10.10.10.10';
FLUSH PRIVILEGES;

Application server configuration

Run all commands with the log file and the terminal side by side. Make sure no errors occur while executing any of the following steps. If that is the case, start again. If runinstall fails, recreate the database to ensure a clean slate.

Bootstrap WildFly

Download and extract Galleon

cd $EJBCA_BASE/library && curl -OL https://github.com/wildfly/galleon/releases/download/5.0.6.Final/galleon-5.0.6.Final.zip && unzip -q galleon-5.0.6.Final.zip
cd galleon-5.0.6.Final/bin

If using Java 8, switch to Java 11 temporarily.

Run galleon.sh to download only the layers needed by EJBCA

./galleon.sh install wildfly:current#26.1.2.Final --dir=$EJBCA_BASE/library/wildfly-26.1.2.Final --default-configs=standalone/standalone.xml --layers=cdi,core-tools,datasources,deployment-scanner,discovery,ee,-jsonb,ejb,io,jaxrs,jpa,jsf,logging,mail,management,webservices

Remove Galleon

cd $EJBCA_BASE
rm -rf $EJBCA_BASE/library/galleon*

If using Java 8 make sure the correct JDK is set.

Create a symbolic link for application server home

ln -s $EJBCA_BASE/library/wildfly-26.1.2.Final $EJBCA_BASE/middleware/home

The JBoss client JAR is not available when installing with Galleon, we need to add it for CLI tools to work

mkdir $APPSRV_HOME/bin/client
curl https://repo1.maven.org/maven2/org/wildfly/wildfly-client-all/26.1.2.Final/wildfly-client-all-26.1.2.Final.jar -o $APPSRV_HOME/bin/client/jboss-client.jar

Remove RESTEasy-Crypto

sed -i '/.*org.jboss.resteasy.resteasy-crypto.*/d' $APPSRV_HOME/modules/system/layers/base/org/jboss/as/jaxrs/main/module.xml
rm -rf $APPSRV_HOME/modules/system/layers/base/org/jboss/resteasy/resteasy-crypto/

WildFly configuration

Using TLSv1.3 only. For this to work, make sure you're using the latest Java 8 (should be 1.8.0_261+).

Replace content of $APPSRV_HOME/bin/standalone.conf with

if [ "x$JBOSS_MODULES_SYSTEM_PKGS" = "x" ]; then
     JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman"
fi

if [ "x$JAVA_OPTS" = "x" ]; then
     JAVA_OPTS="-Xms{{ HEAP_SIZE }}m -Xmx{{ HEAP_SIZE }}m -XX:MetaspaceSize=1024m -XX:MaxMetaspaceSize=1024m"
     JAVA_OPTS="$JAVA_OPTS -Dhttps.protocols=TLSv1.3"
     JAVA_OPTS="$JAVA_OPTS -Djdk.tls.client.protocols=TLSv1.3"
     JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true"
     JAVA_OPTS="$JAVA_OPTS -Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS"
     JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true"
     JAVA_OPTS="$JAVA_OPTS -Djboss.tx.node.id={{ TX_NODE_ID }}"
     JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError"
     JAVA_OPTS="$JAVA_OPTS -Djdk.tls.ephemeralDHKeySize=2048"
     #JAVA_OPTS="$JAVA_OPTS --add-exports=jdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED"
else
     echo "JAVA_OPTS already set in environment; overriding default settings with values: $JAVA_OPTS"
fi

then configure Java heap size and jboss.tx.node.id

sed -i -e 's/{{ HEAP_SIZE }}/4096/g' $APPSRV_HOME/bin/standalone.conf
sed -i -e "s/{{ TX_NODE_ID }}/$(od -A n -t d -N 1 /dev/urandom | tr -d ' ')/g" $APPSRV_HOME/bin/standalone.conf

Optionally, create a copy of the application server directory

cp -a $EJBCA_BASE/library/wildfly-26.1.2.Final $EJBCA_BASE/library/wildfly-26.1.2.Final.initial

Server start

standalone.sh

Note that systemd can be used, see the official documentation for details.

Elytron store configuration

Create master password

echo '#!/bin/sh' > $APPSRV_HOME/bin/wildfly_pass
echo "echo '$(openssl rand -base64 24)'" >> $APPSRV_HOME/bin/wildfly_pass
chmod 500 $APPSRV_HOME/bin/wildfly_pass

Create credential store

mkdir $APPSRV_HOME/standalone/configuration/keystore
jboss-cli.sh --connect '/subsystem=elytron/credential-store=defaultCS:add(path=keystore/credentials, relative-to=jboss.server.config.dir, credential-reference={clear-text="{EXT}wildfly_pass", type="COMMAND"}, create=true)'

Add database driver

curl -O https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.31/mysql-connector-j-8.0.31.jar
mv mysql-connector-j-8.0.31.jar $APPSRV_HOME/standalone/deployments/mysql-java-client.jar

Data source configuration

jboss-cli.sh --connect '/subsystem=elytron/credential-store=defaultCS:add-alias(alias=dbPassword, secret-value="changeit")'
jboss-cli.sh --connect 'data-source add --name=ejbcads --connection-url="jdbc:mysql://mysql.example.com:3306/ejbca" --jndi-name="java:/EjbcaDS" --use-ccm=true --driver-name="mysql-java-client.jar" --driver-class="com.mysql.cj.jdbc.Driver" --user-name="ejbca" --credential-reference={store=defaultCS, alias=dbPassword} --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1;"'
jboss-cli.sh --connect 'data-source add --name=ocspds --driver-name="mysql-java-client.jar" --connection-url="jdbc:mysql://mysql.example.com:3306/ejbca" --jndi-name="java:/OcspDS" --use-ccm=true --driver-class="com.mysql.cj.jdbc.Driver" --user-name="ocsp" --credential-reference={store=defaultCS, alias=dbPassword} --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --check-valid-connection-sql="select 1;"'
jboss-cli.sh --connect ':reload'

Remoting configuration

jboss-cli.sh --connect '/subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=connector-ref,value=remoting)'
jboss-cli.sh --connect '/socket-binding-group=standard-sockets/socket-binding=remoting:add(port=4447,interface=management)'
jboss-cli.sh --connect '/subsystem=undertow/server=default-server/http-listener=remoting:add(socket-binding=remoting,enable-http2=true)'
jboss-cli.sh --connect ':reload'

Logging configuration

Set quiet logging

jboss-cli.sh --connect '/subsystem=logging/logger=org.cesecore.audit.impl.log4j.Log4jDevice:add(level=WARN)'
jboss-cli.sh --connect '/subsystem=logging/logger=org.ejbca:add(level=WARN)'
jboss-cli.sh --connect '/subsystem=logging/logger=org.cesecore:add(level=WARN)'

HTTP(S) configuration

Remove existing TLS/HTTP configuration

jboss-cli.sh --connect '/subsystem=undertow/server=default-server/http-listener=default:remove()'
jboss-cli.sh --connect '/socket-binding-group=standard-sockets/socket-binding=http:remove()'
jboss-cli.sh --connect '/socket-binding-group=standard-sockets/socket-binding=https:remove()'
jboss-cli.sh --connect ':reload'

Allow pki to run services on privileged ports

Set the capability for java binary

# setcap CAP_NET_BIND_SERVICE=+eip /local/pki/java/jdk/bin/java

Configure the dynamic linker (for Java 8; architecture specific)

# echo "/local/pki/java/jdk/lib/aarch64/jli" > /etc/ld.so.conf.d/ejbca.conf

or

# echo -e "/local/pki/java/jdk/lib/jli\n/local/pki/java/jdk/jre/lib/jli" > /etc/ld.so.conf.d/ejbca.conf

for Java 11.

Update the dynamic linker

# ldconfig

Two-port separation

Other configurations are possible, see the official documentation.

Add interfaces and sockets

jboss-cli.sh --connect '/interface=http:add(inet-address="10.10.10.10")'
jboss-cli.sh --connect '/interface=https:add(inet-address="10.10.10.10")'
jboss-cli.sh --connect '/socket-binding-group=standard-sockets/socket-binding=http:add(port="80",interface="http")'
jboss-cli.sh --connect '/socket-binding-group=standard-sockets/socket-binding=https:add(port="443",interface="https")'

Configure TLS

Using TLSv1.3 only. Cipher suites adjusted to match protocol.

jboss-cli.sh --connect '/subsystem=elytron/credential-store=defaultCS:add-alias(alias=httpsKeystorePassword, secret-value="changeit")'
jboss-cli.sh --connect '/subsystem=elytron/credential-store=defaultCS:add-alias(alias=httpsTruststorePassword, secret-value="changeit")'
jboss-cli.sh --connect '/subsystem=elytron/key-store=httpsKS:add(path="keystore/keystore.jks",relative-to=jboss.server.config.dir,credential-reference={store=defaultCS, alias=httpsKeystorePassword},type=JKS)'
jboss-cli.sh --connect '/subsystem=elytron/key-store=httpsTS:add(path="keystore/truststore.jks",relative-to=jboss.server.config.dir,credential-reference={store=defaultCS, alias=httpsTruststorePassword},type=JKS)'
jboss-cli.sh --connect '/subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,algorithm="SunX509",credential-reference={store=defaultCS, alias=httpsKeystorePassword})'
jboss-cli.sh --connect '/subsystem=elytron/trust-manager=httpsTM:add(key-store=httpsTS)'
jboss-cli.sh --connect '/subsystem=elytron/server-ssl-context=https:add(key-manager=httpsKM,protocols=["TLSv1.3"],use-cipher-suites-order=false,cipher-suite-names="TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256",trust-manager=httpsTM,want-client-auth=true,authentication-optional=true)'

Add HTTP(S) listeners

jboss-cli.sh --connect '/subsystem=undertow/server=default-server/http-listener=http:add(socket-binding="http", redirect-socket="https")'
jboss-cli.sh --connect '/subsystem=undertow/server=default-server/https-listener=https:add(socket-binding="https", ssl-context="https", max-parameters=2048)'
jboss-cli.sh --connect ':reload'

Configure firewall

# firewall-cmd --add-service http --permanent
# firewall-cmd --add-service https --permanent
# firewall-cmd --reload

HTTP protocol behavior configuration

jboss-cli.sh --connect '/system-property=org.apache.catalina.connector.URI_ENCODING:add(value="UTF-8")'
jboss-cli.sh --connect '/system-property=org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING:add(value=true)'
jboss-cli.sh --connect '/system-property=org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:add(value=true)'
jboss-cli.sh --connect '/system-property=org.apache.tomcat.util.http.Parameters.MAX_COUNT:add(value=2048)'
jboss-cli.sh --connect '/system-property=org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:add(value=true)'
jboss-cli.sh --connect '/subsystem=webservices:write-attribute(name=wsdl-host, value=jbossws.undefined.host)'
jboss-cli.sh --connect '/subsystem=webservices:write-attribute(name=modify-wsdl-address, value=true)'
jboss-cli.sh --connect ':reload'

Galleon specific configuration

Add security domain to Undertow

jboss-cli.sh --connect '/subsystem=undertow/application-security-domain=other:add(security-domain=ApplicationDomain)'
jboss-cli.sh --connect ':reload' 

Optional configuration

Redirect to application for known URLs

jboss-cli.sh --connect '/subsystem=undertow/configuration=filter/rewrite=redirect-to-app:add(redirect=true,target="/ejbca/")'
jboss-cli.sh --connect '/subsystem=undertow/server=default-server/host=default-host/filter-ref=redirect-to-app:add(priority=1,predicate="method(GET) and not path-prefix(/ejbca,/crls,/certificates,/.well-known) and not equals({\%{LOCAL_PORT}, 4447})")'

Enable HSTS

Skipped; ca.example.com will serve resources over HTTP (CRLs, OCSP responses).

URL rewriting for OCSP responder

jboss-cli.sh --connect '/subsystem=undertow/configuration=filter/rewrite=rewrite-ocsp:add(target="/ejbca/publicweb/status/ocsp")'
jboss-cli.sh --connect '/subsystem=undertow/server=default-server/host=default-host/filter-ref=rewrite-ocsp:add(predicate="path(/ocsp) and method(GET,POST)")'

Add a request limiter

jboss-cli.sh --connect '/subsystem=undertow/configuration=filter/request-limit=ejbca-request-limiter:add(max-concurrent-requests=100,queue-size=300)'
jboss-cli.sh --connect '/subsystem=undertow/server=default-server/host=default-host/filter-ref=ejbca-request-limiter:add(predicate=path-prefix(/ejbca)'

Add support for email

jboss-cli.sh --connect '/subsystem=elytron/credential-store=defaultCS:add-alias(alias=smtpPassword, secret-value="changeit")'
jboss-cli.sh --connect '/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=ejbca-mail-smtp:add(port="587", host="mail.example.com")'
jboss-cli.sh --connect '/subsystem=mail/mail-session="java:/EjbcaMail":add(jndi-name=java:/EjbcaMail, from=no-reply@example.com)'
jboss-cli.sh --connect '/subsystem=mail/mail-session="java:/EjbcaMail"/server=smtp:add(outbound-socket-binding-ref=ejbca-mail-smtp, tls=true, username=yellow-ca@example.com, credential-reference={store=defaultCS, alias=smtpPassword})'
jboss-cli.sh --connect ':reload'

Only deploy at startup

jboss-cli.sh --connect '/subsystem=deployment-scanner/scanner=default:write-attribute(name=scan-interval,value=0)'

Increase deployment timeout

jboss-cli.sh --connect '/subsystem=deployment-scanner/scanner=default:write-attribute(name=deployment-timeout,value=300)'

If for some reason this is not enough, and timeout errors are thrown during startup, further increase the above value, while also modifying $APPSRV_HOME/bin/standalone.conf by adding the parameter below with the same value, e.g.

     JAVA_OPTS="$JAVA_OPTS -Djboss.as.management.blocking.timeout=600"

Default value of jboss.as.management.blocking.timeout is 300.

Disable management console

jboss-cli.sh --connect '/core-service=management/management-interface=http-interface:write-attribute(name=console-enabled,value=false)'
jboss-cli.sh --connect ':reload'

Increase maximum upload size

For two-port separation:

jboss-cli.sh --connect '/subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=max-post-size,value=25485760)'
jboss-cli.sh --connect ':reload'

Create a snapshot of configuration

jboss-cli.sh --connect ':take-snapshot(name="Initial configuration")'
cp $APPSRV_HOME/standalone/configuration/standalone.xml $EJBCA_BASE/library/standalone.xml.initial

Optionally, stop server and create a backup of the application server directory:

cp -a $EJBCA_BASE/library/wildfly-26.1.2.Final $EJBCA_BASE/library/wildfly-26.1.2.Final.gold

EJBCA configuration as CA with Management CA

Download and extract EJBCA CE, then move it to $EJBCA_BASE/ejbca.

mv $EJBCA_BASE/library/ejbca_ce_7_10_0_2 $EJBCA_BASE/ejbca

Customization

Copy configuration files into ejbca-custom:

cp -a $EJBCA_BASE/ejbca/conf $EJBCA_BASE/ejbca-custom

The following will list only changed lines in existing files.

For each changed file, remove .sample from its name.

catoken.properties

This file is used for CLI operations only.

If no HSM is used, skip this file.

Nitrokey HSM
sharedLibrary /usr/lib64/pkcs11/opensc-pkcs11.so
slotLabelType=SLOT_NUMBER
slotLabelValue=0

# Management CA key configuration
defaultKey mcaDefaultKey
certSignKey mcaSignKey
crlSignKey mcaSignKey
testKey rTestKey
SoftHSM
sharedLibrary /usr/lib64/softhsm/libsofthsm.so
slotLabelType=SLOT_NUMBER
slotLabelValue=1741639722

# Management CA key configuration
defaultKey mcaDefaultKey
certSignKey mcaSignKey
crlSignKey mcaSignKey
testKey rTestKey

cesecore.properties

allow.external-dynamic.configuration=true
password.encryption.key=changeit
ca.keystorepass=changeit
ca.serialnumberoctetsize=16

custom.properties

customejbca.home=${ejbca.home}/../ejbca-custom

database.properties

database.name=mysql
database.url=jdbc:mysql://mysql.example.com:3306/ejbca
database.driver=com.mysql.cj.jdbc.Driver
database.username=ejbca
database.password=changeit

ejbca.properties

appserver.type=jboss
ejbca.productionmode=true
allow.external-dynamic.configuration=true
ca.cmskeystorepass=changeit
ejbca.cli.defaultpassword=changeit

install.properties

ca.name=Yellow Management CA
ca.dn=C=SE,O=Yellow,CN=Yellow Management CA
# don't change ca.tokentype if no HSM 
ca.tokentype=org.cesecore.keys.token.PKCS11CryptoToken
# don't change ca.tokenpassword if no HSM, otherwise set the defined PIN
ca.tokenpassword=648219
# don't change ca.tokenproperties if no HSM 
ca.tokenproperties=/local/pki/ejbca-custom/conf/catoken.properties
ca.keyspec=4096
ca.signaturealgorithm=SHA384WithRSA

mail.properties

mail.jndi-name=java:/EjbcaMail
mail.user=yellow-ca@example.com
mail.password=changeit
mail.smtp.host=mail.example.com
mail.smtp.port=587
mail.smtp.auth=true
mail.smtp.starttls.enable=true
mail.from=no-reply@example.com

ocsp.properties

ocsp.enabled=true

va-publisher.properties

ocsp-datasource.jndi-name=OcspDS
ocsp-database.url=jdbc:mysql://mysql.example.com:3306/ejbca
ocsp-database.driver=com.mysql.cj.jdbc.Driver
ocsp-database.username=ocsp
ocsp-database.password=changeit

web.properties

java.trustpassword=changeit
superadmin.cn=SuperAdmin
superadmin.dn=C=SE,O=Yellow,CN=${superadmin.cn}
superadmin.password=changeit
httpsserver.password=changeit
httpsserver.hostname=ca.example.com
httpsserver.dn=CN=${httpsserver.hostname}
httpserver.pubhttp=80
httpserver.pubhttps=443
httpserver.external.privhttps=443
httpserver.external.fqdn=${httpsserver.hostname}

Cleanup

Remove unmodified files

rm -rf $EJBCA_BASE/ejbca-custom/conf/*.sample

Create and deploy EAR

modules/ejbca-ejb-cli/src/org/ejbca/ui/cli/ca/CaInitCommand.java:        cainfo.setDescription(caname + "created using CLI");

Create EJBCA EAR

cd $EJBCA_HOME
ant -q clean deployear

Restart WildFly to deploy EJBCA.

Generate client tools

ant clientToolBox
cp -a $EJBCA_HOME/dist/clientToolBox/* $EJBCA_HOME/bin

Prepare HSM

Skip if no HSM is used.

Generate keys on Nitrokey HSM

pkcs11HSM.sh generate /usr/lib64/pkcs11/opensc-pkcs11.so 4096 mcaDefaultKey 0
pkcs11HSM.sh generate /usr/lib64/pkcs11/opensc-pkcs11.so 4096 mcaSignKey 0
pkcs11HSM.sh generate /usr/lib64/pkcs11/opensc-pkcs11.so 1024 rTestKey 0

Check keys are created on HSM

pkcs15-tool -D

Using Java 17 (17.0.8.0.2) and EJBCA CE 8.0, I was able to generate RSA keys on Nitrokey HSM by modifying ejbcaClientToolBox.sh and adding in Java options --add-exports=jdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED.

ejbcaClientToolBox.sh PKCS11HSMKeyTool generate /usr/lib64/pkcs11/opensc-pkcs11.so 4096 defaultKey 0
Using Slot Reference Type: Slot Number.
PKCS11 Token [SunPKCS11-opensc-pkcs11.so-slot0] Password:

342395 [main] INFO  com.keyfactor.util.keys.SignWithWorkingAlgorithm  - Signature algorithm 'SHA256WithRSA' working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 17'.
Created certificate with entry defaultKey.

With Java 11 key generation fails

pkcs11HSM.sh generate /usr/lib64/pkcs11/opensc-pkcs11.so 4096 defaultKey 0
Using Slot Reference Type: Slot Number.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.cesecore.keys.token.p11.SunP11SlotListWrapper (file:/local/pki/ejbca/dist/clientToolBox/lib/cesecore-common.jar) to method sun.security.pkcs11.wrapper.PKCS11.getInstance(java.lang.String,java.lang.String,sun.security.pkcs11.wrapper.CK_C_INITIALIZE_ARGS,boolean)
WARNING: Please consider reporting this to the maintainers of org.cesecore.keys.token.p11.SunP11SlotListWrapper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
PKCS11 Token [SunPKCS11-opensc-pkcs11.so-slot0] Password:
2022-11-22 18:36:01,664 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA256WithRSA' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: Signing certificate failed: cannot create signer: no such algorithm: SHA256WITHRSA for provider SunPKCS11-opensc-pkcs11.so-slot0
sun.security.pkcs11.P11PSSSignature@6dd93a21: Calling C_SignUpdate
2022-11-22 18:36:01,820 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA256withRSAandMGF1' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DATA_LEN_RANGE
sun.security.pkcs11.P11PSSSignature@368d5c00: Calling C_SignUpdate
2022-11-22 18:36:01,970 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA384withRSAandMGF1' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DATA_LEN_RANGE
sun.security.pkcs11.P11PSSSignature@12a160c2: Calling C_SignUpdate
2022-11-22 18:36:02,127 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA512withRSAandMGF1' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DATA_LEN_RANGE
2022-11-22 18:36:02,130 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA384WithRSA' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: Signing certificate failed: cannot create signer: no such algorithm: SHA384WITHRSA for provider SunPKCS11-opensc-pkcs11.so-slot0
2022-11-22 18:36:02,133 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA512WithRSA' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: Signing certificate failed: cannot create signer: no such algorithm: SHA512WITHRSA for provider SunPKCS11-opensc-pkcs11.so-slot0
2022-11-22 18:36:02,136 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA3-256withRSA' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: Signing certificate failed: cannot create signer: no such algorithm: 2.16.840.1.101.3.4.3.14 for provider SunPKCS11-opensc-pkcs11.so-slot0
2022-11-22 18:36:02,138 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA3-384withRSA' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: Signing certificate failed: cannot create signer: no such algorithm: 2.16.840.1.101.3.4.3.15 for provider SunPKCS11-opensc-pkcs11.so-slot0
2022-11-22 18:36:02,141 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] Signature algorithm 'SHA3-512withRSA' not working for provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'. Exception: Signing certificate failed: cannot create signer: no such algorithm: 2.16.840.1.101.3.4.3.16 for provider SunPKCS11-opensc-pkcs11.so-slot0
2022-11-22 18:36:02,143 INFO  [org.cesecore.keys.util.SignWithWorkingAlgorithm] No valid signing algorithm found for the provider 'SunPKCS11-opensc-pkcs11.so-slot0 version 11'.
Command could not be executed. See log for stack trace.
2022-11-22 18:36:02,148 ERROR [org.ejbca.ui.cli.HSMKeyTool] Command 'PKCS11HSMKeyTool generate /usr/lib64/pkcs11/opensc-pkcs11.so 4096 defaultKey 0' could not be executed.
org.cesecore.keys.KeyCreationException: Can't create keystore because dummy certificate chain creation failed.
        at org.cesecore.keys.util.KeyStoreTools.generateKeyPair(KeyStoreTools.java:471) ~[cesecore-common.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.cesecore.keys.util.KeyStoreTools.generateRSA(KeyStoreTools.java:302) ~[cesecore-common.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.cesecore.keys.util.KeyStoreTools.generateKeyPair(KeyStoreTools.java:362) ~[cesecore-common.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.ejbca.ui.cli.HSMKeyTool.doIt(HSMKeyTool.java:243) ~[clientToolBox.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.ejbca.ui.cli.HSMKeyTool.execute(HSMKeyTool.java:730) [clientToolBox.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.ejbca.ui.cli.ClientToolBox.executeIfSelected(ClientToolBox.java:40) [clientToolBox.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.ejbca.ui.cli.ClientToolBox.main(ClientToolBox.java:72) [clientToolBox.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
Caused by: java.security.cert.CertificateException: Self signing of certificate failed.
        at org.cesecore.keys.util.KeyStoreTools.getSelfCertificate(KeyStoreTools.java:201) ~[cesecore-common.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        at org.cesecore.keys.util.KeyStoreTools.generateKeyPair(KeyStoreTools.java:454) ~[cesecore-common.jar:EJBCA 7.10.0.2 Community (31768d4428323576dd0466388ed69cabf5cb779d)]
        ... 6 more

SoftHSM

pkcs11HSM.sh generate /usr/lib64/softhsm/libsofthsm.so 4096 mcaDefaultKey 1741639722
pkcs11HSM.sh generate /usr/lib64/softhsm/libsofthsm.so 4096 mcaSignKey 1741639722
pkcs11HSM.sh generate /usr/lib64/softhsm/libsofthsm.so 1024 rTestKey 1741639722

Install CA

ant runinstall

If this step fails, especially when using a HSM, stop the server, remove WildFly directory, remove the database, and start again. If a known good configuration is available, restore it and start from that point.

Deploy TLS keystore

ant deploy-keystore

Restart server.

Access EJBCA web UI

Get the root certificate and copy it on the local machine together with the Super Admin's keystore from $EJBCA_HOME/p12/superadmin.p12.

ejbca.sh ca getcacert --caname "Yellow Management CA" -f /tmp/mca.pem

Import both in the user keystore (e.g., using certmgr.msc). Restart the browser if it was already running and go to https://ca.example.com - the web UIs can now be accessed.

Administration console: https://ca.example.com/ejbca/adminweb

RA console: https://ca.example.com/ejbca/ra

System configuration

Configuration Checker: enable EJBCA Configuration Checker and EJBCA common

Basic Configurations: check Hide Public Web

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment