Skip to content

Commit

Permalink
[WFCORE-6802] [Preview] OCSP stapling support: server-ssl subsystem code
Browse files Browse the repository at this point in the history
  • Loading branch information
Prarthona Paul committed May 15, 2024
1 parent 724fc10 commit 056fbe0
Show file tree
Hide file tree
Showing 8 changed files with 7,063 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
interface ElytronDescriptionConstants {

String ACCEPT_OCSP_STAPLING = "accept-ocsp-stapling";
String ACCOUNT_KEY = "account-key";
String ACTION = "action";
String ACTIVE_SESSION_COUNT = "active-session-count";
Expand Down Expand Up @@ -73,6 +74,8 @@ interface ElytronDescriptionConstants {
String BCRYPT_MAPPER = "bcrypt-mapper";

String CAA_IDENTITIES = "caa-identities";
String CACHE_SIZE = "cache-size";
String CACHE_LIFETIME = "cache-lifetime";
String CACHING_REALM = "caching-realm";
String CASE_PRINCIPAL_TRANSFORMER = "case-principal-transformer";
String CALLBACK_HANDLER = "callback-handler";
Expand Down Expand Up @@ -246,6 +249,7 @@ interface ElytronDescriptionConstants {
String IDENTITY_MAPPING = "identity-mapping";
String IDENTITY_REALM = "identity-realm";
String IGNORE_UNAVAILABLE_REALMS = "ignore-unavailable-realms";
String IGNORE_EXTENSIONS = "ignore-extensions";
String IMPLEMENTATION = "implementation";
String IMPLEMENTATION_PROPERTIES = "implementation-properties";
String IMPORT_CERTIFICATE = "import-certificate";
Expand Down Expand Up @@ -366,6 +370,7 @@ interface ElytronDescriptionConstants {
String OBTAIN_CERTIFICATE = "obtain-certificate";
String OBTAIN_KERBEROS_TICKET = "obtain-kerberos-ticket";
String OCSP = "ocsp";
String OCSP_STAPLING = "ocsp-stapling";
String OID = "oid";
String ONLY_LEAF_CERT = "only-leaf-cert";
String OPERATIONS = "operations";
Expand Down Expand Up @@ -467,6 +472,9 @@ interface ElytronDescriptionConstants {
String RESPONDER = "responder";
String RESPONDER_CERTIFICATE = "responder-certificate";
String RESPONDER_KEYSTORE = "responder-keystore";
String RESPONDER_OVERRIDE = "responder-override";
String RESPONDER_URI = "responder-uri";
String RESPONSE_TIMEOUT = "response-timeout";
String REVERSE = "reverse";
String REVOKE_CERTIFICATE = "revoke-certificate";
String RIGHT = "right";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ public class ElytronExtension implements Extension {
static final ModelVersion ELYTRON_17_0_0 = ModelVersion.create(17);
static final ModelVersion ELYTRON_18_0_0 = ModelVersion.create(18);
static final ModelVersion ELYTRON_19_0_0 = ModelVersion.create(19);
static final ModelVersion ELYTRON_20_0_0 = ModelVersion.create(20);

private static final ModelVersion ELYTRON_CURRENT = ELYTRON_19_0_0;
private static final ModelVersion ELYTRON_CURRENT = ELYTRON_20_0_0;

static final String ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ public enum ElytronSubsystemSchema implements PersistentSubsystemSchema<ElytronS
VERSION_17_0(17),
VERSION_18_0(18),
VERSION_18_0_COMMUNITY(18, Stability.COMMUNITY),
VERSION_18_0_PREVIEW(18, Stability.PREVIEW),
;
static final Map<Stability, ElytronSubsystemSchema> CURRENT = Feature.map(EnumSet.of(VERSION_18_0, VERSION_18_0_COMMUNITY));
static final Map<Stability, ElytronSubsystemSchema> CURRENT = Feature.map(EnumSet.of(VERSION_18_0, VERSION_18_0_COMMUNITY, VERSION_18_0_PREVIEW));

private final VersionedNamespace<IntVersion, ElytronSubsystemSchema> namespace;

Expand Down Expand Up @@ -192,7 +193,9 @@ private void addCredentialStoreParser(PersistentResourceXMLDescription.Persisten

private void addTlsParser(PersistentResourceXMLDescription.PersistentResourceXMLBuilder builder) {
TlsParser tlsParser = new TlsParser();
if (this.since(ElytronSubsystemSchema.VERSION_18_0_COMMUNITY) && this.enables(getDynamicClientSSLContextDefinition())) {
if (this.since(ElytronSubsystemSchema.VERSION_18_0_PREVIEW) && this.enables(SSLDefinitions.OCSP_STAPLING)) {
builder.addChild(tlsParser.tlsParserPreview_18_0);
} else if (this.since(ElytronSubsystemSchema.VERSION_18_0_COMMUNITY) && this.enables(getDynamicClientSSLContextDefinition())) {
builder.addChild(tlsParser.tlsParserCommunity_18_0);
} else if (this.since(ElytronSubsystemSchema.VERSION_14_0)) {
builder.addChild(tlsParser.tlsParser_14_0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ class SSLDefinitions {
//.setDefaultValue(new ModelNode(CipherSuiteSelector.OPENSSL_DEFAULT_CIPHER_SUITE_NAMES))
.build();

static final SimpleAttributeDefinition ACCEPT_OCSP_STAPLING = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.ACCEPT_OCSP_STAPLING, ModelType.BOOLEAN, true)
.setAllowExpression(true)
.setRestartAllServices()
.setDefaultValue(ModelNode.FALSE)
.build();

private static final String[] ALLOWED_PROTOCOLS = { "SSLv2", "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" };

static final StringListAttributeDefinition PROTOCOLS = new StringListAttributeDefinition.Builder(ElytronDescriptionConstants.PROTOCOLS)
Expand Down Expand Up @@ -398,6 +404,55 @@ class SSLDefinitions {
.setRestartAllServices()
.build();

static final SimpleAttributeDefinition RESPONSE_TIMEOUT = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.RESPONSE_TIMEOUT, ModelType.INT, true)
.setValidator(new IntRangeValidator(1))
.setDefaultValue(new ModelNode(5000))
.setAllowExpression(true)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

static final SimpleAttributeDefinition CACHE_SIZE = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.CACHE_SIZE, ModelType.INT, true)
.setDefaultValue(new ModelNode(256))
.setAllowExpression(true)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

static final SimpleAttributeDefinition CACHE_LIFETIME = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.CACHE_LIFETIME, ModelType.INT, true)
.setDefaultValue(new ModelNode(3600))
.setAllowExpression(true)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

static final SimpleAttributeDefinition RESPONDER_URI = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.RESPONDER_URI, ModelType.STRING, true)
.setRequires(ElytronDescriptionConstants.RESPONDER_OVERRIDE)
.setAllowExpression(true)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

static final SimpleAttributeDefinition RESPONDER_OVERRIDE = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.RESPONDER_OVERRIDE, ModelType.BOOLEAN, true)
.setDefaultValue(ModelNode.FALSE)
.setAllowExpression(true)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

static final SimpleAttributeDefinition IGNORE_EXTENSIONS = new SimpleAttributeDefinitionBuilder(ElytronDescriptionConstants.IGNORE_EXTENSIONS, ModelType.BOOLEAN, true)
.setDefaultValue(ModelNode.FALSE)
.setAllowExpression(true)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

static final ObjectTypeAttributeDefinition OCSP_STAPLING = new ObjectTypeAttributeDefinition.Builder(ElytronDescriptionConstants.OCSP_STAPLING, RESPONSE_TIMEOUT, CACHE_SIZE, CACHE_LIFETIME, RESPONDER_URI, RESPONDER_OVERRIDE, IGNORE_EXTENSIONS)
.setRequired(false)
.setRestartAllServices()
.setStability(Stability.PREVIEW)
.build();

/*
* Runtime Attributes
*/
Expand Down Expand Up @@ -1288,7 +1343,7 @@ static ResourceDefinition getServerSSLContextDefinition(boolean serverOrHostCont
SECURITY_DOMAIN, WANT_CLIENT_AUTH, NEED_CLIENT_AUTH, AUTHENTICATION_OPTIONAL,
USE_CIPHER_SUITES_ORDER, MAXIMUM_SESSION_CACHE_SIZE, SESSION_TIMEOUT, WRAP, keyManagerDefinition, TRUST_MANAGER,
PRE_REALM_PRINCIPAL_TRANSFORMER, POST_REALM_PRINCIPAL_TRANSFORMER, FINAL_PRINCIPAL_TRANSFORMER, REALM_MAPPER,
providersDefinition, PROVIDER_NAME};
providersDefinition, PROVIDER_NAME, OCSP_STAPLING};

AbstractAddStepHandler add = new TrivialAddHandler<SSLContext>(SSLContext.class, ServiceController.Mode.ACTIVE, ServiceController.Mode.PASSIVE, attributes, SSL_CONTEXT_RUNTIME_CAPABILITY) {

Expand Down Expand Up @@ -1316,6 +1371,12 @@ protected ValueSupplier<SSLContext> getValueSupplier(ServiceBuilder<SSLContext>
final int maximumSessionCacheSize = MAXIMUM_SESSION_CACHE_SIZE.resolveModelAttribute(context, model).asInt();
final int sessionTimeout = SESSION_TIMEOUT.resolveModelAttribute(context, model).asInt();
final boolean wrap = WRAP.resolveModelAttribute(context, model).asBoolean();
final int responseTimeout = RESPONSE_TIMEOUT.resolveModelAttribute(context, model).asInt();
final int cacheSize = CACHE_SIZE.resolveModelAttribute(context, model).asInt();
final int cacheLifetime = CACHE_LIFETIME.resolveModelAttribute(context, model).asInt();
final String responderURI = RESPONDER_URI.resolveModelAttribute(context, model).asString();
final Boolean responderOverride = RESPONDER_OVERRIDE.resolveModelAttribute(context, model).asBoolean();
final Boolean ignoreExtensions = IGNORE_EXTENSIONS.resolveModelAttribute(context, model).asBoolean();

return () -> {
SecurityDomain securityDomain = securityDomainInjector.getOptionalValue();
Expand Down Expand Up @@ -1364,7 +1425,13 @@ protected ValueSupplier<SSLContext> getValueSupplier(ServiceBuilder<SSLContext>
.setUseCipherSuitesOrder(useCipherSuitesOrder)
.setSessionCacheSize(maximumSessionCacheSize)
.setSessionTimeout(sessionTimeout)
.setWrap(wrap);
.setWrap(wrap)
.setResponseTimeout(responseTimeout)
.setCacheSize(cacheSize)
.setCacheLifetime(cacheLifetime)
.setResponderURI(responderURI)
.setResponderOverride(responderOverride)
.setIgnoreExtensions(ignoreExtensions);

if (ROOT_LOGGER.isTraceEnabled()) {
ROOT_LOGGER.tracef(
Expand Down Expand Up @@ -1461,7 +1528,7 @@ static ResourceDefinition getClientSSLContextDefinition(boolean serverOrHostCont
.build();

AttributeDefinition[] attributes = new AttributeDefinition[]{CIPHER_SUITE_FILTER, CIPHER_SUITE_NAMES, PROTOCOLS,
KEY_MANAGER, TRUST_MANAGER, providersDefinition, PROVIDER_NAME};
KEY_MANAGER, TRUST_MANAGER, providersDefinition, PROVIDER_NAME, ACCEPT_OCSP_STAPLING};

AbstractAddStepHandler add = new TrivialAddHandler<SSLContext>(SSLContext.class, attributes, SSL_CONTEXT_RUNTIME_CAPABILITY) {
@Override
Expand All @@ -1475,6 +1542,7 @@ protected ValueSupplier<SSLContext> getValueSupplier(ServiceBuilder<SSLContext>
final List<String> protocols = PROTOCOLS.unwrap(context, model);
final String cipherSuiteFilter = CIPHER_SUITE_FILTER.resolveModelAttribute(context, model).asString(); // has default value, can't be null
final String cipherSuiteNames = CIPHER_SUITE_NAMES.resolveModelAttribute(context, model).asStringOrNull(); // doesn't have a default value yet since we are disabling TLS 1.3 by default
final boolean acceptOCSPStapling = ACCEPT_OCSP_STAPLING.resolveModelAttribute(context, model).asBoolean();
return () -> {
X509ExtendedKeyManager keyManager = getX509KeyManager(keyManagerInjector.getOptionalValue());
X509ExtendedTrustManager trustManager = getX509TrustManager(trustManagerInjector.getOptionalValue());
Expand All @@ -1496,7 +1564,8 @@ protected ValueSupplier<SSLContext> getValueSupplier(ServiceBuilder<SSLContext>
));
}
builder.setClientMode(true)
.setWrap(false);
.setWrap(false)
.setAcceptOCSPStapling(acceptOCSPStapling);

if (ROOT_LOGGER.isTraceEnabled()) {
ROOT_LOGGER.tracef(
Expand Down
59 changes: 59 additions & 0 deletions elytron/src/main/java/org/wildfly/extension/elytron/TlsParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,30 @@ class TlsParser {
.addAttribute(SSLDefinitions.FINAL_PRINCIPAL_TRANSFORMER)
.addAttribute(SSLDefinitions.REALM_MAPPER);

private PersistentResourceXMLBuilder serverSslContextPreviewParser_18_0 = PersistentResourceXMLDescription.builder(PathElement.pathElement(SERVER_SSL_CONTEXT))
.setXmlWrapperElement(SERVER_SSL_CONTEXTS)
.setMarshallDefaultValues(true)
.addAttribute(SSLDefinitions.SECURITY_DOMAIN)
.addAttribute(SSLDefinitions.CIPHER_SUITE_FILTER)
.addAttribute(SSLDefinitions.CIPHER_SUITE_NAMES)
.addAttribute(SSLDefinitions.PROTOCOLS)
.addAttribute(SSLDefinitions.WANT_CLIENT_AUTH)
.addAttribute(SSLDefinitions.NEED_CLIENT_AUTH)
.addAttribute(SSLDefinitions.AUTHENTICATION_OPTIONAL)
.addAttribute(SSLDefinitions.USE_CIPHER_SUITES_ORDER)
.addAttribute(SSLDefinitions.MAXIMUM_SESSION_CACHE_SIZE)
.addAttribute(SSLDefinitions.SESSION_TIMEOUT)
.addAttribute(SSLDefinitions.WRAP)
.addAttribute(SSLDefinitions.KEY_MANAGER)
.addAttribute(SSLDefinitions.TRUST_MANAGER)
.addAttribute(SSLDefinitions.PROVIDERS)
.addAttribute(SSLDefinitions.PROVIDER_NAME)
.addAttribute(SSLDefinitions.PRE_REALM_PRINCIPAL_TRANSFORMER)
.addAttribute(SSLDefinitions.POST_REALM_PRINCIPAL_TRANSFORMER)
.addAttribute(SSLDefinitions.FINAL_PRINCIPAL_TRANSFORMER)
.addAttribute(SSLDefinitions.REALM_MAPPER)
.addAttribute(SSLDefinitions.OCSP_STAPLING); // new

private PersistentResourceXMLBuilder clientSslContextParser = PersistentResourceXMLDescription.builder(PathElement.pathElement(CLIENT_SSL_CONTEXT))
.setXmlWrapperElement(CLIENT_SSL_CONTEXTS)
.addAttribute(SSLDefinitions.SECURITY_DOMAIN)
Expand Down Expand Up @@ -224,6 +248,25 @@ class TlsParser {
.addAttribute(SSLDefinitions.PROVIDERS)
.addAttribute(SSLDefinitions.PROVIDER_NAME);

private PersistentResourceXMLBuilder clientSslContextParserCommunity_18_0 = PersistentResourceXMLDescription.builder(PathElement.pathElement(CLIENT_SSL_CONTEXT))
.setXmlWrapperElement(CLIENT_SSL_CONTEXTS)
.addAttribute(SSLDefinitions.SECURITY_DOMAIN)
.addAttribute(SSLDefinitions.CIPHER_SUITE_FILTER)
.addAttribute(SSLDefinitions.CIPHER_SUITE_NAMES)
.addAttribute(SSLDefinitions.PROTOCOLS)
.addAttribute(SSLDefinitions.WANT_CLIENT_AUTH)
.addAttribute(SSLDefinitions.NEED_CLIENT_AUTH)
.addAttribute(SSLDefinitions.AUTHENTICATION_OPTIONAL)
.addAttribute(SSLDefinitions.USE_CIPHER_SUITES_ORDER)
.addAttribute(SSLDefinitions.MAXIMUM_SESSION_CACHE_SIZE)
.addAttribute(SSLDefinitions.SESSION_TIMEOUT)
.addAttribute(SSLDefinitions.WRAP)
.addAttribute(SSLDefinitions.KEY_MANAGER)
.addAttribute(SSLDefinitions.TRUST_MANAGER)
.addAttribute(SSLDefinitions.PROVIDERS)
.addAttribute(SSLDefinitions.PROVIDER_NAME)
.addAttribute(SSLDefinitions.ACCEPT_OCSP_STAPLING); //new

private PersistentResourceXMLBuilder certificateAuthorityAccountParser = PersistentResourceXMLDescription.builder(PathElement.pathElement(CERTIFICATE_AUTHORITY_ACCOUNT))
.setXmlWrapperElement(CERTIFICATE_AUTHORITY_ACCOUNTS)
.addAttribute(CertificateAuthorityAccountDefinition.CERTIFICATE_AUTHORITY)
Expand Down Expand Up @@ -371,4 +414,20 @@ public void marshallSingleElement(AttributeDefinition attribute, ModelNode mappi
.addChild(serverSslSniContextParser)
.addChild(dynamicClientSslContextParser) // new
.build();

final PersistentResourceXMLDescription tlsParserPreview_18_0 = decorator(TLS)
.addChild(decorator(KEY_STORES)
.addChild(keyStoreParser)
.addChild(ldapKeyStoreParser)
.addChild(filteringKeyStoreParser)
)
.addChild(keyManagerParser_12_0)
.addChild(trustManagerParser_14_0)
.addChild(serverSslContextPreviewParser_18_0) // new
.addChild(clientSslContextParserCommunity_18_0) // new
.addChild(certificateAuthorityParser)
.addChild(certificateAuthorityAccountParser)
.addChild(serverSslSniContextParser)
.addChild(dynamicClientSslContextParser)
.build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,7 @@ elytron.client-ssl-context.key-refresh=Refresh KeyManager used by SSLContext.
elytron.client-ssl-context.trust-manager=Reference to the trust manager to use within the SSLContext.
elytron.client-ssl-context.provider-name=The name of the provider to use. If not specified, all providers from providers will be passed to the SSLContext.
elytron.client-ssl-context.providers=The name of the providers to obtain the Provider[] to use to load the SSLContext.
elytron.client-ssl-context.accept-ocsp-stapling=Indicates whether the client would accept OCSP stapled responses fom the model or not.
# Runtime Attributes
elytron.client-ssl-context.active-session-count=The count of current active sessions.

Expand Down Expand Up @@ -1521,6 +1522,13 @@ elytron.server-ssl-context.ssl-session.peer-certificates.signature-algorithm=The
elytron.server-ssl-context.ssl-session.peer-certificates.signature=The signature of the certificate.
elytron.server-ssl-context.ssl-session.peer-certificates.version=The certificate version.

elytron.server-ssl-context.ocsp-stapling=Support for OCSP Stapling for server ssl context.
elytron.server-ssl-context.ocsp-stapling.response-timeout=Enables online certificate status protocol Stapling for the server SSL context.
elytron.server-ssl-context.ocsp-stapling.cache-size=Controls the maximum cache size in entries.
elytron.server-ssl-context.ocsp-stapling.cache-lifetime=Controls the maximum life of a cached response in seconds.
elytron.server-ssl-context.ocsp-stapling.responder-uri=The responder to contact in case the certificate used by the server does not have the Authority Info Access (AIA) extension. This does not override the AIA extension value unless "responder-override" is set to true.
elytron.server-ssl-context.ocsp-stapling.responder-override=Determines whether the Authority information from the AIA extension value would be overridden by the value of the `responderURI`.
elytron.server-ssl-context.ocsp-stapling.ignore-extensions=determines whether the forwarding of OCSP extensions specified in the "status_request" or "status_request_v2" TLS extensions is disabled or not.
# Operations
elytron.server-ssl-context.ssl-session.invalidate=Invalidate the SSLSession (Note: This does not terminate current connections, only prevents future connections from joining or resuming this session).

Expand Down
Loading

0 comments on commit 056fbe0

Please sign in to comment.