
com.nimbusds.jose.jwk.loader.PKCS11Configuration Maven / Gradle / Ivy
Show all versions of nimbus-jwkset-loader Show documentation
package com.nimbusds.jose.jwk.loader;
import com.thetransactioncompany.util.PropertyParseException;
import com.thetransactioncompany.util.PropertyRetriever;
import net.jcip.annotations.Immutable;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
/**
* PKCS#11 configuration. Supports system properties override.
*
* Example configuration for an HSM:
*
*
* pkcs11.enable=true
* pkcs11.configFile=/WEB-INF/hsm.cfg
* pkcs11.password=ohNeC0iH
*
*
* Example configuration for an HSM to load only keys with the specified IDs
* (aliases):
*
*
* pkcs11.enable=true
* pkcs11.configFile=/WEB-INF/hsm.cfg
* pkcs11.password=ohNeC0iH
* pkcs11.keyIDs.1=c3c1f1ad-dfc8-4c76-96ce-2f31564d6ebd
* pkcs11.keyIDs.2=be196a4a-5a7f-4af1-8e4e-b45517339cf0
* pkcs11.keyIDs.3=86caefbe-e192-4628-8e6a-cc2380f50898
*
*/
@Immutable
public class PKCS11Configuration {
/**
* The default name of the PKCS#11 configuration file.
*/
static final String DEFAULT_CONFIG_FILENAME = "/WEB-INF/jose.properties";
/**
* The default configuration property name prefix.
*/
static final String DEFAULT_CONFIG_PROPERTY_PREFIX = "pkcs11.";
/**
* PKCS#11 enabled / disabled.
*/
private final boolean pkcs11Enabled;
/**
* The PKCS#11 configuration, specified by file name or inline (with
* optional additional BASE64URL encoding), {@code null} if not
* specified.
*/
private final String pkcs11ConfigFile;
/**
* The PKCS#11 password, empty if none or not applicable.
*/
private final char[] pkcs11KeyStorePassword;
/**
* The IDs of the PKCS#11 keys to load, empty list to load all.
*/
private final List pkcs11KeyIDs;
/**
* Creates a new default JOSE configuration.
*/
public PKCS11Configuration() {
this(new Properties());
}
/**
* Creates a new JOSE configuration with the specified properties.
* System properties override is disabled.
*
* @param props The configuration properties.
*/
public PKCS11Configuration(final Properties props) {
this(props, false);
}
/**
* Creates a new JOSE configuration with the specified properties.
*
* @param props The configuration properties.
* @param override Enables system properties override.
*/
public PKCS11Configuration(final Properties props, final boolean override) {
this(DEFAULT_CONFIG_PROPERTY_PREFIX, props, override);
}
/**
* Creates a new JOSE configuration with the specified properties.
*
* @param props The configuration properties.
* @param override Enables system properties override.
*/
public PKCS11Configuration(final String prefix, final Properties props, final boolean override) {
var pr = new PropertyRetriever(props, override);
try {
pkcs11Enabled = pr.getOptBoolean(prefix + "enable", false);
if (pkcs11Enabled) {
pkcs11ConfigFile = pr.getOptString(prefix + "configFile", null);
if (pkcs11ConfigFile == null || pkcs11ConfigFile.trim().isEmpty()) {
throw new RuntimeException("PKCS#11 is enabled by pkcs11.enable, " +
"but no PKCS#11 configuration is specified in " + prefix + "configFile");
}
String pw = pr.getOptString(prefix + "password", null);
if (pw == null || pw.trim().isEmpty()) {
pkcs11KeyStorePassword = "".toCharArray();
} else {
pkcs11KeyStorePassword = pw.trim().toCharArray();
}
pkcs11KeyIDs = pr.getOptStringListMulti(prefix + "keyIDs.", Collections.emptyList());
} else {
pkcs11ConfigFile = null;
pkcs11KeyStorePassword = "".toCharArray();
pkcs11KeyIDs = Collections.emptyList();
}
} catch (PropertyParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* Checks if PKCS#11 (HSM) is enabled.
*
* @return {@code true} if enabled, else {@code false}.
*/
public boolean isPKCS11Enabled() {
return pkcs11Enabled;
}
/**
* Returns the PKCS#11 (HSM) configuration, specified as file name or
* inline (with optional additional BASE64URL encoding).
*
* See https://docs.oracle.com/en/java/javase/11/security/pkcs11-reference-guide1.html#GUID-C4ABFACB-B2C9-4E71-A313-79F881488BB9
*
* @return The PKCS#11 configuration, {@code null} if not specified.
*/
public String getPKCS11ConfigurationFile() {
return pkcs11ConfigFile;
}
/**
* Returns the PKCS#11 (HSM) password (or PIN).
*
* @return The password, empty array if none.
*/
public char[] getPKCS11KeyStorePassword() {
return pkcs11KeyStorePassword;
}
/**
* Returns {@code true} if a PKCS#11 (HSM) password is configured.
*
* @return {@code true} if a password is configured, {@code false} if
* not.
*/
public boolean hasPKCS11KeyStorePassword() {
return getPKCS11KeyStorePassword().length > 0;
}
/**
* Returns the specific PKCS#11 key IDs (aliases) to load if PKCS#11
* (HSM) is enabled.
*
* @return The PKCS#11 key IDs to load, empty list to load all keys
* found in the PKCS#11 (HSM) store.
*/
public List getPKCS11KeyIDs() {
return pkcs11KeyIDs;
}
/**
* Logs the configuration at INFO level.
*
* @param logger The logger.
*/
public void log(final Logger logger) {
if (logger == null) {
return;
}
logger.info("[SE0001] PKCS#11 enabled: {}", isPKCS11Enabled());
if (isPKCS11Enabled()) {
logger.info("[SE0002] PKCS#11 configuration file: {}", getPKCS11ConfigurationFile());
logger.info("[SE0003] PKCS#11 password configured: {}", hasPKCS11KeyStorePassword());
logger.info("[SE0004] PKCS#11 key IDs to load: {}",
getPKCS11KeyIDs().isEmpty() ? "all" : getPKCS11KeyIDs());
}
}
/**
* Loads a JOSE configuration using the specified file input stream
* source. System properties override is enabled.
*
* @param fisSource The file input source. Must not be {@code null}.
*
* @return The JOSE configuration.
*
* @throws IOException If an I/O exception is encountered.
*/
static PKCS11Configuration load(final FileInputStreamSource fisSource)
throws IOException {
InputStream is = fisSource.getInputSteam(DEFAULT_CONFIG_FILENAME);
var properties = new Properties();
if (is != null) {
properties.load(is);
}
return new PKCS11Configuration(properties, true);
}
}