com.nimbusds.jose.jwk.loader.JOSEConfiguration 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;
/**
* JOSE and 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 that will load only the keys with the
* specified IDs (alias):
*
*
* 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
*
*
* Example configuration allowing weak RSA keys (< 2048 bits):
*
*
* jose.allowWeakKeys=true
*
*/
@Immutable
class JOSEConfiguration {
/**
* The name of the JOSE configuration file.
*/
static final String FILENAME = "/WEB-INF/jose.properties";
/**
* If {@code true} weak RSA keys shorter than 2048 bits will be
* allowed. The default value if {@code false}.
*/
private final boolean allowWeakKeys;
/**
* 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 JOSEConfiguration() {
this(new Properties());
}
/**
* Creates a new JOSE configuration with the specified properties.
* System properties override is disabled.
*
* @param props The configuration properties, {@code null} if none.
*/
public JOSEConfiguration(final Properties props) {
this(props, false);
}
/**
* Creates a new JOSE configuration with the specified properties.
*
* @param props The configuration properties, {@code null} if none.
* @param override Enables system properties override.
*/
public JOSEConfiguration(final Properties props, final boolean override) {
var pr = new PropertyRetriever(props, override);
try {
allowWeakKeys = pr.getOptBoolean("jose.allowWeakKeys", false);
pkcs11Enabled = pr.getOptBoolean("pkcs11.enable", false);
if (pkcs11Enabled) {
pkcs11ConfigFile = pr.getOptString("pkcs11.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 pkcs11.configFile");
}
String pw = pr.getOptString("pkcs11.password", null);
if (pw == null || pw.trim().isEmpty()) {
pkcs11KeyStorePassword = "".toCharArray();
} else {
pkcs11KeyStorePassword = pw.trim().toCharArray();
}
pkcs11KeyIDs = pr.getOptStringListMulti("pkcs11.keyIDs.", Collections.emptyList());
} else {
pkcs11ConfigFile = null;
pkcs11KeyStorePassword = "".toCharArray();
pkcs11KeyIDs = Collections.emptyList();
}
} catch (PropertyParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* Checks if weak keys are allowed.
*
* @return {@code true} if allowed, else {@code false}.
*/
boolean isAllowWeakKeys() {
return allowWeakKeys;
}
/**
* Checks if PKCS#11 (HSM) is enabled.
*
* @return {@code true} if enabled, else {@code false}.
*/
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.
*/
String getPKCS11ConfigurationFile() {
return pkcs11ConfigFile;
}
/**
* Returns the PKCS#11 (HSM) password (or PIN).
*
* @return The password, empty array if none.
*/
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.
*/
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.
*/
void log(final Logger logger) {
if (logger == null) {
return;
}
logger.info("[SE0000] JOSE configuration: Allow weak RSA keys: {}", isAllowWeakKeys());
logger.info("[SE0001] JOSE configuration: PKCS#11 enabled: {}", isPKCS11Enabled());
if (isPKCS11Enabled()) {
logger.info("[SE0002] JOSE configuration: PKCS#11 configuration file: {}", getPKCS11ConfigurationFile());
logger.info("[SE0003] JOSE configuration: PKCS#11 password configured: {}", hasPKCS11KeyStorePassword());
logger.info("[SE0004] JOSE configuration: 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 JOSEConfiguration load(final FileInputStreamSource fisSource)
throws IOException {
InputStream is = fisSource.getInputSteam(FILENAME);
var properties = new Properties();
if (is != null) {
properties.load(is);
}
return new JOSEConfiguration(properties, true);
}
}