mirror of
https://github.com/Graylog2/graylog2-server.git
synced 2026-03-13 09:32:21 +08:00
Refactoring/keystores code simplification (#18951)
* Datanode preflight provisioning IT * npe fix * fixed naming * Add test for uploaded CA in preflight provisioning * Keystore code simplifications in datanode * more deprecations * KeystoreMongoLocation code cleanup * Remove KeyPairChecker, simplify code * code cleanup --------- Co-authored-by: Matthias Oesterheld <33032967+moesterheld@users.noreply.github.com>
This commit is contained in:
@@ -20,12 +20,12 @@ import com.google.common.eventbus.EventBus;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.multibindings.OptionalBinder;
|
||||
import jakarta.ws.rs.container.DynamicFeature;
|
||||
import jakarta.ws.rs.ext.ExceptionMapper;
|
||||
import org.graylog.datanode.Configuration;
|
||||
import org.graylog.datanode.process.ProcessStateMachine;
|
||||
import org.graylog.datanode.process.ProcessStateMachineProvider;
|
||||
import org.graylog.datanode.shared.system.activities.DataNodeActivityWriter;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreContentMover;
|
||||
import org.graylog.security.certutil.keystore.storage.SinglePasswordKeystoreContentMover;
|
||||
import org.graylog2.bindings.providers.ClusterEventBusProvider;
|
||||
import org.graylog2.cluster.ClusterConfigServiceImpl;
|
||||
import org.graylog2.cluster.nodes.DataNodeClusterService;
|
||||
@@ -40,9 +40,6 @@ import org.graylog2.plugin.inject.Graylog2Module;
|
||||
import org.graylog2.shared.bindings.providers.EventBusProvider;
|
||||
import org.graylog2.shared.system.activities.ActivityWriter;
|
||||
|
||||
import jakarta.ws.rs.container.DynamicFeature;
|
||||
import jakarta.ws.rs.ext.ExceptionMapper;
|
||||
|
||||
public class ServerBindings extends Graylog2Module {
|
||||
private final Configuration configuration;
|
||||
private final boolean isMigrationCommand;
|
||||
@@ -80,7 +77,6 @@ public class ServerBindings extends Graylog2Module {
|
||||
|
||||
private void bindSingletons() {
|
||||
bind(ClusterConfigService.class).to(ClusterConfigServiceImpl.class).asEagerSingleton();
|
||||
bind(KeystoreContentMover.class).to(SinglePasswordKeystoreContentMover.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
private void bindInterfaces() {
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package org.graylog.datanode.bootstrap.preflight;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.inject.Singleton;
|
||||
import org.bouncycastle.operator.OperatorException;
|
||||
import org.graylog.datanode.configuration.DatanodeConfiguration;
|
||||
import org.graylog.security.certutil.CertConstants;
|
||||
@@ -27,7 +30,7 @@ import org.graylog.security.certutil.csr.CertificateAndPrivateKeyMerger;
|
||||
import org.graylog.security.certutil.csr.CsrGenerator;
|
||||
import org.graylog.security.certutil.csr.exceptions.CSRGenerationException;
|
||||
import org.graylog.security.certutil.csr.storage.CsrMongoStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.SmartKeystoreStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreMongoStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoCollections;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoLocation;
|
||||
import org.graylog.security.certutil.privatekey.PrivateKeyEncryptedFileStorage;
|
||||
@@ -42,10 +45,6 @@ import org.graylog2.shared.SuppressForbidden;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.file.Path;
|
||||
@@ -68,9 +67,10 @@ public class DataNodeConfigurationPeriodical extends Periodical {
|
||||
private final CsrGenerator csrGenerator;
|
||||
private final CertChainStorage certMongoStorage;
|
||||
private final CertificateAndPrivateKeyMerger certificateAndPrivateKeyMerger;
|
||||
private final SmartKeystoreStorage keystoreStorage;
|
||||
private final char[] passwordSecret;
|
||||
|
||||
private final KeystoreMongoStorage mongoKeyStorage;
|
||||
|
||||
@Inject
|
||||
public DataNodeConfigurationPeriodical(final DataNodeProvisioningService dataNodeProvisioningService,
|
||||
final NodeService<DataNodeDto> nodeService,
|
||||
@@ -79,9 +79,8 @@ public class DataNodeConfigurationPeriodical extends Periodical {
|
||||
final CsrGenerator csrGenerator,
|
||||
final CertChainMongoStorage certMongoStorage,
|
||||
final CertificateAndPrivateKeyMerger certificateAndPrivateKeyMerger,
|
||||
final SmartKeystoreStorage keystoreStorage,
|
||||
final @Named("password_secret") String passwordSecret,
|
||||
final DatanodeConfiguration datanodeConfiguration) throws IOException {
|
||||
final DatanodeConfiguration datanodeConfiguration, KeystoreMongoStorage mongoKeyStorage) throws IOException {
|
||||
this.dataNodeProvisioningService = dataNodeProvisioningService;
|
||||
this.nodeService = nodeService;
|
||||
this.nodeId = nodeId;
|
||||
@@ -89,10 +88,10 @@ public class DataNodeConfigurationPeriodical extends Periodical {
|
||||
this.csrGenerator = csrGenerator;
|
||||
this.certMongoStorage = certMongoStorage;
|
||||
this.certificateAndPrivateKeyMerger = certificateAndPrivateKeyMerger;
|
||||
this.keystoreStorage = keystoreStorage;
|
||||
// TODO: merge with real storage
|
||||
this.privateKeyEncryptedStorage = new PrivateKeyEncryptedFileStorage(datanodeConfiguration.datanodeDirectories().createConfigurationFile(Path.of("privateKey.cert")));
|
||||
this.passwordSecret = passwordSecret.toCharArray();
|
||||
this.mongoKeyStorage = mongoKeyStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,8 +132,7 @@ public class DataNodeConfigurationPeriodical extends Periodical {
|
||||
CertConstants.DATANODE_KEY_ALIAS
|
||||
);
|
||||
|
||||
final KeystoreMongoLocation location = new KeystoreMongoLocation(nodeId.getNodeId(), KeystoreMongoCollections.DATA_NODE_KEYSTORE_COLLECTION);
|
||||
keystoreStorage.writeKeyStore(location, nodeKeystore, secret, secret);
|
||||
mongoKeyStorage.writeKeyStore(KeystoreMongoLocation.datanode(nodeId), nodeKeystore, secret, secret);
|
||||
|
||||
//should be in one transaction, but we miss transactions...
|
||||
dataNodeProvisioningService.changeState(nodeId.getNodeId(), DataNodeProvisioningConfig.State.STORED);
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Graylog, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*/
|
||||
package org.graylog.datanode.configuration.certificates;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.graylog.security.certutil.ca.exceptions.KeyStoreStorageException;
|
||||
import org.graylog.security.certutil.keystore.storage.SmartKeystoreStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreLocation;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.util.Optional;
|
||||
|
||||
public class KeystoreReEncryption {
|
||||
|
||||
private final SmartKeystoreStorage keystoreStorage;
|
||||
private final String passwordSecret;
|
||||
|
||||
@Inject
|
||||
public KeystoreReEncryption(final SmartKeystoreStorage keystoreStorage,
|
||||
final @Named("password_secret") String passwordSecret) {
|
||||
this.keystoreStorage = keystoreStorage;
|
||||
this.passwordSecret = passwordSecret;
|
||||
}
|
||||
|
||||
public void reEncyptWithSecret(final KeystoreLocation originalLocation,
|
||||
final char[] originalPassword,
|
||||
final KeystoreLocation targetLocation
|
||||
) throws KeyStoreStorageException {
|
||||
reEncypt(originalLocation, originalPassword, targetLocation, passwordSecret.toCharArray());
|
||||
}
|
||||
|
||||
public char[] reEncyptWithOtp(final KeystoreLocation originalLocation,
|
||||
final char[] originalPassword,
|
||||
final KeystoreLocation targetLocation
|
||||
) throws KeyStoreStorageException {
|
||||
final char[] oneTimePassword = RandomStringUtils.randomAlphabetic(256).toCharArray();
|
||||
reEncypt(originalLocation, originalPassword, targetLocation, oneTimePassword);
|
||||
return oneTimePassword;
|
||||
}
|
||||
|
||||
private void reEncypt(final KeystoreLocation originalLocation,
|
||||
final char[] originalPassword,
|
||||
final KeystoreLocation targetLocation,
|
||||
final char[] newPassword
|
||||
) throws KeyStoreStorageException {
|
||||
|
||||
final Optional<KeyStore> keyStore = keystoreStorage.readKeyStore(originalLocation, originalPassword);
|
||||
if (keyStore.isPresent()) {
|
||||
final KeyStore originalKeystore = keyStore.get();
|
||||
keystoreStorage.writeKeyStore(targetLocation, originalKeystore, originalPassword, newPassword);
|
||||
} else {
|
||||
throw new KeyStoreStorageException("No keystore present in : " + originalLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,46 +16,49 @@
|
||||
*/
|
||||
package org.graylog.datanode.configuration.variants;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.graylog.datanode.Configuration;
|
||||
import org.graylog.datanode.configuration.DatanodeConfiguration;
|
||||
import org.graylog.datanode.configuration.certificates.KeystoreReEncryption;
|
||||
import org.graylog.security.certutil.ca.exceptions.KeyStoreStorageException;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreFileLocation;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoCollections;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreFileStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreMongoStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreMongoLocation;
|
||||
import org.graylog2.cluster.certificates.CertificatesService;
|
||||
import org.graylog2.plugin.system.NodeId;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class MongoCertSecureConfiguration extends SecureConfiguration {
|
||||
|
||||
private final KeystoreReEncryption keystoreReEncryption;
|
||||
private final NodeId nodeId;
|
||||
private final CertificatesService certificatesService;
|
||||
|
||||
private final char[] secret;
|
||||
private final KeystoreMongoLocation mongoLocation;
|
||||
|
||||
private final char[] mongoKeystorePassword;
|
||||
|
||||
private final KeystoreMongoStorage mongoKeyStorage;
|
||||
private final KeystoreFileStorage fileKeyStorage;
|
||||
|
||||
@Inject
|
||||
public MongoCertSecureConfiguration(final Configuration localConfiguration,
|
||||
final DatanodeConfiguration datanodeConfiguration,
|
||||
final KeystoreReEncryption keystoreReEncryption,
|
||||
public MongoCertSecureConfiguration(final DatanodeConfiguration datanodeConfiguration,
|
||||
final NodeId nodeId,
|
||||
final @Named("password_secret") String passwordSecret,
|
||||
final CertificatesService certificatesService
|
||||
final CertificatesService certificatesService, KeystoreMongoStorage mongoKeyStore, KeystoreFileStorage fileKeyStore
|
||||
) {
|
||||
super(datanodeConfiguration);
|
||||
this.keystoreReEncryption = keystoreReEncryption;
|
||||
this.nodeId = nodeId;
|
||||
this.certificatesService = certificatesService;
|
||||
|
||||
this.mongoLocation = new KeystoreMongoLocation(nodeId.getNodeId(), KeystoreMongoCollections.DATA_NODE_KEYSTORE_COLLECTION);
|
||||
this.secret = passwordSecret.toCharArray();
|
||||
this.mongoKeyStorage = mongoKeyStore;
|
||||
this.fileKeyStorage = fileKeyStore;
|
||||
|
||||
//TODO: matches line 123 of DataNodePreflightGeneratePeriodical, but both need to be changed
|
||||
this.mongoKeystorePassword = secret;
|
||||
@@ -63,22 +66,44 @@ public final class MongoCertSecureConfiguration extends SecureConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean isConfigured(Configuration localConfiguration) {
|
||||
return certificatesService.hasCert(mongoLocation);
|
||||
return certificatesService.hasCert(getMongoKeystoreLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpensearchSecurityConfiguration build() throws KeyStoreStorageException, IOException, GeneralSecurityException {
|
||||
|
||||
final KeystoreFileLocation targetTransportKeystoreLocation = getTransportKeystoreLocation();
|
||||
final KeystoreFileLocation targetHttpKeystoreLocation = getHttpKeystoreLocation();
|
||||
final Path targetTransportKeystoreLocation = getTransportKeystoreLocation();
|
||||
final Path targetHttpKeystoreLocation = getHttpKeystoreLocation();
|
||||
|
||||
|
||||
// this will take the mongodb-stored keys and persist them on a disk, in the opensearch configuration directory
|
||||
keystoreReEncryption.reEncyptWithSecret(mongoLocation, mongoKeystorePassword, targetTransportKeystoreLocation);
|
||||
keystoreReEncryption.reEncyptWithSecret(mongoLocation, mongoKeystorePassword, targetHttpKeystoreLocation);
|
||||
final KeystoreMongoLocation mongoKeystoreLocation = getMongoKeystoreLocation();
|
||||
reEncypt(mongoKeystoreLocation, mongoKeystorePassword, targetTransportKeystoreLocation, secret);
|
||||
reEncypt(mongoKeystoreLocation, mongoKeystorePassword, targetHttpKeystoreLocation, secret);
|
||||
|
||||
return new OpensearchSecurityConfiguration(
|
||||
new KeystoreInformation(targetTransportKeystoreLocation.keystorePath().toAbsolutePath(), secret),
|
||||
new KeystoreInformation(targetHttpKeystoreLocation.keystorePath().toAbsolutePath(), secret)
|
||||
new KeystoreInformation(targetTransportKeystoreLocation.toAbsolutePath(), secret),
|
||||
new KeystoreInformation(targetHttpKeystoreLocation.toAbsolutePath(), secret)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private KeystoreMongoLocation getMongoKeystoreLocation() {
|
||||
return KeystoreMongoLocation.datanode(nodeId);
|
||||
}
|
||||
|
||||
private void reEncypt(final KeystoreMongoLocation originalLocation,
|
||||
final char[] originalPassword,
|
||||
final Path targetLocation,
|
||||
final char[] newPassword
|
||||
) throws KeyStoreStorageException {
|
||||
|
||||
final Optional<KeyStore> keyStore = mongoKeyStorage.readKeyStore(originalLocation, originalPassword);
|
||||
if (keyStore.isPresent()) {
|
||||
final KeyStore originalKeystore = keyStore.get();
|
||||
fileKeyStorage.writeKeyStore(targetLocation, originalKeystore, originalPassword, newPassword);
|
||||
} else {
|
||||
throw new KeyStoreStorageException("No keystore present in : " + originalLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.graylog.datanode.configuration.variants;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.graylog.datanode.configuration.DatanodeConfiguration;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreFileLocation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
@@ -41,14 +40,13 @@ public sealed abstract class SecureConfiguration implements SecurityConfiguratio
|
||||
*/
|
||||
private static final Path TARGET_DATANODE_TRANSPORT_KEYSTORE_FILENAME = Path.of("transport-keystore.p12");
|
||||
|
||||
private final Supplier<KeystoreFileLocation> httpKeystoreLocation;
|
||||
private final Supplier<KeystoreFileLocation> transportKeystoreLocation;
|
||||
private final Supplier<Path> httpKeystoreLocation;
|
||||
private final Supplier<Path> transportKeystoreLocation;
|
||||
|
||||
public SecureConfiguration(final DatanodeConfiguration datanodeConfiguration) {
|
||||
this.httpKeystoreLocation = Suppliers.memoize(() -> {
|
||||
try {
|
||||
final Path filePath = datanodeConfiguration.datanodeDirectories().createOpensearchProcessConfigurationFile(TARGET_DATANODE_HTTP_KEYSTORE_FILENAME);
|
||||
return new KeystoreFileLocation(filePath);
|
||||
return datanodeConfiguration.datanodeDirectories().createOpensearchProcessConfigurationFile(TARGET_DATANODE_HTTP_KEYSTORE_FILENAME);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to create http keystore file", e);
|
||||
}
|
||||
@@ -56,20 +54,19 @@ public sealed abstract class SecureConfiguration implements SecurityConfiguratio
|
||||
|
||||
this.transportKeystoreLocation = Suppliers.memoize(() -> {
|
||||
try {
|
||||
final Path filePath = datanodeConfiguration.datanodeDirectories().createOpensearchProcessConfigurationFile(TARGET_DATANODE_TRANSPORT_KEYSTORE_FILENAME);
|
||||
return new KeystoreFileLocation(filePath);
|
||||
return datanodeConfiguration.datanodeDirectories().createOpensearchProcessConfigurationFile(TARGET_DATANODE_TRANSPORT_KEYSTORE_FILENAME);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to create transport keystore file", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
KeystoreFileLocation getHttpKeystoreLocation() {
|
||||
Path getHttpKeystoreLocation() {
|
||||
return httpKeystoreLocation.get();
|
||||
}
|
||||
|
||||
|
||||
KeystoreFileLocation getTransportKeystoreLocation() {
|
||||
Path getTransportKeystoreLocation() {
|
||||
return transportKeystoreLocation.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
*/
|
||||
package org.graylog.datanode.configuration.variants;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.graylog.datanode.Configuration;
|
||||
import org.graylog.datanode.configuration.DatanodeConfiguration;
|
||||
import org.graylog.datanode.configuration.OpensearchConfigurationException;
|
||||
import org.graylog.datanode.configuration.certificates.KeystoreReEncryption;
|
||||
import org.graylog.security.certutil.ca.exceptions.KeyStoreStorageException;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreFileLocation;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreFileStorage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -41,16 +42,16 @@ public final class UploadedCertFilesSecureConfiguration extends SecureConfigurat
|
||||
private final String uploadedHttpKeystoreFileName;
|
||||
private final String datanodeTransportCertificatePassword;
|
||||
private final String datanodeHttpCertificatePassword;
|
||||
private final KeystoreReEncryption keystoreReEncryption;
|
||||
private final KeystoreFileStorage keystoreFileStorage;
|
||||
private final DatanodeConfiguration datanodeConfiguration;
|
||||
|
||||
@Inject
|
||||
public UploadedCertFilesSecureConfiguration(final Configuration localConfiguration,
|
||||
final DatanodeConfiguration datanodeConfiguration,
|
||||
final KeystoreReEncryption keystoreReEncryption) {
|
||||
KeystoreFileStorage keystoreFileStorage) {
|
||||
super(datanodeConfiguration);
|
||||
this.datanodeConfiguration = datanodeConfiguration;
|
||||
this.keystoreReEncryption = keystoreReEncryption;
|
||||
this.keystoreFileStorage = keystoreFileStorage;
|
||||
|
||||
this.uploadedTransportKeystoreFileName = localConfiguration.getDatanodeTransportCertificate();
|
||||
this.uploadedHttpKeystoreFileName = localConfiguration.getDatanodeHttpCertificate();
|
||||
@@ -116,20 +117,45 @@ public final class UploadedCertFilesSecureConfiguration extends SecureConfigurat
|
||||
@Override
|
||||
public OpensearchSecurityConfiguration build() throws KeyStoreStorageException, IOException, GeneralSecurityException {
|
||||
|
||||
final KeystoreFileLocation targetTransportKeystoreLocation = getTransportKeystoreLocation();
|
||||
final KeystoreFileLocation targetHttpKeystoreLocation = getHttpKeystoreLocation();
|
||||
final Path targetTransportKeystoreLocation = getTransportKeystoreLocation();
|
||||
final Path targetHttpKeystoreLocation = getHttpKeystoreLocation();
|
||||
|
||||
final char[] transportOTP = keystoreReEncryption.reEncyptWithOtp(new KeystoreFileLocation(datanodeConfiguration.datanodeDirectories().resolveConfigurationSourceFile(uploadedTransportKeystoreFileName).orElseThrow(() -> new RuntimeException("This should not happen, certificate expected"))),
|
||||
final char[] transportOTP = reEncyptWithOtp(datanodeConfiguration.datanodeDirectories().resolveConfigurationSourceFile(uploadedTransportKeystoreFileName).orElseThrow(() -> new RuntimeException("This should not happen, certificate expected")),
|
||||
datanodeTransportCertificatePassword.toCharArray(),
|
||||
targetTransportKeystoreLocation);
|
||||
|
||||
final char[] httpOTP = keystoreReEncryption.reEncyptWithOtp(new KeystoreFileLocation(datanodeConfiguration.datanodeDirectories().resolveConfigurationSourceFile(uploadedHttpKeystoreFileName).orElseThrow(() -> new RuntimeException("This should not happen, certificate expected"))),
|
||||
final char[] httpOTP = reEncyptWithOtp(datanodeConfiguration.datanodeDirectories().resolveConfigurationSourceFile(uploadedHttpKeystoreFileName).orElseThrow(() -> new RuntimeException("This should not happen, certificate expected")),
|
||||
datanodeHttpCertificatePassword.toCharArray(),
|
||||
targetHttpKeystoreLocation);
|
||||
|
||||
return new OpensearchSecurityConfiguration(
|
||||
new KeystoreInformation(targetTransportKeystoreLocation.keystorePath().toAbsolutePath(), transportOTP),
|
||||
new KeystoreInformation(targetHttpKeystoreLocation.keystorePath().toAbsolutePath(), httpOTP)
|
||||
new KeystoreInformation(targetTransportKeystoreLocation.toAbsolutePath(), transportOTP),
|
||||
new KeystoreInformation(targetHttpKeystoreLocation.toAbsolutePath(), httpOTP)
|
||||
);
|
||||
}
|
||||
|
||||
public char[] reEncyptWithOtp(final Path originalLocation,
|
||||
final char[] originalPassword,
|
||||
final Path targetLocation
|
||||
) throws KeyStoreStorageException {
|
||||
// caution! This password changes during each configuration request!!!
|
||||
final char[] oneTimePassword = RandomStringUtils.randomAlphabetic(256).toCharArray();
|
||||
reEncypt(originalLocation, originalPassword, targetLocation, oneTimePassword);
|
||||
return oneTimePassword;
|
||||
}
|
||||
|
||||
private void reEncypt(final Path originalLocation,
|
||||
final char[] originalPassword,
|
||||
final Path targetLocation,
|
||||
final char[] newPassword
|
||||
) throws KeyStoreStorageException {
|
||||
|
||||
final Optional<KeyStore> keyStore = keystoreFileStorage.readKeyStore(originalLocation, originalPassword);
|
||||
if (keyStore.isPresent()) {
|
||||
final KeyStore originalKeystore = keyStore.get();
|
||||
keystoreFileStorage.writeKeyStore(targetLocation, originalKeystore, originalPassword, newPassword);
|
||||
} else {
|
||||
throw new KeyStoreStorageException("No keystore present in : " + originalLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user