diff --git a/pom.xml b/pom.xml
index c7c4382..4f2c25c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -198,17 +198,6 @@
-
- ${project.groupId}
- elytron-tls-dependency
- ${project.version}
-
-
- *
- *
-
-
-
${project.groupId}
elytron-tls-subsystem
@@ -264,61 +253,56 @@
wildfly-checkstyle-config
${version.org.wildfly.checkstyle-config}
-
+
+ org.wildfly.core
+ wildfly-elytron-integration
+ ${version.org.wildfly.core}
+
org.wildfly.security
wildfly-elytron-asn1
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-base
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-credential
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-provider-util
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-ssl-common
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-x500
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-x500-cert
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-x500-cert-acme
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-x500-cert-util
${version.org.wildfly.security.elytron}
-
org.wildfly.security
wildfly-elytron-x500-principal
@@ -410,6 +394,7 @@
org.jmockit
jmockit
+ test
${version.org.jmockit}
diff --git a/subsystem/pom.xml b/subsystem/pom.xml
index d6e9767..90d1928 100644
--- a/subsystem/pom.xml
+++ b/subsystem/pom.xml
@@ -33,88 +33,72 @@
jakarta.json
jakarta.json-api
-
org.glassfish
jakarta.json
-
org.jboss.logging
jboss-logging-annotations
-
org.jboss.logging
jboss-logging-processor
-
provided
true
-
org.wildfly.core
wildfly-controller
-
+
+ org.wildfly.core
+ wildfly-elytron-integration
+
org.wildfly.core
wildfly-server
-
org.wildfly.checkstyle
wildfly-checkstyle-config
-
org.wildfly.security
wildfly-elytron-asn1
-
org.wildfly.security
wildfly-elytron-base
-
org.wildfly.security
wildfly-elytron-credential
-
org.wildfly.security
wildfly-elytron-provider-util
-
org.wildfly.security
wildfly-elytron-ssl-common
-
org.wildfly.security
wildfly-elytron-x500
-
org.wildfly.security
wildfly-elytron-x500-cert
-
org.wildfly.security
wildfly-elytron-x500-cert-acme
-
org.wildfly.security
wildfly-elytron-x500-cert-util
-
org.wildfly.security
wildfly-elytron-x500-principal
@@ -124,7 +108,6 @@
junit
junit
- test
org.bouncycastle
@@ -137,12 +120,10 @@
org.mock-server
mockserver-netty
- test
org.jmockit
jmockit
- test
org.wildfly.core
diff --git a/subsystem/src/main/java/org/wildfly/extension/elytron/tls/AbstractCredentialStoreResourceDefinition.java b/subsystem/src/main/java/org/wildfly/extension/elytron/tls/AbstractCredentialStoreResourceDefinition.java
deleted file mode 100644
index ef7aad6..0000000
--- a/subsystem/src/main/java/org/wildfly/extension/elytron/tls/AbstractCredentialStoreResourceDefinition.java
+++ /dev/null
@@ -1,362 +0,0 @@
- /*
- * Copyright 2021 Red Hat, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.wildfly.extension.elytron.tls;
-
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_API_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_RUNTIME_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.ElytronTlsExtension.isServerOrHostController;
-import static org.wildfly.extension.elytron.tls.ServiceStateDefinition.STATE;
-import static org.wildfly.extension.elytron.tls.ServiceStateDefinition.populateResponse;
-import static org.wildfly.extension.elytron.tls._private.ElytronTLSMessages.LOGGER;
-import static org.wildfly.security.encryption.SecretKeyUtil.exportSecretKey;
-import static org.wildfly.security.encryption.SecretKeyUtil.generateSecretKey;
-import static org.wildfly.security.encryption.SecretKeyUtil.importSecretKey;
-
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-
-import javax.crypto.SecretKey;
-
-import org.jboss.as.controller.AbstractWriteAttributeHandler;
-import org.jboss.as.controller.AttributeDefinition;
-import org.jboss.as.controller.OperationContext;
-import org.jboss.as.controller.OperationFailedException;
-import org.jboss.as.controller.OperationStepHandler;
-import org.jboss.as.controller.PathAddress;
-import org.jboss.as.controller.SimpleAttributeDefinition;
-import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
-import org.jboss.as.controller.SimpleOperationDefinition;
-import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
-import org.jboss.as.controller.SimpleResourceDefinition;
-import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
-import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
-import org.jboss.as.controller.registry.ManagementResourceRegistration;
-import org.jboss.dmr.ModelNode;
-import org.jboss.dmr.ModelType;
-import org.jboss.msc.service.ServiceController;
-import org.jboss.msc.service.ServiceName;
-import org.wildfly.common.function.ExceptionFunction;
-import org.wildfly.security.credential.Credential;
-import org.wildfly.security.credential.PasswordCredential;
-import org.wildfly.security.credential.SecretKeyCredential;
-import org.wildfly.security.credential.store.CredentialStore;
-import org.wildfly.security.credential.store.CredentialStoreException;
-import org.wildfly.security.credential.store.UnsupportedCredentialTypeException;
-import org.wildfly.security.password.PasswordFactory;
-import org.wildfly.security.password.interfaces.ClearPassword;
-import org.wildfly.security.password.spec.ClearPasswordSpec;
-
-/**
- * A common base for resource definitions representing credential stores.
- *
- * @author Darran Lofthouse
- */
-abstract class AbstractCredentialStoreResourceDefinition extends SimpleResourceDefinition {
-
- static final ServiceUtil CREDENTIAL_STORE_UTIL = ServiceUtil.newInstance(CREDENTIAL_STORE_RUNTIME_CAPABILITY, Constants.CREDENTIAL_STORE, CredentialStore.class);
-
- protected ServiceUtil getCredentialStoreUtil() {
- return CREDENTIAL_STORE_UTIL;
- }
-
- // Operations
-
- static final StandardResourceDescriptionResolver OPERATION_RESOLVER = ElytronTlsExtension
- .getResourceDescriptionResolver(Constants.CREDENTIAL_STORE,
- Constants.OPERATIONS);
-
- static final SimpleOperationDefinition READ_ALIASES = new SimpleOperationDefinitionBuilder(Constants.READ_ALIASES, OPERATION_RESOLVER)
- .setRuntimeOnly()
- .setReadOnly()
- .build();
-
- static final SimpleAttributeDefinition ALIAS = new SimpleAttributeDefinitionBuilder(Constants.ALIAS, ModelType.STRING, false)
- .setMinSize(1)
- .build();
-
- static final SimpleAttributeDefinition KEY = new SimpleAttributeDefinitionBuilder(Constants.KEY, ModelType.STRING, false)
- .setMinSize(1)
- .build();
-
- static final SimpleOperationDefinition EXPORT_SECRET_KEY = new SimpleOperationDefinitionBuilder(Constants.EXPORT_SECRET_KEY, OPERATION_RESOLVER)
- .setParameters(ALIAS)
- .setRuntimeOnly()
- .build();
-
- static final SimpleOperationDefinition IMPORT_SECRET_KEY = new SimpleOperationDefinitionBuilder(Constants.IMPORT_SECRET_KEY, OPERATION_RESOLVER)
- .setParameters(ALIAS, KEY)
- .setRuntimeOnly()
- .build();
-
- static final SimpleOperationDefinition RELOAD = new SimpleOperationDefinitionBuilder(Constants.RELOAD, OPERATION_RESOLVER)
- .setRuntimeOnly()
- .build();
-
- static final OperationStepHandler RELOAD_HANDLER = new CredentialStoreReloadHandler();
-
- protected AbstractCredentialStoreResourceDefinition(Parameters parameters) {
- super(parameters);
- }
-
- @Override
- public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
- AttributeDefinition[] configAttributes = getAttributeDefinitions();
- AbstractWriteAttributeHandler write = new ElytronReloadRequiredWriteAttributeHandler(configAttributes);
- for (AttributeDefinition current : configAttributes) {
- resourceRegistration.registerReadWriteAttribute(current, null, write);
- }
- if (isServerOrHostController(resourceRegistration)) {
- resourceRegistration.registerReadOnlyAttribute(STATE, new ElytronRuntimeOnlyHandler() {
-
- @Override
- protected void executeRuntimeStep(OperationContext context, ModelNode operation) {
- ServiceName credentialStoreClientServiceName = getCredentialStoreUtil().serviceName(operation);
- ServiceController> serviceController = context.getServiceRegistry(false).getRequiredService(credentialStoreClientServiceName);
-
- populateResponse(context.getResult(), serviceController);
- }
-
- });
- }
- }
-
- protected abstract AttributeDefinition[] getAttributeDefinitions();
-
- protected void readAliasesOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- try {
- try {
- List list = new ArrayList<>();
- Set aliases = credentialStore.getAliases();
- for (String s : aliases) {
- ModelNode modelNode = new ModelNode(s);
- list.add(modelNode);
- }
- context.getResult().set(list);
- } catch (CredentialStoreException e) {
- throw LOGGER.unableToCompleteOperation(e, dumpCause(e));
- }
- } catch (RuntimeException e) {
- e.printStackTrace();
- throw new OperationFailedException(e);
- }
- }
-
- protected void removeAliasOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore, Class extends Credential> credentialType) throws OperationFailedException {
- try {
- try {
- String alias = ALIAS.resolveModelAttribute(context, operation).asString();
-
- Credential retrieved = credentialStore.retrieve(alias, credentialType);
- if (retrieved == null) {
- throw LOGGER.credentialDoesNotExist(alias, credentialType.getSimpleName());
- }
- credentialStore.remove(alias, credentialType);
- context.addResponseWarning(Level.WARNING, LOGGER.updateDependantServices(alias));
- try {
- credentialStore.flush();
- } catch (CredentialStoreException e) {
- // the operation fails, return removed entry back to the store to avoid an inconsistency
- // between the store on the FS and in the memory
- credentialStore.store(alias, retrieved);
- throw e;
- }
- } catch (CredentialStoreException e) {
- throw LOGGER.unableToCompleteOperation(e, dumpCause(e));
- }
- } catch (RuntimeException e) {
- throw new OperationFailedException(e);
- }
- }
-
- protected void exportSecretKeyOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore)
- throws OperationFailedException {
- try {
- String alias = ALIAS.resolveModelAttribute(context, operation).asString();
-
- SecretKeyCredential credential = credentialStore.retrieve(alias, SecretKeyCredential.class);
- if (credential == null) {
- throw LOGGER.credentialDoesNotExist(alias, SecretKeyCredential.class.getSimpleName());
- }
-
- SecretKey secretKey = credential.getSecretKey();
- String exportedKey = exportSecretKey(secretKey);
-
- ModelNode result = context.getResult();
- result.get(Constants.KEY).set(exportedKey);
- } catch (GeneralSecurityException e) {
- throw LOGGER.secretKeyOperationFailed(Constants.EXPORT_SECRET_KEY, dumpCause(e), e);
- }
- }
-
- protected void importSecretKeyOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore)
- throws OperationFailedException {
- try {
- String alias = ALIAS.resolveModelAttribute(context, operation).asString();
- String rawKey = KEY.resolveModelAttribute(context, operation).asString();
-
- if (credentialStore.exists(alias, SecretKeyCredential.class)) {
- throw LOGGER.credentialAlreadyExists(alias, SecretKeyCredential.class.getName());
- }
-
- SecretKey secretKey = importSecretKey(rawKey);
-
- storeSecretKey(credentialStore, alias, secretKey);
-
- } catch (GeneralSecurityException e) {
- throw LOGGER.secretKeyOperationFailed(Constants.IMPORT_SECRET_KEY, dumpCause(e), e);
- }
- }
-
- protected void generateSecretKeyOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore,
- int keySize) throws OperationFailedException {
- try {
- String alias = ALIAS.resolveModelAttribute(context, operation).asString();
-
- if (credentialStore.exists(alias, SecretKeyCredential.class)) {
- throw LOGGER.credentialAlreadyExists(alias, SecretKeyCredential.class.getName());
- }
-
- SecretKey secretKey = generateSecretKey(keySize);
- storeSecretKey(credentialStore, alias, secretKey);
-
- } catch (GeneralSecurityException e) {
- throw LOGGER.secretKeyOperationFailed(Constants.GENERATE_SECRET_KEY, dumpCause(e), e);
- }
- }
-
- /**
- * Convert {@code char[]} password to {@code PasswordCredential}
- * @param password to convert
- * @return new {@code PasswordCredential}
- * @throws UnsupportedCredentialTypeException should never happen as we have only supported types and algorithms
- */
- protected static PasswordCredential createCredentialFromPassword(char[] password) throws UnsupportedCredentialTypeException {
- try {
- PasswordFactory passwordFactory = PasswordFactory.getInstance(ClearPassword.ALGORITHM_CLEAR);
- return new PasswordCredential(passwordFactory.generatePassword(new ClearPasswordSpec(password)));
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new UnsupportedCredentialTypeException(e);
- }
- }
-
- protected static void storeSecret(CredentialStore credentialStore, String alias, String secretValue) throws CredentialStoreException {
- char[] secret = secretValue != null ? secretValue.toCharArray() : new char[0];
- storeCredential(credentialStore, alias, createCredentialFromPassword(secret));
- }
-
- protected static void storeSecretKey(CredentialStore credentialStore, String alias, SecretKey secretKey) throws CredentialStoreException {
- storeCredential(credentialStore, alias, new SecretKeyCredential(secretKey));
- }
-
- protected static void storeCredential(CredentialStore credentialStore, String alias, Credential credential) throws CredentialStoreException {
- credentialStore.store(alias, credential);
- try {
- credentialStore.flush();
- } catch (CredentialStoreException e) {
- // operation fails, remove the entry from the store, to avoid an inconsistency between
- // the store on the FS and in the memory
- credentialStore.remove(alias, PasswordCredential.class);
- throw e;
- }
- }
-
- protected static String dumpCause(Throwable e) {
- StringBuffer sb = new StringBuffer().append(e.getLocalizedMessage());
- Throwable c = e.getCause();
- int depth = 0;
- while(c != null && depth++ < 10) {
- sb.append("->").append(c.getLocalizedMessage());
- c = c.getCause() == c ? null : c.getCause();
- }
- return sb.toString();
- }
-
- protected abstract static class AbstractCredentialStoreDoohickey extends ElytronDoohickey {
-
- protected AbstractCredentialStoreDoohickey(PathAddress resourceAddress) {
- super(resourceAddress);
- }
-
- protected abstract void reload(OperationContext context) throws GeneralSecurityException, OperationFailedException;
-
- }
-
- protected static class CredentialStoreRuntimeHandler extends ElytronRuntimeOnlyHandler {
-
- private final Map definedOperations;
-
- protected CredentialStoreRuntimeHandler(final Map definedOperations) {
- this.definedOperations = definedOperations;
- }
-
- @Override
- protected void executeRuntimeStep(OperationContext context, ModelNode operation) throws OperationFailedException {
- final String operationName = operation.require(ModelDescriptionConstants.OP).asString();
- CredentialStoreRuntimeOperation operationMethod = definedOperations.get(operationName);
- if (operationMethod == null) {
- throw LOGGER.invalidOperationName(operationName, getExpectedOperationNames());
- }
-
- CredentialStore credentialStore = getCredentialStore(context);
- operationMethod.handle(context, operation, credentialStore);
- }
-
- private String[] getExpectedOperationNames() {
- return definedOperations.keySet().toArray(new String[definedOperations.size()]);
- }
-
- protected CredentialStore getCredentialStore(OperationContext context) throws OperationFailedException {
- final ExceptionFunction credentialStoreApi = context
- .getCapabilityRuntimeAPI(CREDENTIAL_STORE_API_CAPABILITY, context.getCurrentAddressValue(), ExceptionFunction.class);
-
- return credentialStoreApi.apply(context);
- }
-
- }
-
- static class CredentialStoreReloadHandler extends ElytronRuntimeOnlyHandler {
-
- @Override
- protected void executeRuntimeStep(OperationContext context, ModelNode operation) throws OperationFailedException {
- final ExceptionFunction credentialStoreApi = context
- .getCapabilityRuntimeAPI(CREDENTIAL_STORE_API_CAPABILITY, context.getCurrentAddressValue(), ExceptionFunction.class);
-
- AbstractCredentialStoreDoohickey doohickey = (AbstractCredentialStoreDoohickey) credentialStoreApi;
-
- try {
- doohickey.reload(context);
- } catch (GeneralSecurityException e) {
- throw LOGGER.unableToReloadCredentialStore(e);
- }
-
- }
-
- }
-
- @FunctionalInterface
- interface CredentialStoreRuntimeOperation {
-
- void handle(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException;
-
- }
-}
diff --git a/subsystem/src/main/java/org/wildfly/extension/elytron/tls/CredentialStoreResourceDefinition.java b/subsystem/src/main/java/org/wildfly/extension/elytron/tls/CredentialStoreResourceDefinition.java
deleted file mode 100644
index f0038aa..0000000
--- a/subsystem/src/main/java/org/wildfly/extension/elytron/tls/CredentialStoreResourceDefinition.java
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2015 Red Hat, Inc., and individual contributors
- * as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.wildfly.extension.elytron.tls;
-
-import static org.jboss.as.controller.security.CredentialReference.getCredentialSource;
-import static org.jboss.as.controller.security.CredentialReference.handleCredentialReferenceUpdate;
-import static org.jboss.as.controller.security.CredentialReference.rollbackCredentialStoreUpdate;
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_API_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_RUNTIME_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.Capabilities.PROVIDERS_API_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.Capabilities.PROVIDERS_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.ElytronTlsExtension.isServerOrHostController;
-import static org.wildfly.extension.elytron.tls.FileAttributeDefinitions.pathName;
-import static org.wildfly.extension.elytron.tls.FileAttributeDefinitions.pathResolver;
-import static org.wildfly.extension.elytron.tls._private.ElytronTLSMessages.LOGGER;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Provider;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.function.Supplier;
-import java.util.logging.Level;
-
-import org.jboss.as.controller.AttributeDefinition;
-import org.jboss.as.controller.CapabilityServiceBuilder;
-import org.jboss.as.controller.ModelVersion;
-import org.jboss.as.controller.ObjectTypeAttributeDefinition;
-import org.jboss.as.controller.OperationContext;
-import org.jboss.as.controller.OperationFailedException;
-import org.jboss.as.controller.OperationStepHandler;
-import org.jboss.as.controller.PathAddress;
-import org.jboss.as.controller.PathElement;
-import org.jboss.as.controller.ResourceDefinition;
-import org.jboss.as.controller.SimpleAttributeDefinition;
-import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
-import org.jboss.as.controller.SimpleMapAttributeDefinition;
-import org.jboss.as.controller.SimpleOperationDefinition;
-import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
-import org.jboss.as.controller.SimpleResourceDefinition;
-import org.jboss.as.controller.capability.RuntimeCapability;
-import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
-import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
-import org.jboss.as.controller.registry.ManagementResourceRegistration;
-import org.jboss.as.controller.registry.OperationEntry;
-import org.jboss.as.controller.registry.Resource;
-import org.jboss.as.controller.security.CredentialReference;
-import org.jboss.as.controller.services.path.PathManagerService;
-import org.jboss.dmr.ModelNode;
-import org.jboss.dmr.ModelType;
-import org.jboss.msc.service.ServiceName;
-import org.jboss.msc.service.StartException;
-import org.wildfly.common.function.ExceptionFunction;
-import org.wildfly.common.function.ExceptionRunnable;
-import org.wildfly.common.function.ExceptionSupplier;
-import org.wildfly.extension.elytron.tls.FileAttributeDefinitions.PathResolver;
-import org.wildfly.security.EmptyProvider;
-import org.wildfly.security.auth.server.IdentityCredentials;
-import org.wildfly.security.credential.Credential;
-import org.wildfly.security.credential.PasswordCredential;
-import org.wildfly.security.credential.SecretKeyCredential;
-import org.wildfly.security.credential.source.CredentialSource;
-import org.wildfly.security.credential.store.CredentialStore;
-import org.wildfly.security.credential.store.CredentialStore.CredentialSourceProtectionParameter;
-import org.wildfly.security.credential.store.CredentialStoreException;
-import org.wildfly.security.credential.store.impl.KeyStoreCredentialStore;
-
-/**
- * A {@link ResourceDefinition} for a CredentialStore.
- *
- * @author Peter Skopek
- */
-final class CredentialStoreResourceDefinition extends AbstractCredentialStoreResourceDefinition {
-
- // KeyStore backed credential store supported attributes
- private static final String CS_KEY_STORE_TYPE_ATTRIBUTE = "keyStoreType";
- private static final List filebasedKeystoreTypes = Collections.unmodifiableList(Arrays.asList("JKS", "JCEKS", "PKCS12"));
-
- static final SimpleAttributeDefinition LOCATION = new SimpleAttributeDefinitionBuilder(Constants.LOCATION, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setMinSize(1)
- .setRestartAllServices()
- .setDeprecated(ModelVersion.create(13))
- .setAlternatives(Constants.PATH)
- .build();
-
- static final SimpleAttributeDefinition MODIFIABLE = new SimpleAttributeDefinitionBuilder(Constants.MODIFIABLE, ModelType.BOOLEAN, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setDefaultValue(ModelNode.TRUE)
- .setAllowExpression(false)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition CREATE = new SimpleAttributeDefinitionBuilder(Constants.CREATE, ModelType.BOOLEAN, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(false)
- .setDefaultValue(ModelNode.FALSE)
- .setRestartAllServices()
- .build();
-
- static final SimpleMapAttributeDefinition IMPLEMENTATION_PROPERTIES = new SimpleMapAttributeDefinition.Builder(Constants.IMPLEMENTATION_PROPERTIES, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setRestartAllServices()
- .build();
-
- static final ObjectTypeAttributeDefinition CREDENTIAL_REFERENCE = CredentialReference.getAttributeDefinition(true);
-
- static final SimpleAttributeDefinition TYPE = new SimpleAttributeDefinitionBuilder(Constants.TYPE, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setMinSize(1)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition PROVIDER_NAME = new SimpleAttributeDefinitionBuilder(Constants.PROVIDER_NAME, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setMinSize(1)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition PROVIDERS = new SimpleAttributeDefinitionBuilder(Constants.PROVIDERS, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(false)
- .setMinSize(1)
- .setRestartAllServices()
- .setCapabilityReference(PROVIDERS_CAPABILITY, CREDENTIAL_STORE_CAPABILITY)
- .build();
-
- static final SimpleAttributeDefinition OTHER_PROVIDERS = new SimpleAttributeDefinitionBuilder(Constants.OTHER_PROVIDERS, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(false)
- .setMinSize(1)
- .setRestartAllServices()
- .setCapabilityReference(PROVIDERS_CAPABILITY, CREDENTIAL_STORE_CAPABILITY)
- .build();
-
- static final SimpleAttributeDefinition RELATIVE_TO = new SimpleAttributeDefinitionBuilder(Constants.RELATIVE_TO, ModelType.STRING, true)
- .setAllowExpression(false)
- .setMinSize(1)
- .setAttributeGroup(Constants.FILE)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition PATH = new SimpleAttributeDefinitionBuilder(Constants.PATH, ModelType.STRING, true)
- .setAllowExpression(true)
- .setMinSize(1)
- .setAttributeGroup(Constants.FILE)
- .setRestartAllServices()
- .setAlternatives(Constants.LOCATION)
- .build();
-
- // Resource Resolver
- private static final StandardResourceDescriptionResolver RESOURCE_RESOLVER = ElytronTlsExtension.getResourceDescriptionResolver(Constants.CREDENTIAL_STORE);
-
- // Operations parameters
-
-
- static final SimpleAttributeDefinition KEY_SIZE = new SimpleAttributeDefinitionBuilder(Constants.KEY_SIZE, ModelType.INT, true)
- .setMinSize(1)
- .setDefaultValue(new ModelNode(256))
- .setAllowedValues(128, 192, 256)
- .build();
-
- static final SimpleAttributeDefinition ADD_ENTRY_TYPE;
- static final SimpleAttributeDefinition REMOVE_ENTRY_TYPE;
-
- static {
- String[] addEntryTypes = new String[] { PasswordCredential.class.getCanonicalName() };
- ADD_ENTRY_TYPE = new SimpleAttributeDefinitionBuilder(Constants.ENTRY_TYPE, ModelType.STRING, true)
- .setAllowedValues(addEntryTypes)
- .build();
- String[] removeEntryTypes = new String[] { PasswordCredential.class.getCanonicalName(), PasswordCredential.class.getSimpleName(),
- SecretKeyCredential.class.getCanonicalName(), SecretKeyCredential.class.getSimpleName()};
- REMOVE_ENTRY_TYPE = new SimpleAttributeDefinitionBuilder(Constants.ENTRY_TYPE, ModelType.STRING, true)
- .setAllowedValues(removeEntryTypes)
- .setDefaultValue(new ModelNode(PasswordCredential.class.getSimpleName()))
- .build();
- }
-
- static final SimpleAttributeDefinition SECRET_VALUE = new SimpleAttributeDefinitionBuilder(Constants.SECRET_VALUE, ModelType.STRING, true)
- .setMinSize(0)
- .build();
-
- // Operations
-
- private static final SimpleOperationDefinition ADD_ALIAS = new SimpleOperationDefinitionBuilder(Constants.ADD_ALIAS, OPERATION_RESOLVER)
- .setParameters(ALIAS, ADD_ENTRY_TYPE, SECRET_VALUE)
- .setRuntimeOnly()
- .build();
-
- private static final SimpleOperationDefinition REMOVE_ALIAS = new SimpleOperationDefinitionBuilder(Constants.REMOVE_ALIAS, OPERATION_RESOLVER)
- .setParameters(ALIAS, REMOVE_ENTRY_TYPE)
- .setRuntimeOnly()
- .build();
-
- private static final SimpleOperationDefinition SET_SECRET = new SimpleOperationDefinitionBuilder(Constants.SET_SECRET, OPERATION_RESOLVER)
- .setParameters(ALIAS, ADD_ENTRY_TYPE, SECRET_VALUE)
- .setRuntimeOnly()
- .build();
-
- private static final SimpleOperationDefinition GENERATE_SECRET_KEY = new SimpleOperationDefinitionBuilder(Constants.GENERATE_SECRET_KEY, OPERATION_RESOLVER)
- .setParameters(ALIAS, KEY_SIZE)
- .setRuntimeOnly()
- .build();
-
- private static final AttributeDefinition[] CONFIG_ATTRIBUTES = new AttributeDefinition[] {LOCATION, PATH, CREATE, MODIFIABLE, IMPLEMENTATION_PROPERTIES, CREDENTIAL_REFERENCE, TYPE, PROVIDER_NAME, PROVIDERS, OTHER_PROVIDERS, RELATIVE_TO};
-
- private static final CredentialStoreAddHandler ADD = new CredentialStoreAddHandler();
- private static final OperationStepHandler REMOVE = new TrivialCapabilityServiceRemoveHandler(ADD, CREDENTIAL_STORE_RUNTIME_CAPABILITY);
-
-
- CredentialStoreResourceDefinition() {
- super(new SimpleResourceDefinition.Parameters(PathElement.pathElement(Constants.CREDENTIAL_STORE), RESOURCE_RESOLVER)
- .setAddHandler(ADD)
- .setRemoveHandler(REMOVE)
- .setAddRestartLevel(OperationEntry.Flag.RESTART_NONE)
- .setRemoveRestartLevel(OperationEntry.Flag.RESTART_NONE)
- .setCapabilities(CREDENTIAL_STORE_RUNTIME_CAPABILITY)
- );
- }
-
- @Override
- protected AttributeDefinition[] getAttributeDefinitions() {
- return CONFIG_ATTRIBUTES;
- }
-
- @Override
- public void registerOperations(ManagementResourceRegistration resourceRegistration) {
- super.registerOperations(resourceRegistration); // Always needed to register add / remove.
-
- boolean isServerOrHostController = isServerOrHostController(resourceRegistration);
- Map operationMethods = new HashMap<>();
-
- operationMethods.put(Constants.READ_ALIASES, this::readAliasesOperation);
- if (isServerOrHostController) {
- operationMethods.put(Constants.ADD_ALIAS, this::addAliasOperation);
- operationMethods.put(Constants.REMOVE_ALIAS, this::removeAliasOperation);
- operationMethods.put(Constants.SET_SECRET, this::setSecretOperation);
- operationMethods.put(Constants.EXPORT_SECRET_KEY, this::exportSecretKeyOperation);
- operationMethods.put(Constants.GENERATE_SECRET_KEY, this::generateSecretKeyOperation);
- operationMethods.put(Constants.IMPORT_SECRET_KEY, this::importSecretKeyOperation);
- }
-
- OperationStepHandler operationHandler = new CredentialStoreRuntimeHandler(operationMethods);
- resourceRegistration.registerOperationHandler(READ_ALIASES, operationHandler); // MAPPED
- if (isServerOrHostController) {
- resourceRegistration.registerOperationHandler(ADD_ALIAS, operationHandler); // Mapped
- resourceRegistration.registerOperationHandler(REMOVE_ALIAS, operationHandler); // Mapped
- resourceRegistration.registerOperationHandler(SET_SECRET, operationHandler); // Mapped
- resourceRegistration.registerOperationHandler(GENERATE_SECRET_KEY, operationHandler);
- resourceRegistration.registerOperationHandler(EXPORT_SECRET_KEY, operationHandler);
- resourceRegistration.registerOperationHandler(IMPORT_SECRET_KEY, operationHandler);
- resourceRegistration.registerOperationHandler(RELOAD, RELOAD_HANDLER);
- }
- }
-
- /*
- * Operation Handler Methods
- */
-
- void addAliasOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- try {
- try {
- String alias = ALIAS.resolveModelAttribute(context, operation).asString();
- String entryType = ADD_ENTRY_TYPE.resolveModelAttribute(context, operation).asStringOrNull();
- String secretValue = SECRET_VALUE.resolveModelAttribute(context, operation).asStringOrNull();
- if (entryType == null || entryType.equals(PasswordCredential.class.getCanonicalName())) {
- if (credentialStore.exists(alias, PasswordCredential.class)) {
- throw LOGGER.credentialAlreadyExists(alias, PasswordCredential.class.getName());
- }
- storeSecret(credentialStore, alias, secretValue);
- } else {
- String credentialStoreName = CredentialStoreResourceDefinition.credentialStoreName(operation);
- throw LOGGER.credentialStoreEntryTypeNotSupported(credentialStoreName, entryType);
- }
- } catch (CredentialStoreException e) {
- throw LOGGER.unableToCompleteOperation(e, dumpCause(e));
- }
- } catch (RuntimeException e) {
- throw new OperationFailedException(e);
- }
- }
-
- void removeAliasOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- String entryType = REMOVE_ENTRY_TYPE.resolveModelAttribute(context, operation).asString();
- Class extends Credential> credentialType = fromEntryType(entryType);
-
- super.removeAliasOperation(context, operation, credentialStore, credentialType);
- }
-
- void setSecretOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- try {
- try {
- String alias = ALIAS.resolveModelAttribute(context, operation).asString();
- String entryType = ADD_ENTRY_TYPE.resolveModelAttribute(context, operation).asStringOrNull();
- String secretValue = SECRET_VALUE.resolveModelAttribute(context, operation).asStringOrNull();
-
- if (entryType == null || entryType.equals(PasswordCredential.class.getCanonicalName())) {
- if ( ! credentialStore.exists(alias, PasswordCredential.class)) {
- throw LOGGER.credentialDoesNotExist(alias, PasswordCredential.class.getName());
- }
- storeSecret(credentialStore, alias, secretValue);
- context.addResponseWarning(Level.WARNING, LOGGER.reloadDependantServices());
- } else {
- String credentialStoreName = CredentialStoreResourceDefinition.credentialStoreName(operation);
- throw LOGGER.credentialStoreEntryTypeNotSupported(credentialStoreName, entryType);
- }
- } catch (CredentialStoreException e) {
- throw LOGGER.unableToCompleteOperation(e, dumpCause(e));
- }
- } catch (RuntimeException e) {
- throw new OperationFailedException(e);
- }
- }
-
- protected void generateSecretKeyOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- final int keySize = KEY_SIZE.resolveModelAttribute(context, operation).asInt();
-
- generateSecretKeyOperation(context, operation, credentialStore, keySize);
- }
-
- static String credentialStoreName(ModelNode operation) {
- String credentialStoreName = null;
- PathAddress pa = PathAddress.pathAddress(operation.require(ModelDescriptionConstants.OP_ADDR));
- for (int i = pa.size() - 1; i > 0; i--) {
- PathElement pe = pa.getElement(i);
- if (Constants.CREDENTIAL_STORE.equals(pe.getKey())) {
- credentialStoreName = pe.getValue();
- break;
- }
- }
-
- if (credentialStoreName == null) {
- throw LOGGER.operationAddressMissingKey(Constants.CREDENTIAL_STORE);
- }
-
- return credentialStoreName;
- }
-
- private static Class extends Credential> fromEntryType(final String entryTyoe) {
- if (PasswordCredential.class.getCanonicalName().equals(entryTyoe) || PasswordCredential.class.getSimpleName().equals(entryTyoe)) {
- return PasswordCredential.class;
- } else if (SecretKeyCredential.class.getCanonicalName().equals(entryTyoe) || SecretKeyCredential.class.getSimpleName().equals(entryTyoe)) {
- return SecretKeyCredential.class;
- }
-
- return null;
- }
-
- private static class CredentialStoreAddHandler extends DoohickeyAddHandler {
-
- private CredentialStoreAddHandler() {
- super(CREDENTIAL_STORE_RUNTIME_CAPABILITY, CONFIG_ATTRIBUTES, CREDENTIAL_STORE_API_CAPABILITY);
- }
-
- @Override
- protected void populateModel(final OperationContext context, final ModelNode operation, final Resource resource) throws OperationFailedException {
- super.populateModel(context, operation, resource);
- handleCredentialReferenceUpdate(context, resource.getModel());
- }
-
- @Override
- protected ElytronDoohickey createDoohickey(PathAddress resourceAddress) {
- return new CredentialStoreDoohickey(resourceAddress);
- }
-
- @Override
- protected void rollbackRuntime(OperationContext context, final ModelNode operation, final Resource resource) {
- rollbackCredentialStoreUpdate(CREDENTIAL_REFERENCE, context, resource);
- }
- }
-
- static class CredentialStoreDoohickey extends AbstractCredentialStoreDoohickey {
-
- private final String name;
- private volatile String location;
- private volatile boolean modifiable;
- private volatile String type;
- private volatile String providers;
- private volatile String otherProviders;
- private volatile String providerName;
- private volatile String relativeTo;
- private volatile Map credentialStoreAttributes;
- private volatile ModelNode model; // It would be nice to eliminate but credential reference performs resolution
- // and use of values in a single step.
-
- private volatile ExceptionRunnable reloader;
-
- protected CredentialStoreDoohickey(PathAddress resourceAddress) {
- super(resourceAddress);
- this.name = resourceAddress.getLastElement().getValue();
- }
-
- @Override
- protected void resolveRuntime(ModelNode model, OperationContext context) throws OperationFailedException {
- location = PATH.resolveModelAttribute(context, model).asStringOrNull();
- if (location == null) {
- location = LOCATION.resolveModelAttribute(context, model).asStringOrNull();
- }
- credentialStoreAttributes = new HashMap<>();
- modifiable = MODIFIABLE.resolveModelAttribute(context, model).asBoolean();
- credentialStoreAttributes.put(Constants.MODIFIABLE, Boolean.toString(modifiable));
- boolean create = CREATE.resolveModelAttribute(context, model).asBoolean();
- credentialStoreAttributes.put(Constants.CREATE, Boolean.toString(create));
- ModelNode implAttrModel = IMPLEMENTATION_PROPERTIES.resolveModelAttribute(context, model);
- if (implAttrModel.isDefined()) {
- for (String s : implAttrModel.keys()) {
- credentialStoreAttributes.put(s, implAttrModel.require(s).asString());
- }
- }
- type = TYPE.resolveModelAttribute(context, model).asStringOrNull();
- providers = PROVIDERS.resolveModelAttribute(context, model).asStringOrNull();
- otherProviders = OTHER_PROVIDERS.resolveModelAttribute(context, model).asStringOrNull();
- providerName = PROVIDER_NAME.resolveModelAttribute(context, model).asStringOrNull();
- relativeTo = RELATIVE_TO.resolveModelAttribute(context, model).asStringOrNull();
- if (type == null || type.equals(KeyStoreCredentialStore.KEY_STORE_CREDENTIAL_STORE)) {
- credentialStoreAttributes.putIfAbsent(CS_KEY_STORE_TYPE_ATTRIBUTE, "JCEKS");
- }
-
- String implAttrKeyStoreType = credentialStoreAttributes.get(CS_KEY_STORE_TYPE_ATTRIBUTE);
- if (location == null && implAttrKeyStoreType != null && filebasedKeystoreTypes.contains(implAttrKeyStoreType.toUpperCase(Locale.ENGLISH))) {
- throw LOGGER.filebasedKeystoreLocationMissing(implAttrKeyStoreType);
- }
- this.model = model;
- }
-
- @Override
- protected ExceptionSupplier prepareServiceSupplier(OperationContext context,
- CapabilityServiceBuilder> serviceBuilder) throws OperationFailedException {
-
- final Supplier pathManager;
- if (relativeTo != null) {
- pathManager = serviceBuilder.requires(PathManagerService.SERVICE_NAME);
- serviceBuilder.requires(pathName(relativeTo));
- } else {
- pathManager = null;
- }
-
- final Supplier providerSupplier;
- if (providers != null) {
- String providersCapabilityName = RuntimeCapability.buildDynamicCapabilityName(PROVIDERS_CAPABILITY, providers);
- ServiceName providerLoaderServiceName = context.getCapabilityServiceName(providersCapabilityName,
- Provider[].class);
-
- providerSupplier = serviceBuilder.requires(providerLoaderServiceName);
- } else {
- providerSupplier = null;
- }
-
- final Supplier otherProviderSupplier;
- if (otherProviders != null) {
- String providersCapabilityName = RuntimeCapability.buildDynamicCapabilityName(PROVIDERS_CAPABILITY,
- otherProviders);
- ServiceName otherProvidersLoaderServiceName = context.getCapabilityServiceName(providersCapabilityName,
- Provider[].class);
-
- otherProviderSupplier = serviceBuilder.requires(otherProvidersLoaderServiceName);
- } else {
- otherProviderSupplier = null;
- }
-
- ExceptionSupplier credentialSourceSupplier = CredentialReference
- .getCredentialSourceSupplier(context, CredentialStoreResourceDefinition.CREDENTIAL_REFERENCE, model,
- serviceBuilder);
-
- return new ExceptionSupplier() {
-
- @Override
- public CredentialStore get() throws StartException {
- try {
- if (location != null) {
- PathResolver pathResolver = pathResolver();
- pathResolver.path(location);
- if (relativeTo != null) {
- pathResolver.relativeTo(relativeTo, pathManager.get());
- }
- File resolved = pathResolver.resolve();
- pathResolver.clear();
- credentialStoreAttributes.put(Constants.LOCATION, resolved.getAbsolutePath());
- } else {
- credentialStoreAttributes.put(Constants.LOCATION, null);
- }
-
- LOGGER.tracef("starting CredentialStore: name = %s", name);
-
- CredentialStore cs = getCredentialStoreInstance(providerSupplier != null ? providerSupplier.get() : null);
- Provider[] otherProvidersArr = otherProviderSupplier != null ? otherProviderSupplier.get() : null;
- if (LOGGER.isTraceEnabled()) {
- LOGGER.tracef(
- "initializing CredentialStore: name = %s type = %s provider = %s otherProviders = %s attributes = %s",
- name, type, providerName, Arrays.toString(otherProvidersArr), credentialStoreAttributes);
- }
-
- CredentialSourceProtectionParameter credentialSource = resolveCredentialStoreProtectionParameter(name,
- credentialSourceSupplier != null ? credentialSourceSupplier.get() : null);
- reloader = new ExceptionRunnable() {
-
- @Override
- public void run() throws GeneralSecurityException {
- synchronized (EmptyProvider.getInstance()) {
- cs.initialize(credentialStoreAttributes, credentialSource, otherProvidersArr);
- }
- }
- };
- reloader.run();
-
- return cs;
- } catch (Exception e) {
- throw LOGGER.unableToStartService(e);
- }
- }
-
- };
-
- }
-
- @Override
- protected CredentialStore createImmediately(OperationContext foreignContext) throws OperationFailedException {
- File resolvedPath = null;
- if (location != null) {
- resolvedPath = resolveRelativeToImmediately(location, relativeTo, foreignContext);
- credentialStoreAttributes.put(Constants.LOCATION, resolvedPath.getAbsolutePath());
- }
-
- Provider[] providers = null;
- if (this.providers != null) {
- ExceptionFunction providerApi = foreignContext
- .getCapabilityRuntimeAPI(PROVIDERS_API_CAPABILITY, this.providers, ExceptionFunction.class);
- providers = providerApi.apply(foreignContext);
- }
-
- Provider[] otherProviders;
- if (this.otherProviders != null) {
- ExceptionFunction providerApi = foreignContext
- .getCapabilityRuntimeAPI(PROVIDERS_API_CAPABILITY, this.otherProviders, ExceptionFunction.class);
- otherProviders = providerApi.apply(foreignContext);
- } else {
- otherProviders = null;
- }
-
- CredentialSource credentialSource = getCredentialSource(foreignContext, CREDENTIAL_REFERENCE, model);
-
- try {
- CredentialStore credentialStore = getCredentialStoreInstance(providers);
-
- CredentialSourceProtectionParameter protectionParamter = resolveCredentialStoreProtectionParameter(name, credentialSource);
- reloader = new ExceptionRunnable() {
-
- @Override
- public void run() throws GeneralSecurityException {
- synchronized (EmptyProvider.getInstance()) {
- credentialStore.initialize(credentialStoreAttributes, protectionParamter, otherProviders);
- }
- }
- };
- reloader.run();
-
- return credentialStore;
- } catch (GeneralSecurityException | IOException e) {
- throw LOGGER.unableToInitialiseCredentialStore(e);
- }
-
- }
-
- @Override
- protected void reload(OperationContext context) throws GeneralSecurityException, OperationFailedException {
- if (reloader != null) {
- reloader.run();
- } else {
- super.apply(context);
- }
- }
-
- private CredentialStore getCredentialStoreInstance(Provider[] injectedProviders) throws CredentialStoreException, NoSuchAlgorithmException, NoSuchProviderException {
- String resolvedType = type != null ? type : KeyStoreCredentialStore.KEY_STORE_CREDENTIAL_STORE;
- if (providerName != null) {
- // directly specified provider
- return CredentialStore.getInstance(resolvedType, providerName);
- }
-
- if (LOGGER.isTraceEnabled()) {
- LOGGER.tracef("obtaining CredentialStore %s from providers %s", name, Arrays.toString(injectedProviders));
- }
- if (injectedProviders != null) {
- // injected provider list, select the first provider with corresponding type
- for (Provider p : injectedProviders) {
- try {
- return CredentialStore.getInstance(resolvedType, p);
- } catch (NoSuchAlgorithmException ignore) {
- }
- }
-
- throw LOGGER.providerLoaderCannotSupplyProvider(providers, resolvedType);
- } else {
- // default provider
- return CredentialStore.getInstance(resolvedType);
- }
- }
-
- private static CredentialSourceProtectionParameter resolveCredentialStoreProtectionParameter(String name, CredentialSource cs) throws IOException {
- if (cs != null) {
- Credential credential = cs.getCredential(PasswordCredential.class);
-
- LOGGER.tracef("resolving CredentialStore %s ProtectionParameter from %s", name, credential);
- return credentialToCredentialSourceProtectionParameter(credential);
- } else {
- throw LOGGER.credentialStoreProtectionParameterCannotBeResolved(name);
- }
- }
-
- private static CredentialSourceProtectionParameter credentialToCredentialSourceProtectionParameter(Credential credential) {
- return new CredentialSourceProtectionParameter(IdentityCredentials.NONE.withCredential(credential));
- }
-
- }
-}
diff --git a/subsystem/src/main/java/org/wildfly/extension/elytron/tls/SecretKeyCredentialStoreDefinition.java b/subsystem/src/main/java/org/wildfly/extension/elytron/tls/SecretKeyCredentialStoreDefinition.java
deleted file mode 100644
index eb5f49c..0000000
--- a/subsystem/src/main/java/org/wildfly/extension/elytron/tls/SecretKeyCredentialStoreDefinition.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright 2021 Red Hat, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.wildfly.extension.elytron.tls;
-
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_API_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.Capabilities.CREDENTIAL_STORE_RUNTIME_CAPABILITY;
-import static org.wildfly.extension.elytron.tls.ElytronTlsExtension.isServerOrHostController;
-import static org.wildfly.extension.elytron.tls.FileAttributeDefinitions.RELATIVE_TO;
-import static org.wildfly.extension.elytron.tls.FileAttributeDefinitions.pathName;
-import static org.wildfly.extension.elytron.tls.FileAttributeDefinitions.pathResolver;
-import static org.wildfly.extension.elytron.tls._private.ElytronTLSMessages.LOGGER;
-import static org.wildfly.security.encryption.SecretKeyUtil.generateSecretKey;
-
-import java.io.File;
-import java.security.GeneralSecurityException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import javax.crypto.SecretKey;
-
-import org.jboss.as.controller.AbstractAddStepHandler;
-import org.jboss.as.controller.AttributeDefinition;
-import org.jboss.as.controller.CapabilityServiceBuilder;
-import org.jboss.as.controller.OperationContext;
-import org.jboss.as.controller.OperationFailedException;
-import org.jboss.as.controller.OperationStepHandler;
-import org.jboss.as.controller.PathAddress;
-import org.jboss.as.controller.PathElement;
-import org.jboss.as.controller.SimpleAttributeDefinition;
-import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
-import org.jboss.as.controller.SimpleOperationDefinition;
-import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
-import org.jboss.as.controller.SimpleResourceDefinition;
-import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
-import org.jboss.as.controller.registry.ManagementResourceRegistration;
-import org.jboss.as.controller.registry.OperationEntry;
-import org.jboss.as.controller.services.path.PathManagerService;
-import org.jboss.dmr.ModelNode;
-import org.jboss.dmr.ModelType;
-import org.jboss.msc.service.StartException;
-import org.wildfly.common.function.ExceptionRunnable;
-import org.wildfly.common.function.ExceptionSupplier;
-import org.wildfly.extension.elytron.tls.FileAttributeDefinitions.PathResolver;
-import org.wildfly.security.credential.SecretKeyCredential;
-import org.wildfly.security.credential.store.CredentialStore;
-
-/**
- * A resource definitions for a simple credential store which just supports the storage of
- * {@link SecretKey} instances stored in the clear.
- *
- * Whilst the keys are stored in the clear this resource allows administrators to bootstrap in
- * an initial key which can be used to encrypt passwords defined within the management model.
- *
- * @author Darran Lofthouse
- */
-class SecretKeyCredentialStoreDefinition extends AbstractCredentialStoreResourceDefinition {
-
- private static final String CREDENTIAL_STORE_TYPE = "PropertiesCredentialStore";
-
- static final SimpleAttributeDefinition PATH =
- new SimpleAttributeDefinitionBuilder(Constants.PATH, FileAttributeDefinitions.PATH)
- .setAttributeGroup(Constants.FILE)
- .setRequired(true)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition CREATE = new SimpleAttributeDefinitionBuilder(Constants.CREATE, ModelType.BOOLEAN, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setDefaultValue(ModelNode.TRUE)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition POPULATE = new SimpleAttributeDefinitionBuilder(Constants.POPULATE, ModelType.BOOLEAN, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setDefaultValue(ModelNode.TRUE)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition KEY_SIZE = new SimpleAttributeDefinitionBuilder(Constants.KEY_SIZE, ModelType.INT, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setDefaultValue(new ModelNode(256))
- .setAllowedValues(128, 192, 256)
- .setRestartAllServices()
- .build();
-
- static final SimpleAttributeDefinition DEFAULT_ALIAS = new SimpleAttributeDefinitionBuilder(Constants.DEFAULT_ALIAS, ModelType.STRING, true)
- .setAttributeGroup(Constants.IMPLEMENTATION)
- .setAllowExpression(true)
- .setDefaultValue(new ModelNode("key"))
- .setRestartAllServices()
- .build();
-
- // Resource Resolver
- private static final StandardResourceDescriptionResolver RESOURCE_RESOLVER = ElytronTlsExtension.getResourceDescriptionResolver(Constants.SECRET_KEY_CREDENTIAL_STORE);
-
- static final AttributeDefinition[] CONFIG_ATTRIBUTES = new AttributeDefinition[] { RELATIVE_TO, PATH, CREATE, POPULATE, KEY_SIZE, DEFAULT_ALIAS };
-
- private static final AbstractAddStepHandler ADD = new SecretKeyCredentialStoreAddHandler();
- private static final OperationStepHandler REMOVE = new TrivialCapabilityServiceRemoveHandler(ADD, CREDENTIAL_STORE_RUNTIME_CAPABILITY);
-
- // Operation Definitions and Parameters
-
- private static final SimpleOperationDefinition REMOVE_ALIAS = new SimpleOperationDefinitionBuilder(Constants.REMOVE_ALIAS, OPERATION_RESOLVER)
- .setParameters(ALIAS)
- .setRuntimeOnly()
- .build();
-
- private static final SimpleAttributeDefinition KEY_SIZE_PARAMETER = new SimpleAttributeDefinitionBuilder(Constants.KEY_SIZE, ModelType.INT, true)
- .setAllowExpression(true)
- .setAllowedValues(128, 192, 256)
- .setRestartAllServices()
- .build();
-
- private static final SimpleOperationDefinition GENERATE_SECRET_KEY = new SimpleOperationDefinitionBuilder(Constants.GENERATE_SECRET_KEY, OPERATION_RESOLVER)
- .setParameters(ALIAS, KEY_SIZE_PARAMETER)
- .setRuntimeOnly()
- .build();
-
- SecretKeyCredentialStoreDefinition() {
- super(new SimpleResourceDefinition.Parameters(PathElement.pathElement(Constants.SECRET_KEY_CREDENTIAL_STORE), RESOURCE_RESOLVER)
- .setAddHandler(ADD)
- .setRemoveHandler(REMOVE)
- .setAddRestartLevel(OperationEntry.Flag.RESTART_NONE)
- .setRemoveRestartLevel(OperationEntry.Flag.RESTART_NONE)
- .setCapabilities(CREDENTIAL_STORE_RUNTIME_CAPABILITY)
- );
- }
-
- @Override
- protected AttributeDefinition[] getAttributeDefinitions() {
- return CONFIG_ATTRIBUTES;
- }
-
-
- @Override
- public void registerOperations(ManagementResourceRegistration resourceRegistration) {
- super.registerOperations(resourceRegistration); // Always needed to register add / remove.
-
- boolean isServerOrHostController = isServerOrHostController(resourceRegistration);
- Map operationMethods = new HashMap<>();
-
- operationMethods.put(Constants.READ_ALIASES, this::readAliasesOperation);
- if (isServerOrHostController) {
- operationMethods.put(Constants.REMOVE_ALIAS, this::removeAliasOperation);
- operationMethods.put(Constants.EXPORT_SECRET_KEY, this::exportSecretKeyOperation);
- operationMethods.put(Constants.GENERATE_SECRET_KEY, this::generateSecretKeyOperation);
- operationMethods.put(Constants.IMPORT_SECRET_KEY, this::importSecretKeyOperation);
- }
-
- OperationStepHandler operationHandler = new CredentialStoreRuntimeHandler(operationMethods);
- resourceRegistration.registerOperationHandler(READ_ALIASES, operationHandler);
- if (isServerOrHostController) {
- resourceRegistration.registerOperationHandler(REMOVE_ALIAS, operationHandler);
- resourceRegistration.registerOperationHandler(EXPORT_SECRET_KEY, operationHandler);
- resourceRegistration.registerOperationHandler(GENERATE_SECRET_KEY, operationHandler);
- resourceRegistration.registerOperationHandler(IMPORT_SECRET_KEY, operationHandler);
- resourceRegistration.registerOperationHandler(RELOAD, RELOAD_HANDLER);
- }
- }
-
- /*
- * Operation Handler Methods.
- */
-
- void removeAliasOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- super.removeAliasOperation(context, operation, credentialStore, SecretKeyCredential.class);
- }
-
- protected void generateSecretKeyOperation(OperationContext context, ModelNode operation, CredentialStore credentialStore) throws OperationFailedException {
- final int keySize;
- ModelNode keySizeModel = KEY_SIZE_PARAMETER.resolveModelAttribute(context, operation);
- if (keySizeModel.isDefined()) {
- keySize = keySizeModel.asInt();
- } else {
- ModelNode resourceModel = context.readResource(PathAddress.EMPTY_ADDRESS).getModel();
- keySize = KEY_SIZE.resolveModelAttribute(context, resourceModel).asInt();
- }
-
- generateSecretKeyOperation(context, operation, credentialStore, keySize);
- }
-
- static class SecretKeyCredentialStoreAddHandler extends DoohickeyAddHandler {
-
- private SecretKeyCredentialStoreAddHandler() {
- super(CREDENTIAL_STORE_RUNTIME_CAPABILITY, CONFIG_ATTRIBUTES, CREDENTIAL_STORE_API_CAPABILITY);
- }
-
- @Override
- protected ElytronDoohickey createDoohickey(PathAddress resourceAddress) {
- return new SecretKeyDoohickey(resourceAddress);
- }
-
- }
-
- static class SecretKeyDoohickey extends AbstractCredentialStoreDoohickey {
-
- private volatile String relativeTo;
- private volatile String path;
- private volatile boolean create;
- private volatile boolean populate;
- private volatile int keySize;
- private volatile String defaultAlias;
-
- private volatile ExceptionRunnable reloader;
-
- protected SecretKeyDoohickey(PathAddress resourceAddress) {
- super(resourceAddress);
- }
-
- @Override
- protected void resolveRuntime(ModelNode model, OperationContext context) throws OperationFailedException {
- relativeTo = RELATIVE_TO.resolveModelAttribute(context, model).asStringOrNull();
- path = PATH.resolveModelAttribute(context, model).asString();
- create = CREATE.resolveModelAttribute(context, model).asBoolean();
- populate = POPULATE.resolveModelAttribute(context, model).asBoolean();
- keySize = KEY_SIZE.resolveModelAttribute(context, model).asInt();
- defaultAlias = DEFAULT_ALIAS.resolveModelAttribute(context, model).asString();
- }
-
- @Override
- protected ExceptionSupplier prepareServiceSupplier(OperationContext context,
- CapabilityServiceBuilder> serviceBuilder) {
-
- final Supplier pathManager;
- if (relativeTo != null) {
- pathManager = serviceBuilder.requires(PathManagerService.SERVICE_NAME);
- serviceBuilder.requires(pathName(relativeTo));
- } else {
- pathManager = null;
- }
-
- return new ExceptionSupplier() {
-
- @Override
- public CredentialStore get() throws StartException {
- try {
- PathResolver pathResolver = pathResolver();
- pathResolver.path(path);
- if (relativeTo != null) {
- pathResolver.relativeTo(relativeTo, pathManager.get());
- }
- File resolved = pathResolver.resolve();
- pathResolver.clear();
-
- return createCredentialStore(resolved);
- } catch (GeneralSecurityException e) {
- throw LOGGER.unableToStartService(e);
- }
- }
- };
- }
-
- @Override
- protected CredentialStore createImmediately(OperationContext foreignContext) throws OperationFailedException {
- try {
- return createCredentialStore(resolveRelativeToImmediately(path, relativeTo, foreignContext));
- } catch (GeneralSecurityException e) {
- throw LOGGER.unableToCreateCredentialStoreImmediately(e);
- }
- }
-
- private CredentialStore createCredentialStore(final File resolved) throws GeneralSecurityException {
- CredentialStore credentialStore = CredentialStore.getInstance(CREDENTIAL_STORE_TYPE);
-
- final Map configuration = new HashMap<>();
- configuration.put(Constants.LOCATION, resolved.getAbsolutePath());
- if (create) {
- configuration.put(Constants.CREATE, Boolean.TRUE.toString());
- }
-
- reloader = new ExceptionRunnable() {
-
- @Override
- public void run() throws GeneralSecurityException {
- credentialStore.initialize(configuration);
- }
- };
- reloader.run();
-
- if (populate && !credentialStore.getAliases().contains(defaultAlias)) {
- SecretKey secretKey = generateSecretKey(keySize);
- SecretKeyCredential credential = new SecretKeyCredential(secretKey);
-
- credentialStore.store(defaultAlias, credential);
- credentialStore.flush();
- }
-
- return credentialStore;
- }
-
- @Override
- protected void reload(OperationContext context) throws GeneralSecurityException, OperationFailedException {
- if (reloader != null) {
- reloader.run();
- } else {
- super.apply(context);
- }
- }
-
- }
-
-}
diff --git a/subsystem/src/test/resources/org/wildfly/extension/elytron/tls/elytron-subsys.xml.example b/subsystem/src/test/resources/org/wildfly/extension/elytron/tls/elytron-subsys.xml.example
deleted file mode 100644
index 7d67ac0..0000000
--- a/subsystem/src/test/resources/org/wildfly/extension/elytron/tls/elytron-subsys.xml.example
+++ /dev/null
@@ -1,404 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/testsuite/integration/elytron-tls/pom.xml b/testsuite/integration/elytron-tls/pom.xml
index 2ea23a1..63d5e95 100644
--- a/testsuite/integration/elytron-tls/pom.xml
+++ b/testsuite/integration/elytron-tls/pom.xml
@@ -40,6 +40,11 @@
elytron-tls-subsystem
test
+
+ org.wildfly.core
+ wildfly-elytron-integration
+ test
+
org.wildfly.core
wildfly-core-test-runner