mirror of https://github.com/hyperledger/besu
PKI Block Creation cli configuration (#2619)
* Added CLI options for PKI Block Creation * BesuCommand changes for PKI Block Creation Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>pull/2623/head
parent
b9e1ce05c0
commit
047b680ddc
@ -0,0 +1,144 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* 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. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
package org.hyperledger.besu.cli.options.unstable; |
||||
|
||||
import static java.util.Arrays.asList; |
||||
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP; |
||||
|
||||
import org.hyperledger.besu.cli.util.CommandLineUtils; |
||||
import org.hyperledger.besu.ethereum.api.tls.FileBasedPasswordProvider; |
||||
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; |
||||
|
||||
import java.nio.file.Path; |
||||
import java.util.Optional; |
||||
|
||||
import org.apache.logging.log4j.Logger; |
||||
import picocli.CommandLine; |
||||
import picocli.CommandLine.Option; |
||||
import picocli.CommandLine.ParameterException; |
||||
|
||||
public class PkiBlockCreationOptions { |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-enabled"}, |
||||
hidden = true, |
||||
description = "Enable PKI integration (default: ${DEFAULT-VALUE})") |
||||
Boolean enabled = false; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-keystore-type"}, |
||||
hidden = true, |
||||
paramLabel = "<NAME>", |
||||
description = "PKI service keystore type. Required if PKI Block Creation is enabled.") |
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) |
||||
String keyStoreType = PkiKeyStoreConfiguration.DEFAULT_KEYSTORE_TYPE; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-keystore-file"}, |
||||
hidden = true, |
||||
paramLabel = MANDATORY_FILE_FORMAT_HELP, |
||||
description = "Keystore containing key/certificate for PKI Block Creation.") |
||||
Path keyStoreFile = null; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-keystore-password-file"}, |
||||
hidden = true, |
||||
paramLabel = MANDATORY_FILE_FORMAT_HELP, |
||||
description = |
||||
"File containing password to unlock keystore for PKI Integration. Required if PKI Block Creation is enabled.") |
||||
Path keyStorePasswordFile = null; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-keystore-certificate-alias"}, |
||||
hidden = true, |
||||
paramLabel = "<NAME>", |
||||
description = |
||||
"Alias of the certificate that will be included in the blocks proposed by this validator.") |
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) |
||||
String certificateAlias = PkiKeyStoreConfiguration.DEFAULT_CERTIFICATE_ALIAS; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-truststore-type"}, |
||||
hidden = true, |
||||
paramLabel = "<NAME>", |
||||
description = "PKI Integration truststore type.") |
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) |
||||
String trustStoreType = PkiKeyStoreConfiguration.DEFAULT_KEYSTORE_TYPE; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-truststore-file"}, |
||||
hidden = true, |
||||
paramLabel = MANDATORY_FILE_FORMAT_HELP, |
||||
description = "Truststore containing trusted certificates for PKI Block Creation.") |
||||
Path trustStoreFile = null; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-truststore-password-file"}, |
||||
hidden = true, |
||||
paramLabel = MANDATORY_FILE_FORMAT_HELP, |
||||
description = "File containing password to unlock truststore for PKI Block Creation.") |
||||
Path trustStorePasswordFile = null; |
||||
|
||||
@Option( |
||||
names = {"--Xpki-block-creation-crl-file"}, |
||||
hidden = true, |
||||
paramLabel = MANDATORY_FILE_FORMAT_HELP, |
||||
description = "File with all CRLs for PKI Block Creation.") |
||||
Path crlFile = null; |
||||
|
||||
public Optional<PkiKeyStoreConfiguration> asDomainConfig(final CommandLine commandLine) { |
||||
if (!enabled) { |
||||
return Optional.empty(); |
||||
} |
||||
|
||||
if (keyStoreFile == null) { |
||||
throw new ParameterException( |
||||
commandLine, "KeyStore file is required when PKI Block Creation is enabled"); |
||||
} |
||||
|
||||
if (keyStorePasswordFile == null) { |
||||
throw new ParameterException( |
||||
commandLine, |
||||
"File containing password to unlock keystore is required when PKI Block Creation is enabled"); |
||||
} |
||||
|
||||
return Optional.of( |
||||
new PkiKeyStoreConfiguration.Builder() |
||||
.withKeyStoreType(keyStoreType) |
||||
.withKeyStorePath(keyStoreFile) |
||||
.withKeyStorePasswordSupplier(new FileBasedPasswordProvider(keyStorePasswordFile)) |
||||
.withCertificateAlias(certificateAlias) |
||||
.withTrustStoreType(trustStoreType) |
||||
.withTrustStorePath(trustStoreFile) |
||||
.withTrustStorePasswordSupplier( |
||||
null == trustStorePasswordFile |
||||
? null |
||||
: new FileBasedPasswordProvider(trustStorePasswordFile)) |
||||
.withCrlFilePath(crlFile) |
||||
.build()); |
||||
} |
||||
|
||||
public void checkPkiBlockCreationOptionsDependencies( |
||||
final Logger logger, final CommandLine commandLine) { |
||||
CommandLineUtils.checkOptionDependencies( |
||||
logger, |
||||
commandLine, |
||||
"--Xpki-block-creation-enabled", |
||||
!enabled, |
||||
asList( |
||||
"--Xpki-block-creation-keystore-file", "--Xpki-block-creation-keystore-password-file")); |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* 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. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
package org.hyperledger.besu.consensus.qbft.pki; |
||||
|
||||
import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; |
||||
|
||||
public class PkiBlockCreationConfiguration { |
||||
|
||||
private final KeyStoreWrapper keyStore; |
||||
private final KeyStoreWrapper trustStore; |
||||
private final String certificateAlias; |
||||
|
||||
public PkiBlockCreationConfiguration( |
||||
final KeyStoreWrapper keyStore, |
||||
final KeyStoreWrapper trustStore, |
||||
final String certificateAlias) { |
||||
this.keyStore = keyStore; |
||||
this.trustStore = trustStore; |
||||
this.certificateAlias = certificateAlias; |
||||
} |
||||
|
||||
public KeyStoreWrapper getKeyStore() { |
||||
return keyStore; |
||||
} |
||||
|
||||
public KeyStoreWrapper getTrustStore() { |
||||
return trustStore; |
||||
} |
||||
|
||||
public String getCertificateAlias() { |
||||
return certificateAlias; |
||||
} |
||||
} |
@ -0,0 +1,91 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* 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. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
package org.hyperledger.besu.consensus.qbft.pki; |
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull; |
||||
|
||||
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; |
||||
import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; |
||||
import org.hyperledger.besu.pki.keystore.SoftwareKeyStoreWrapper; |
||||
|
||||
import java.nio.file.Path; |
||||
|
||||
import com.google.common.annotations.VisibleForTesting; |
||||
import org.apache.logging.log4j.LogManager; |
||||
import org.apache.logging.log4j.Logger; |
||||
|
||||
public class PkiBlockCreationConfigurationProvider { |
||||
|
||||
private static final Logger LOG = LogManager.getLogger(); |
||||
|
||||
private final KeyStoreWrapperProvider keyStoreWrapperProvider; |
||||
|
||||
public PkiBlockCreationConfigurationProvider() { |
||||
this(SoftwareKeyStoreWrapper::new); |
||||
} |
||||
|
||||
@VisibleForTesting |
||||
PkiBlockCreationConfigurationProvider(final KeyStoreWrapperProvider keyStoreWrapperProvider) { |
||||
this.keyStoreWrapperProvider = checkNotNull(keyStoreWrapperProvider); |
||||
} |
||||
|
||||
public PkiBlockCreationConfiguration load( |
||||
final PkiKeyStoreConfiguration pkiKeyStoreConfiguration) { |
||||
KeyStoreWrapper keyStore; |
||||
try { |
||||
keyStore = |
||||
keyStoreWrapperProvider.apply( |
||||
pkiKeyStoreConfiguration.getKeyStoreType(), |
||||
pkiKeyStoreConfiguration.getKeyStorePath(), |
||||
pkiKeyStoreConfiguration.getKeyStorePassword(), |
||||
null); |
||||
LOG.info("Loaded PKI Block Creation KeyStore {}", pkiKeyStoreConfiguration.getKeyStorePath()); |
||||
} catch (Exception e) { |
||||
final String message = "Error loading PKI Block Creation KeyStore"; |
||||
LOG.error(message, e); |
||||
throw new RuntimeException(message, e); |
||||
} |
||||
|
||||
KeyStoreWrapper trustStore; |
||||
try { |
||||
trustStore = |
||||
keyStoreWrapperProvider.apply( |
||||
pkiKeyStoreConfiguration.getTrustStoreType(), |
||||
pkiKeyStoreConfiguration.getTrustStorePath(), |
||||
pkiKeyStoreConfiguration.getTrustStorePassword(), |
||||
pkiKeyStoreConfiguration.getCrlFilePath().orElse(null)); |
||||
LOG.info( |
||||
"Loaded PKI Block Creation TrustStore {}", pkiKeyStoreConfiguration.getTrustStorePath()); |
||||
} catch (Exception e) { |
||||
final String message = "Error loading PKI Block Creation TrustStore"; |
||||
LOG.error(message, e); |
||||
throw new RuntimeException(message, e); |
||||
} |
||||
|
||||
return new PkiBlockCreationConfiguration( |
||||
keyStore, trustStore, pkiKeyStoreConfiguration.getCertificateAlias()); |
||||
} |
||||
|
||||
@FunctionalInterface |
||||
interface KeyStoreWrapperProvider { |
||||
|
||||
KeyStoreWrapper apply( |
||||
final String keyStoreType, |
||||
final Path keyStorePath, |
||||
final String keyStorePassword, |
||||
final Path crl); |
||||
} |
||||
} |
@ -0,0 +1,71 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* 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. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
package org.hyperledger.besu.consensus.qbft.pki; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.ArgumentMatchers.any; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.ArgumentMatchers.isNull; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfigurationProvider.KeyStoreWrapperProvider; |
||||
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration; |
||||
import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; |
||||
|
||||
import java.nio.file.Path; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class PkiBlockCreationConfigurationProviderTest { |
||||
|
||||
@Mock KeyStoreWrapperProvider keyStoreWrapperProvider; |
||||
@Mock KeyStoreWrapper keyStoreWrapper; |
||||
@Mock KeyStoreWrapper trustStoreWrapper; |
||||
|
||||
@Test |
||||
public void pkiBlockCreationConfigurationIsLoadedCorrectly() { |
||||
when(keyStoreWrapperProvider.apply(any(), eq(Path.of("/tmp/keystore")), eq("pwd"), isNull())) |
||||
.thenReturn(keyStoreWrapper); |
||||
when(keyStoreWrapperProvider.apply( |
||||
any(), eq(Path.of("/tmp/truststore")), eq("pwd"), eq(Path.of("/tmp/crl")))) |
||||
.thenReturn(trustStoreWrapper); |
||||
|
||||
final PkiKeyStoreConfiguration pkiKeyStoreConfiguration = |
||||
new PkiKeyStoreConfiguration.Builder() |
||||
.withKeyStorePath(Path.of("/tmp/keystore")) |
||||
.withKeyStorePasswordSupplier(() -> "pwd") |
||||
.withTrustStorePath(Path.of("/tmp/truststore")) |
||||
.withTrustStorePasswordSupplier(() -> "pwd") |
||||
.withCertificateAlias("anAlias") |
||||
.withCrlFilePath(Path.of("/tmp/crl")) |
||||
.build(); |
||||
|
||||
final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider = |
||||
new PkiBlockCreationConfigurationProvider(keyStoreWrapperProvider); |
||||
|
||||
final PkiBlockCreationConfiguration pkiBlockCreationConfiguration = |
||||
pkiBlockCreationConfigProvider.load(pkiKeyStoreConfiguration); |
||||
|
||||
assertThat(pkiBlockCreationConfiguration).isNotNull(); |
||||
assertThat(pkiBlockCreationConfiguration.getKeyStore()).isNotNull(); |
||||
assertThat(pkiBlockCreationConfiguration.getTrustStore()).isNotNull(); |
||||
assertThat(pkiBlockCreationConfiguration.getCertificateAlias()).isEqualTo("anAlias"); |
||||
} |
||||
} |
Loading…
Reference in new issue