From 9dc2a8df18ca30e68fa4e2e8fb329eaa9a062a8a Mon Sep 17 00:00:00 2001 From: Robert Godfrey Date: Tue, 19 Aug 2014 07:25:26 +0000 Subject: QPID-6017 : [Jaa Broker] Provide a mechanism by which "secure" attributes in the configuration can be encrypted git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1618815 13f79535-47bb-0310-9956-ffa450edef68 --- .../server/model/AbstractConfiguredObject.java | 64 ++++++++ .../java/org/apache/qpid/server/model/Broker.java | 3 + .../apache/qpid/server/model/ConfiguredObject.java | 2 + .../qpid/server/model/adapter/BrokerAdapter.java | 29 ++++ .../ConfigurationSecretEncrypterFactory.java | 29 ++++ .../security/encryption/AESKeyFileEncrypter.java | 130 ++++++++++++++++ .../encryption/AESKeyFileEncrypterFactory.java | 164 +++++++++++++++++++++ .../encryption/ConfigurationSecretEncrypter.java | 28 ++++ .../apache/qpid/server/store/GenericRecoverer.java | 1 + .../qpid/systest/rest/BrokerRestHttpsTest.java | 1 + .../apache/qpid/systest/rest/BrokerRestTest.java | 1 + 11 files changed, 452 insertions(+) create mode 100644 qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java create mode 100644 qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java create mode 100644 qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java create mode 100644 qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java (limited to 'qpid/java') diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java index b191db8523..18930d8817 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java @@ -64,6 +64,7 @@ import org.apache.qpid.server.configuration.updater.VoidTask; import org.apache.qpid.server.configuration.updater.VoidTaskWithException; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.security.encryption.ConfigurationSecretEncrypter; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.util.Action; import org.apache.qpid.server.util.ServerScopedRuntimeException; @@ -89,6 +90,8 @@ public abstract class AbstractConfiguredObject> im SECURE_VALUES = Collections.unmodifiableMap(secureValues); } + private ConfigurationSecretEncrypter _encrypter; + private enum DynamicState { UNINIT, OPENED, CLOSED }; private final AtomicReference _dynamicState = new AtomicReference<>(DynamicState.UNINIT); @@ -201,6 +204,16 @@ public abstract class AbstractConfiguredObject> im _automatedFields = model.getTypeRegistry().getAutomatedFields(getClass()); _stateChangeMethods = model.getTypeRegistry().getStateChangeMethods(getClass()); + + for(ConfiguredObject parent : parents.values()) + { + if(parent instanceof AbstractConfiguredObject && ((AbstractConfiguredObject)parent)._encrypter != null) + { + _encrypter = ((AbstractConfiguredObject)parent)._encrypter; + break; + } + } + Object idObj = attributes.get(ID); UUID uuid; @@ -541,6 +554,7 @@ public abstract class AbstractConfiguredObject> im if(skipCheck || _dynamicState.get() != DynamicState.OPENED) { onResolve(); + postResolve(); applyToChildren(new Action>() { @Override @@ -555,6 +569,10 @@ public abstract class AbstractConfiguredObject> im } } + protected void postResolve() + { + } + protected final void doCreation(final boolean skipCheck) { if(skipCheck || _dynamicState.get() != DynamicState.OPENED) @@ -593,6 +611,11 @@ public abstract class AbstractConfiguredObject> im { } + protected void setEncrypter(final ConfigurationSecretEncrypter encrypter) + { + _encrypter = encrypter; + } + protected void onResolve() { Set> unresolved = new HashSet<>(); @@ -1094,6 +1117,26 @@ public abstract class AbstractConfiguredObject> im { value = ((ConfiguredObject)value).getId(); } + if(attr.isSecure() && _encrypter != null && value != null) + { + if(value instanceof Collection || value instanceof Map) + { + ObjectMapper mapper = new ObjectMapper(); + try(StringWriter stringWriter = new StringWriter()) + { + mapper.writeValue(stringWriter, value); + value = _encrypter.encrypt(stringWriter.toString()); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Failure when encrypting a secret value", e); + } + } + else + { + value = _encrypter.encrypt(value.toString()); + } + } attributes.put(attr.getName(), value); } } @@ -1427,6 +1470,27 @@ public abstract class AbstractConfiguredObject> im return false; } + @Override + public void decryptSecrets() + { + if(_encrypter != null) + { + for (Map.Entry entry : _attributes.entrySet()) + { + ConfiguredObjectAttribute attr = + (ConfiguredObjectAttribute) _attributeTypes.get(entry.getKey()); + if (attr != null + && attr.isSecure() + && entry.getValue() instanceof String) + { + String decrypt = _encrypter.decrypt((String) entry.getValue()); + entry.setValue(decrypt); + } + + } + } + } + //========================================================================================= static String interpolate(ConfiguredObject object, String value) diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java index 1a9390f210..011aaeee23 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java @@ -51,6 +51,7 @@ public interface Broker> extends ConfiguredObject, EventL String STORE_VERSION = "storeVersion"; String STORE_PATH = "storePath"; String MODEL_VERSION = "modelVersion"; + String CONFIDENTIAL_CONFIGURATION_ENCRYPTION_PROVIDER = "confidentialConfigurationEncryptionProvider"; String CONNECTION_SESSION_COUNT_LIMIT = "connection.sessionCountLimit"; String CONNECTION_HEART_BEAT_DELAY = "connection.heartBeatDelay"; @@ -139,6 +140,8 @@ public interface Broker> extends ConfiguredObject, EventL @ManagedContextDefault(name = MESSAGE_COMPRESSION_THRESHOLD_SIZE) int DEFAULT_MESSAGE_COMPRESSION_THRESHOLD_SIZE = 102400; + @ManagedAttribute + String getConfidentialConfigurationEncryptionProvider(); @DerivedAttribute( persist = true ) String getModelVersion(); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java index ac5c75f80f..deda7768f3 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java @@ -253,4 +253,6 @@ public interface ConfiguredObject> Model getModel(); void delete(); + + void decryptSecrets(); } diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index af46bae1c4..afa68e23b1 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -47,6 +47,8 @@ import org.apache.qpid.server.logging.messages.BrokerMessages; import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.model.*; import org.apache.qpid.server.model.port.AbstractPortWithAuthProvider; +import org.apache.qpid.server.plugin.ConfigurationSecretEncrypterFactory; +import org.apache.qpid.server.plugin.PluggableFactoryLoader; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.access.Operation; @@ -94,6 +96,8 @@ public class BrokerAdapter extends AbstractConfiguredObject imple private boolean _statisticsReportingResetEnabled; @ManagedAttributeField private boolean _messageCompressionEnabled; + @ManagedAttributeField + private String _confidentialConfigurationEncryptionProvider; private State _state = State.UNINITIALIZED; @@ -122,6 +126,25 @@ public class BrokerAdapter extends AbstractConfiguredObject imple _dataReceived = new StatisticsCounter("bytes-received"); } + @Override + protected void postResolve() + { + super.postResolve(); + if(_confidentialConfigurationEncryptionProvider != null) + { + + PluggableFactoryLoader factoryLoader = + new PluggableFactoryLoader<>(ConfigurationSecretEncrypterFactory.class); + ConfigurationSecretEncrypterFactory factory = factoryLoader.get(_confidentialConfigurationEncryptionProvider); + if(factory == null) + { + throw new IllegalConfigurationException("Unknown Configuration Secret Encryption method " + _confidentialConfigurationEncryptionProvider); + } + setEncrypter(factory.createEncrypter(this)); + } + + } + public void onValidate() { super.onValidate(); @@ -367,6 +390,12 @@ public class BrokerAdapter extends AbstractConfiguredObject imple return _messageCompressionEnabled; } + @Override + public String getConfidentialConfigurationEncryptionProvider() + { + return _confidentialConfigurationEncryptionProvider; + } + @Override public String getModelVersion() { diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java new file mode 100644 index 0000000000..0548e6418a --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfigurationSecretEncrypterFactory.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.qpid.server.plugin; + +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.security.encryption.ConfigurationSecretEncrypter; + +public interface ConfigurationSecretEncrypterFactory extends Pluggable +{ + public ConfigurationSecretEncrypter createEncrypter(ConfiguredObject object); +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java new file mode 100644 index 0000000000..c0c92f0389 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypter.java @@ -0,0 +1,130 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.qpid.server.security.encryption; + + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.xml.bind.DatatypeConverter; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; + +class AESKeyFileEncrypter implements ConfigurationSecretEncrypter +{ + private static final String CIPHER_NAME = "AES/CBC/PKCS5Padding"; + private static final int AES_INITIALIZATION_VECTOR_LENGTH = 16; + private final SecretKey _secretKey; + private final SecureRandom _random = new SecureRandom(); + + AESKeyFileEncrypter(SecretKey secretKey) + { + _secretKey = secretKey; + } + + @Override + public String encrypt(final String unencrypted) + { + byte[] unencryptedBytes = unencrypted.getBytes(StandardCharsets.UTF_8); + try + { + byte[] ivbytes = new byte[AES_INITIALIZATION_VECTOR_LENGTH]; + _random.nextBytes(ivbytes); + Cipher cipher = Cipher.getInstance(CIPHER_NAME); + cipher.init(Cipher.ENCRYPT_MODE, _secretKey, new IvParameterSpec(ivbytes)); + byte[] encryptedBytes = readFromCipherStream(unencryptedBytes, cipher); + byte[] output = new byte[AES_INITIALIZATION_VECTOR_LENGTH + encryptedBytes.length]; + System.arraycopy(ivbytes, 0, output, 0, AES_INITIALIZATION_VECTOR_LENGTH); + System.arraycopy(encryptedBytes, 0, output, AES_INITIALIZATION_VECTOR_LENGTH, encryptedBytes.length); + return DatatypeConverter.printBase64Binary(output); + } + catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) + { + throw new IllegalConfigurationException("Unable to encrypt secret", e); + } + } + + @Override + public String decrypt(final String encrypted) + { + byte[] encryptedBytes = DatatypeConverter.parseBase64Binary(encrypted); + try + { + Cipher cipher = Cipher.getInstance(CIPHER_NAME); + cipher.init(Cipher.DECRYPT_MODE, _secretKey, new IvParameterSpec(encryptedBytes, 0, + AES_INITIALIZATION_VECTOR_LENGTH)); + return new String(readFromCipherStream(encryptedBytes, + AES_INITIALIZATION_VECTOR_LENGTH, + encryptedBytes.length - AES_INITIALIZATION_VECTOR_LENGTH, + cipher), StandardCharsets.UTF_8); + } + catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) + { + throw new IllegalConfigurationException("Unable to encrypt secret", e); + } + } + + + private byte[] readFromCipherStream(final byte[] unencryptedBytes, final Cipher cipher) throws IOException + { + return readFromCipherStream(unencryptedBytes, 0, unencryptedBytes.length, cipher); + } + + private byte[] readFromCipherStream(final byte[] unencryptedBytes, int offset, int length, final Cipher cipher) + throws IOException + { + final byte[] encryptedBytes; + try (CipherInputStream cipherInputStream = new CipherInputStream(new ByteArrayInputStream(unencryptedBytes, + offset, + length), cipher)) + { + byte[] buf = new byte[1024]; + int pos = 0; + int read; + while ((read = cipherInputStream.read(buf, pos, buf.length - pos)) != -1) + { + pos += read; + if (pos == buf.length - 1) + { + byte[] tmp = buf; + buf = new byte[buf.length + 1024]; + System.arraycopy(tmp, 0, buf, 0, tmp.length); + } + } + encryptedBytes = new byte[pos]; + System.arraycopy(buf, 0, encryptedBytes, 0, pos); + } + return encryptedBytes; + } + + + +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java new file mode 100644 index 0000000000..447f19b7ce --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/AESKeyFileEncrypterFactory.java @@ -0,0 +1,164 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.qpid.server.security.encryption; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.security.NoSuchAlgorithmException; +import java.util.EnumSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.qpid.server.BrokerOptions; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.plugin.ConfigurationSecretEncrypterFactory; +import org.apache.qpid.server.plugin.PluggableService; + +@PluggableService +public class AESKeyFileEncrypterFactory implements ConfigurationSecretEncrypterFactory +{ + private static final String ENCRYPTER_KEY_FILE = "encrypter.key.file"; + + private static final int AES_KEY_SIZE_BITS = 256; + private static final int AES_KEY_SIZE_BYTES = AES_KEY_SIZE_BITS / 8; + private static final String AES_ALGORITHM = "AES"; + + public static String TYPE = "AESKeyFile"; + + @Override + public ConfigurationSecretEncrypter createEncrypter(final ConfiguredObject object) + { + String fileLocation; + if(object.getContextKeys(false).contains(ENCRYPTER_KEY_FILE)) + { + fileLocation = object.getContextValue(String.class, ENCRYPTER_KEY_FILE); + } + else + { + + fileLocation = object.getContextValue(String.class, BrokerOptions.QPID_WORK_DIR) + + File.separator + ".keys" + File.separator + + object.getCategoryClass().getSimpleName() + "_" + + object.getName() + ".key"; + + Map context = object.getContext(); + Map modifiedContext = new LinkedHashMap<>(context); + modifiedContext.put(ENCRYPTER_KEY_FILE, fileLocation); + + object.setAttribute(ConfiguredObject.CONTEXT, context, modifiedContext); + } + File file = new File(fileLocation); + if(!file.exists()) + { + createAndPopulateKeyFile(file); + } + if(!file.isFile()) + { + throw new IllegalArgumentException("File '"+fileLocation+"' is not a regular file."); + } + try + { + Set permissions = Files.getPosixFilePermissions(file.toPath()); + + if (permissions.contains(PosixFilePermission.GROUP_READ) + || permissions.contains(PosixFilePermission.OTHERS_READ) + || permissions.contains(PosixFilePermission.GROUP_WRITE) + || permissions.contains(PosixFilePermission.OTHERS_WRITE)) + { + throw new IllegalStateException("Key file '" + + fileLocation + + "' has incorrect permissions. Only the owner " + + "should be able to read or write this file."); + } + if(Files.size(file.toPath()) != AES_KEY_SIZE_BYTES) + { + throw new IllegalConfigurationException("Key file '" + fileLocation + "' contains an incorrect about of data"); + } + + try(FileInputStream inputStream = new FileInputStream(file)) + { + byte[] key = new byte[AES_KEY_SIZE_BYTES]; + int pos = 0; + int read; + while(pos < key.length && -1 != ( read = inputStream.read(key, pos, key.length - pos))) + { + pos += read; + } + if(pos != key.length) + { + throw new IllegalConfigurationException("Key file '" + fileLocation + "' contained an incorrect about of data"); + } + SecretKeySpec keySpec = new SecretKeySpec(key, AES_ALGORITHM); + return new AESKeyFileEncrypter(keySpec); + } + } + catch (IOException e) + { + throw new IllegalConfigurationException("Unable to get file permissions: " + e.getMessage(), e); + } + } + + private void createAndPopulateKeyFile(final File file) + { + try + { + Set ownerOnly = EnumSet.of(PosixFilePermission.OWNER_READ, + PosixFilePermission.OWNER_WRITE, + PosixFilePermission.OWNER_EXECUTE); + Files.createDirectories(file.getParentFile().toPath(), PosixFilePermissions.asFileAttribute(ownerOnly)); + + Files.createFile(file.toPath(), PosixFilePermissions.asFileAttribute( + EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE))); + + KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM); + keyGenerator.init(AES_KEY_SIZE_BITS); + SecretKey key = keyGenerator.generateKey(); + try(FileOutputStream os = new FileOutputStream(file)) + { + os.write(key.getEncoded()); + } + + Files.setPosixFilePermissions(file.toPath(), EnumSet.of(PosixFilePermission.OWNER_READ)); + } + catch (NoSuchAlgorithmException | IOException e) + { + throw new IllegalConfigurationException("Cannot create key file: " + e.getMessage(), e); + } + + } + + @Override + public String getType() + { + return TYPE; + } +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java new file mode 100644 index 0000000000..d8c64c789c --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/encryption/ConfigurationSecretEncrypter.java @@ -0,0 +1,28 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.qpid.server.security.encryption; + +public interface ConfigurationSecretEncrypter +{ + String encrypt(String unencrypted); + + String decrypt(String encrypted); +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java index 58fa852849..9edc5fd30a 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java @@ -170,6 +170,7 @@ public class GenericRecoverer { updatesMade = true; ConfiguredObject resolved = recovered.resolve(); + resolved.decryptSecrets(); resolvedObjects.put(resolved.getId(), resolved); } else diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java index 319cc1c9da..c81bbd5469 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java @@ -65,6 +65,7 @@ public class BrokerRestHttpsTest extends QpidRestTestCase Asserts.assertAttributesPresent(brokerDetails, BrokerModel.getInstance().getTypeRegistry().getAttributeNames(Broker.class), Broker.PROCESS_PID, + Broker.CONFIDENTIAL_CONFIGURATION_ENCRYPTION_PROVIDER, ConfiguredObject.TYPE, ConfiguredObject.CREATED_BY, ConfiguredObject.CREATED_TIME, diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestTest.java index bae27b802c..ba95eecc6d 100644 --- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestTest.java +++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/BrokerRestTest.java @@ -204,6 +204,7 @@ public class BrokerRestTest extends QpidRestTestCase Asserts.assertAttributesPresent(brokerDetails, BrokerModel.getInstance().getTypeRegistry().getAttributeNames( Broker.class), Broker.PROCESS_PID, + Broker.CONFIDENTIAL_CONFIGURATION_ENCRYPTION_PROVIDER, ConfiguredObject.TYPE, ConfiguredObject.CREATED_BY, ConfiguredObject.CREATED_TIME, -- cgit v1.2.1