From 5288737ab49ad2a35083badcd66bdaf9308ba377 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 27 Nov 2024 14:06:05 +1000 Subject: [PATCH 1/5] removed pki Signed-off-by: Sally MacFarlane --- pki/build.gradle | 49 --- .../hyperledger/besu/pki/PkiException.java | 54 ---- .../hyperledger/besu/pki/cms/CmsCreator.java | 142 -------- .../besu/pki/cms/CmsValidator.java | 203 ------------ .../pki/config/PkiKeyStoreConfiguration.java | 303 ------------------ .../org/hyperledger/besu/pki/crl/CRLUtil.java | 53 --- .../pki/keystore/AbstractKeyStoreWrapper.java | 68 ---- .../pki/keystore/HardwareKeyStoreWrapper.java | 210 ------------ .../besu/pki/keystore/KeyStoreWrapper.java | 88 ----- .../pki/keystore/SoftwareKeyStoreWrapper.java | 269 ---------------- .../besu/pki/util/TestCertificateUtils.java | 217 ------------- .../keystore/invalidpartner1client1/crl.pem | 27 -- .../keystore/invalidpartner1client1/keys.p12 | Bin 6250 -> 0 bytes .../invalidpartner1client1/keystore.jks | Bin 7159 -> 0 bytes .../keystore/invalidpartner1client1/nss.cfg | 6 - .../invalidpartner1client1/nssdb/cert8.db | Bin 65536 -> 0 bytes .../invalidpartner1client1/nssdb/key3.db | Bin 16384 -> 0 bytes .../invalidpartner1client1/nssdb/secmod.db | Bin 16384 -> 0 bytes .../invalidpartner1client1/nsspin.txt | 1 - .../invalidpartner1client1/ssl-ca.pem | 72 ----- .../keystore/invalidpartner1client1/ssl.pem | 129 -------- .../invalidpartner1client1/truststore.jks | Bin 3252 -> 0 bytes pki/src/test/resources/keystore/keystore | Bin 6773 -> 0 bytes .../keystore/partner1client1/crl.pem | 27 -- .../keystore/partner1client1/nssdb/cert8.db | Bin 65536 -> 0 bytes .../keystore/partner1client1/nssdb/key3.db | Bin 16384 -> 0 bytes .../keystore/partner1client1/nssdb/secmod.db | Bin 16384 -> 0 bytes .../keystore/partner1client1/nsspin.txt | 1 - .../keystore/partner1client1/ssl-ca.pem | 70 ---- .../keystore/partner1client1/ssl.pem | 126 -------- .../keystore/partner2client1/crl.pem | 27 -- .../keystore/partner2client1/keys.p12 | Bin 6068 -> 0 bytes .../keystore/partner2client1/keystore.jks | Bin 6817 -> 0 bytes .../keystore/partner2client1/nss.cfg | 6 - .../keystore/partner2client1/nssdb/cert8.db | Bin 65536 -> 0 bytes .../keystore/partner2client1/nssdb/key3.db | Bin 16384 -> 0 bytes .../keystore/partner2client1/nssdb/secmod.db | Bin 16384 -> 0 bytes .../keystore/partner2client1/nsspin.txt | 1 - .../keystore/partner2client1/ssl-ca.pem | 70 ---- .../keystore/partner2client1/ssl.pem | 126 -------- .../keystore/partner2client1/truststore.jks | Bin 3135 -> 0 bytes pki/src/test/resources/keystore/truststore | Bin 2378 -> 0 bytes .../org.mockito.plugins.MockMaker | 1 - 43 files changed, 2346 deletions(-) delete mode 100644 pki/build.gradle delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/PkiException.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/cms/CmsCreator.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/cms/CmsValidator.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/config/PkiKeyStoreConfiguration.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/crl/CRLUtil.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/keystore/AbstractKeyStoreWrapper.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/keystore/HardwareKeyStoreWrapper.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/keystore/KeyStoreWrapper.java delete mode 100644 pki/src/main/java/org/hyperledger/besu/pki/keystore/SoftwareKeyStoreWrapper.java delete mode 100644 pki/src/test/java/org/hyperledger/besu/pki/util/TestCertificateUtils.java delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/crl.pem delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/keys.p12 delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/keystore.jks delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/nss.cfg delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/nssdb/cert8.db delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/nssdb/key3.db delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/nssdb/secmod.db delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/nsspin.txt delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/ssl-ca.pem delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/ssl.pem delete mode 100644 pki/src/test/resources/keystore/invalidpartner1client1/truststore.jks delete mode 100644 pki/src/test/resources/keystore/keystore delete mode 100644 pki/src/test/resources/keystore/partner1client1/crl.pem delete mode 100644 pki/src/test/resources/keystore/partner1client1/nssdb/cert8.db delete mode 100644 pki/src/test/resources/keystore/partner1client1/nssdb/key3.db delete mode 100644 pki/src/test/resources/keystore/partner1client1/nssdb/secmod.db delete mode 100644 pki/src/test/resources/keystore/partner1client1/nsspin.txt delete mode 100644 pki/src/test/resources/keystore/partner1client1/ssl-ca.pem delete mode 100644 pki/src/test/resources/keystore/partner1client1/ssl.pem delete mode 100644 pki/src/test/resources/keystore/partner2client1/crl.pem delete mode 100644 pki/src/test/resources/keystore/partner2client1/keys.p12 delete mode 100644 pki/src/test/resources/keystore/partner2client1/keystore.jks delete mode 100644 pki/src/test/resources/keystore/partner2client1/nss.cfg delete mode 100644 pki/src/test/resources/keystore/partner2client1/nssdb/cert8.db delete mode 100644 pki/src/test/resources/keystore/partner2client1/nssdb/key3.db delete mode 100644 pki/src/test/resources/keystore/partner2client1/nssdb/secmod.db delete mode 100644 pki/src/test/resources/keystore/partner2client1/nsspin.txt delete mode 100644 pki/src/test/resources/keystore/partner2client1/ssl-ca.pem delete mode 100644 pki/src/test/resources/keystore/partner2client1/ssl.pem delete mode 100644 pki/src/test/resources/keystore/partner2client1/truststore.jks delete mode 100644 pki/src/test/resources/keystore/truststore delete mode 100644 pki/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/pki/build.gradle b/pki/build.gradle deleted file mode 100644 index 15f1e8c7d6f..00000000000 --- a/pki/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 - */ - -apply plugin: 'java-library' - -jar { - archiveBaseName = 'besu-pki' - manifest { - attributes( - 'Specification-Title': archiveBaseName, - 'Specification-Version': project.version, - 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion(), - 'Commit-Hash': getGitCommitDetails(40).hash - ) - } -} - -dependencies { - api 'org.slf4j:slf4j-api' - - implementation 'com.google.guava:guava' - implementation 'io.tmio:tuweni-bytes' - implementation 'org.bouncycastle:bcpkix-jdk18on' - - testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.mockito:mockito-core' - testImplementation 'org.mockito:mockito-junit-jupiter' -} - -configurations { testArtifacts } -tasks.register('testJar', Jar) { - archiveBaseName = "${project.name}-test" - from sourceSets.test.output -} - -artifacts { testArtifacts testJar } diff --git a/pki/src/main/java/org/hyperledger/besu/pki/PkiException.java b/pki/src/main/java/org/hyperledger/besu/pki/PkiException.java deleted file mode 100644 index 096684bbc48..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/PkiException.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.pki; - -/** The Pki exception. */ -public class PkiException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - /** Instantiates a new Pki exception. */ - public PkiException() { - super(); - } - - /** - * Instantiates a new Pki exception. - * - * @param message the message - */ - public PkiException(final String message) { - super(message); - } - - /** - * Instantiates a new Pki exception. - * - * @param message the message - * @param t the Throwable cause - */ - public PkiException(final String message, final Throwable t) { - super(message, t); - } - - /** - * Instantiates a new Pki exception. - * - * @param t the Throwable cause - */ - public PkiException(final Throwable t) { - super(t); - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/cms/CmsCreator.java b/pki/src/main/java/org/hyperledger/besu/pki/cms/CmsCreator.java deleted file mode 100644 index 088bf2eaed6..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/cms/CmsCreator.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.pki.cms; - -import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; - -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Security; -import java.security.cert.X509Certificate; -import java.security.interfaces.ECPublicKey; -import java.security.spec.EllipticCurve; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import com.google.common.annotations.VisibleForTesting; -import org.apache.tuweni.bytes.Bytes; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cms.CMSProcessableByteArray; -import org.bouncycastle.cms.CMSSignedData; -import org.bouncycastle.cms.CMSSignedDataGenerator; -import org.bouncycastle.cms.CMSTypedData; -import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.DigestCalculatorProvider; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; -import org.bouncycastle.util.Store; - -/** The Cms creator. */ -public class CmsCreator { - - static { - if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastleProvider()); - } - } - - private final String certificateAlias; - private final KeyStoreWrapper keyStore; - - /** - * Instantiates a new Cms creator. - * - * @param keyStore the key store - * @param certificateAlias the certificate alias - */ - public CmsCreator(final KeyStoreWrapper keyStore, final String certificateAlias) { - this.keyStore = keyStore; - this.certificateAlias = certificateAlias; - } - - /** - * Creates a CMS message with the content parameter, signed with the certificate with alias - * defined in the {@code CmsCreator} constructor. The certificate chain is also included so the - * recipient has the information needed to build a trusted certificate path when validating this - * message. - * - * @param contentToSign the content that will be signed and added to the message - * @return the CMS message bytes - */ - @SuppressWarnings("rawtypes") - public Bytes create(final Bytes contentToSign) { - try { - // Certificates that will be sent - final List x509Certificates = - Stream.of(keyStore.getCertificateChain(certificateAlias)) - .map(X509Certificate.class::cast) - .collect(Collectors.toList()); - final Store certs = new JcaCertStore(x509Certificates); - - // Private key of the certificate that will sign the message - final PrivateKey privateKey = keyStore.getPrivateKey(certificateAlias); - - final ContentSigner contentSigner = - new JcaContentSignerBuilder( - getPreferredSignatureAlgorithm(keyStore.getPublicKey(certificateAlias))) - .build(privateKey); - - final CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator(); - - // Additional intermediate certificates for path building - cmsGenerator.addCertificates(certs); - - final DigestCalculatorProvider digestCalculatorProvider = - new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(); - // The first certificate in the list (leaf certificate is the signer) - cmsGenerator.addSignerInfoGenerator( - new JcaSignerInfoGeneratorBuilder(digestCalculatorProvider) - .build(contentSigner, x509Certificates.get(0))); - - // Add signed content - final CMSTypedData cmsData = new CMSProcessableByteArray(contentToSign.toArray()); - final CMSSignedData cmsSignedData = cmsGenerator.generate(cmsData, false); - - return Bytes.wrap(cmsSignedData.getEncoded()); - } catch (final Exception e) { - throw new RuntimeException("Error creating CMS data", e); - } - } - - /** - * Gets preferred signature algorithm for EC or RSA keys - * - * @param pub the public key - * @return the preferred signature algorithm - */ - @VisibleForTesting - public static String getPreferredSignatureAlgorithm(final PublicKey pub) { - switch (pub.getAlgorithm()) { - case "EC" -> { - final EllipticCurve curve = ((ECPublicKey) pub).getParams().getCurve(); - return switch (curve.getField().getFieldSize()) { - case 224, 256 -> "SHA256withECDSA"; - case 384 -> "SHA384withECDSA"; - case 521 -> "SHA512withECDSA"; - default -> throw new IllegalArgumentException("Elliptic curve not supported: " + curve); - }; - } - case "RSA" -> { - return "SHA256WithRSAEncryption"; - } - default -> - throw new UnsupportedOperationException( - "Private key algorithm not supported: " + pub.getAlgorithm()); - } - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/cms/CmsValidator.java b/pki/src/main/java/org/hyperledger/besu/pki/cms/CmsValidator.java deleted file mode 100644 index c32c11d01a3..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/cms/CmsValidator.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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.pki.cms; - -import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; - -import java.security.Security; -import java.security.cert.CertPathBuilder; -import java.security.cert.CertPathBuilderException; -import java.security.cert.CertStore; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.PKIXRevocationChecker; -import java.security.cert.PKIXRevocationChecker.Option; -import java.security.cert.X509CertSelector; -import java.security.cert.X509Certificate; -import java.util.Collection; -import java.util.EnumSet; -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSProcessableByteArray; -import org.bouncycastle.cms.CMSSignedData; -import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.Store; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** The Cms validator. */ -public class CmsValidator { - - static { - if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastleProvider()); - } - } - - private static final Logger LOGGER = LoggerFactory.getLogger(CmsValidator.class); - - private final KeyStoreWrapper truststore; - - /** - * Instantiates a new Cms validator. - * - * @param truststore the truststore - */ - public CmsValidator(final KeyStoreWrapper truststore) { - this.truststore = truststore; - } - - /** - * Verifies that a CMS message signed content matched the expected content, and that the message - * signer is from a certificate that is trusted (has permission to propose a block) - * - * @param cms the CMS message bytes - * @param expectedContent the expected signed content in the CMS message - * @return true, if the signed content matched the expected content and the signer's certificate - * is trusted, otherwise returns false. - */ - public boolean validate(final Bytes cms, final Bytes expectedContent) { - if (cms == null || cms.isEmpty()) { - return false; - } - - try { - LOGGER.trace("Validating CMS message"); - - final CMSSignedData cmsSignedData = - new CMSSignedData(new CMSProcessableByteArray(expectedContent.toArray()), cms.toArray()); - final X509Certificate signerCertificate = getSignerCertificate(cmsSignedData); - - // Validate msg signature and content - if (!isSignatureValid(signerCertificate, cmsSignedData)) { - return false; - } - - // Validate certificate trust - if (!isCertificateTrusted(signerCertificate, cmsSignedData)) { - return false; - } - - return true; - } catch (final Exception e) { - throw new RuntimeException("Error validating CMS data", e); - } - } - - @SuppressWarnings("unchecked") - private X509Certificate getSignerCertificate(final CMSSignedData cmsSignedData) { - try { - final Store certificateStore = cmsSignedData.getCertificates(); - - // We don't expect more than one signer on the CMS data - if (cmsSignedData.getSignerInfos().size() != 1) { - throw new RuntimeException("Only one signer is expected on the CMS message"); - } - final SignerInformation signerInformation = - cmsSignedData.getSignerInfos().getSigners().stream().findFirst().get(); - - // Find signer's certificate from CMS data - final Collection signerCertificates = - certificateStore.getMatches(signerInformation.getSID()); - final X509CertificateHolder certificateHolder = signerCertificates.stream().findFirst().get(); - - return new JcaX509CertificateConverter().getCertificate(certificateHolder); - } catch (final Exception e) { - throw new RuntimeException("Error retrieving signer certificate from CMS data", e); - } - } - - private boolean isSignatureValid( - final X509Certificate signerCertificate, final CMSSignedData cmsSignedData) { - LOGGER.trace("Validating CMS signature"); - try { - return cmsSignedData.verifySignatures( - sid -> new JcaSimpleSignerInfoVerifierBuilder().build(signerCertificate)); - } catch (final CMSException e) { - return false; - } - } - - private boolean isCertificateTrusted( - final X509Certificate signerCertificate, final CMSSignedData cmsSignedData) { - LOGGER.trace("Starting CMS certificate validation"); - - try { - final CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX"); - - // Define CMS signer certificate as the starting point of the path (leaf certificate) - final X509CertSelector targetConstraints = new X509CertSelector(); - targetConstraints.setCertificate(signerCertificate); - - // Set parameters for the certificate path building algorithm - final PKIXBuilderParameters params = - new PKIXBuilderParameters(truststore.getKeyStore(), targetConstraints); - - // Adding CertStore with CRLs (if present, otherwise disabling revocation check) - createCRLCertStore(truststore) - .ifPresentOrElse( - CRLs -> { - params.addCertStore(CRLs); - PKIXRevocationChecker rc = (PKIXRevocationChecker) cpb.getRevocationChecker(); - rc.setOptions(EnumSet.of(Option.PREFER_CRLS)); - params.addCertPathChecker(rc); - }, - () -> { - LOGGER.warn("No CRL CertStore provided. CRL validation will be disabled."); - params.setRevocationEnabled(false); - }); - - // Read certificates sent on the CMS message and adding it to the path building algorithm - final CertStore cmsCertificates = - new JcaCertStoreBuilder().addCertificates(cmsSignedData.getCertificates()).build(); - params.addCertStore(cmsCertificates); - - // Validate certificate path - try { - cpb.build(params); - return true; - } catch (final CertPathBuilderException cpbe) { - LOGGER.warn("Untrusted certificate chain", cpbe); - LOGGER.trace("Reason for failed validation", cpbe.getCause()); - return false; - } - - } catch (final Exception e) { - LOGGER.error("Error validating certificate chain"); - throw new RuntimeException("Error validating certificate chain", e); - } - } - - private Optional createCRLCertStore(final KeyStoreWrapper truststore) { - if (truststore.getCRLs() != null) { - try { - return Optional.of( - CertStore.getInstance( - "Collection", new CollectionCertStoreParameters(truststore.getCRLs()))); - } catch (final Exception e) { - throw new RuntimeException("Error loading CRLs from Truststore", e); - } - } else { - return Optional.empty(); - } - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/config/PkiKeyStoreConfiguration.java b/pki/src/main/java/org/hyperledger/besu/pki/config/PkiKeyStoreConfiguration.java deleted file mode 100644 index 83ce80f0e4d..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/config/PkiKeyStoreConfiguration.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * 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.pki.config; - -import static java.util.Objects.requireNonNull; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Optional; -import java.util.stream.Stream; - -import com.google.common.annotations.VisibleForTesting; - -/** The Pki key store configuration. */ -public class PkiKeyStoreConfiguration { - - /** The constant DEFAULT_KEYSTORE_TYPE. */ - public static String DEFAULT_KEYSTORE_TYPE = "PKCS12"; - - /** The constant DEFAULT_CERTIFICATE_ALIAS. */ - public static String DEFAULT_CERTIFICATE_ALIAS = "validator"; - - private final String keyStoreType; - private final Path keyStorePath; - private final Path keyStorePasswordPath; - private final String certificateAlias; - private final String trustStoreType; - private final Path trustStorePath; - private final Path trustStorePasswordPath; - private final Optional crlFilePath; - - /** - * Instantiates a new Pki key store configuration. - * - * @param keyStoreType the key store type - * @param keyStorePath the key store path - * @param keyStorePasswordPath the key store password path - * @param certificateAlias the certificate alias - * @param trustStoreType the trust store type - * @param trustStorePath the trust store path - * @param trustStorePasswordPath the trust store password path - * @param crlFilePath the crl file path - */ - public PkiKeyStoreConfiguration( - final String keyStoreType, - final Path keyStorePath, - final Path keyStorePasswordPath, - final String certificateAlias, - final String trustStoreType, - final Path trustStorePath, - final Path trustStorePasswordPath, - final Optional crlFilePath) { - this.keyStoreType = keyStoreType; - this.keyStorePath = keyStorePath; - this.keyStorePasswordPath = keyStorePasswordPath; - this.certificateAlias = certificateAlias; - this.trustStoreType = trustStoreType; - this.trustStorePath = trustStorePath; - this.trustStorePasswordPath = trustStorePasswordPath; - this.crlFilePath = crlFilePath; - } - - /** - * Gets key store type. - * - * @return the key store type - */ - public String getKeyStoreType() { - return keyStoreType; - } - - /** - * Gets key store path. - * - * @return the key store path - */ - public Path getKeyStorePath() { - return keyStorePath; - } - - /** - * Gets key store password path. - * - * @return the key store password path - */ - @VisibleForTesting - public Path getKeyStorePasswordPath() { - return keyStorePasswordPath; - } - - /** - * Gets key store password. - * - * @return the key store password - */ - public String getKeyStorePassword() { - return readPasswordFromFile(keyStorePasswordPath); - } - - /** - * Gets certificate alias. - * - * @return the certificate alias - */ - public String getCertificateAlias() { - return certificateAlias; - } - - /** - * Gets trust store type. - * - * @return the trust store type - */ - public String getTrustStoreType() { - return trustStoreType; - } - - /** - * Gets trust store path. - * - * @return the trust store path - */ - public Path getTrustStorePath() { - return trustStorePath; - } - - /** - * Gets trust store password path. - * - * @return the trust store password path - */ - @VisibleForTesting - public Path getTrustStorePasswordPath() { - return trustStorePasswordPath; - } - - /** - * Gets trust store password. - * - * @return the trust store password - */ - public String getTrustStorePassword() { - return readPasswordFromFile(trustStorePasswordPath); - } - - /** - * Gets CRL file path. - * - * @return the crl file path - */ - public Optional getCrlFilePath() { - return crlFilePath; - } - - /** The Builder. */ - public static final class Builder { - - private String keyStoreType = DEFAULT_KEYSTORE_TYPE; - private Path keyStorePath; - private Path keyStorePasswordPath; - private String certificateAlias = DEFAULT_CERTIFICATE_ALIAS; - private String trustStoreType = DEFAULT_KEYSTORE_TYPE; - private Path trustStorePath; - private Path trustStorePasswordPath; - private Path crlFilePath; - - /** Instantiates a new Builder. */ - public Builder() {} - - /** - * With key store type. - * - * @param keyStoreType the key store type - * @return the builder - */ - public Builder withKeyStoreType(final String keyStoreType) { - this.keyStoreType = keyStoreType; - return this; - } - - /** - * With key store path. - * - * @param keyStorePath the key store path - * @return the builder - */ - public Builder withKeyStorePath(final Path keyStorePath) { - this.keyStorePath = keyStorePath; - return this; - } - - /** - * With key store password path. - * - * @param keyStorePasswordPath the key store password path - * @return the builder - */ - public Builder withKeyStorePasswordPath(final Path keyStorePasswordPath) { - this.keyStorePasswordPath = keyStorePasswordPath; - return this; - } - - /** - * With certificate alias. - * - * @param certificateAlias the certificate alias - * @return the builder - */ - public Builder withCertificateAlias(final String certificateAlias) { - this.certificateAlias = certificateAlias; - return this; - } - - /** - * With trust store type. - * - * @param trustStoreType the trust store type - * @return the builder - */ - public Builder withTrustStoreType(final String trustStoreType) { - this.trustStoreType = trustStoreType; - return this; - } - - /** - * With trust store path. - * - * @param trustStorePath the trust store path - * @return the builder - */ - public Builder withTrustStorePath(final Path trustStorePath) { - this.trustStorePath = trustStorePath; - return this; - } - - /** - * With trust store password path. - * - * @param trustStorePasswordPath the trust store password path - * @return the builder - */ - public Builder withTrustStorePasswordPath(final Path trustStorePasswordPath) { - this.trustStorePasswordPath = trustStorePasswordPath; - return this; - } - - /** - * With crl file path. - * - * @param filePath the file path - * @return the builder - */ - public Builder withCrlFilePath(final Path filePath) { - this.crlFilePath = filePath; - return this; - } - - /** - * Build pki key store configuration. - * - * @return the pki key store configuration - */ - public PkiKeyStoreConfiguration build() { - requireNonNull(keyStoreType, "Key Store Type must not be null"); - requireNonNull(keyStorePasswordPath, "Key Store password file must not be null"); - - return new PkiKeyStoreConfiguration( - keyStoreType, - keyStorePath, - keyStorePasswordPath, - certificateAlias, - trustStoreType, - trustStorePath, - trustStorePasswordPath, - Optional.ofNullable(crlFilePath)); - } - } - - private String readPasswordFromFile(final Path passwordFile) { - try (final Stream fileStream = Files.lines(passwordFile)) { - return fileStream.findFirst().orElseThrow(() -> errorReadingFileException(passwordFile)); - } catch (final IOException e) { - throw errorReadingFileException(passwordFile); - } - } - - private RuntimeException errorReadingFileException(final Path path) { - return new RuntimeException(String.format("Unable to read keystore password from %s", path)); - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/crl/CRLUtil.java b/pki/src/main/java/org/hyperledger/besu/pki/crl/CRLUtil.java deleted file mode 100644 index 17d3ecea765..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/crl/CRLUtil.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.pki.crl; - -import org.hyperledger.besu.pki.PkiException; - -import java.io.FileInputStream; -import java.nio.file.Paths; -import java.security.cert.CertStore; -import java.security.cert.CertificateFactory; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.X509CRL; -import java.util.List; -import java.util.stream.Collectors; - -/** The CRL util. */ -public class CRLUtil { - /** Default constructor */ - private CRLUtil() {} - - /** - * Load CRLs cert store. - * - * @param path the path - * @return the cert store - */ - public static CertStore loadCRLs(final String path) { - try { - final List crls = - CertificateFactory.getInstance("X509") - .generateCRLs(new FileInputStream(Paths.get(path).toFile())) - .stream() - .map(X509CRL.class::cast) - .collect(Collectors.toList()); - - return CertStore.getInstance("Collection", new CollectionCertStoreParameters(crls)); - } catch (Exception e) { - throw new PkiException("Error loading CRL file " + path, e); - } - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/keystore/AbstractKeyStoreWrapper.java b/pki/src/main/java/org/hyperledger/besu/pki/keystore/AbstractKeyStoreWrapper.java deleted file mode 100644 index 54cc1631016..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/keystore/AbstractKeyStoreWrapper.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.pki.keystore; - -import org.hyperledger.besu.pki.PkiException; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.nio.file.Path; -import java.security.cert.CertificateFactory; -import java.security.cert.X509CRL; -import java.util.Collection; -import java.util.stream.Collectors; - -/** The Abstract key store wrapper. */ -public abstract class AbstractKeyStoreWrapper implements KeyStoreWrapper { - - private static final String X_509 = "X.509"; - - private final Collection crls; - - /** - * Instantiates a new Abstract key store wrapper. - * - * @param crlLocation the crl location - */ - protected AbstractKeyStoreWrapper(final Path crlLocation) { - super(); - if (null == crlLocation) { - this.crls = null; - } else { - try (InputStream stream = new FileInputStream(crlLocation.toFile())) { - this.crls = - CertificateFactory.getInstance(X_509).generateCRLs(stream).stream() - .map(X509CRL.class::cast) - .collect(Collectors.toList()); - } catch (final Exception e) { - throw new PkiException("Failed to initialize software truststore", e); - } - } - } - - /** - * Instantiates a new Abstract key store wrapper. - * - * @param crls the collection of X509CRL instances - */ - protected AbstractKeyStoreWrapper(final Collection crls) { - this.crls = crls; - } - - @Override - public Collection getCRLs() { - return crls; - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/keystore/HardwareKeyStoreWrapper.java b/pki/src/main/java/org/hyperledger/besu/pki/keystore/HardwareKeyStoreWrapper.java deleted file mode 100644 index 74217f272b2..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/keystore/HardwareKeyStoreWrapper.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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.pki.keystore; - -import org.hyperledger.besu.pki.PkiException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.nio.file.Path; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.PublicKey; -import java.security.Security; -import java.security.cert.Certificate; -import java.security.cert.X509CRL; -import java.util.Collection; -import java.util.Optional; -import java.util.Properties; -import java.util.stream.Stream; - -import com.google.common.annotations.VisibleForTesting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Creates an instance of this class which is backed by a PKCS#11 keystore, such as a software - * (emulated) HSM or a physical/cloud HSM (see here - */ -public class HardwareKeyStoreWrapper extends AbstractKeyStoreWrapper { - - private static final Logger LOG = LoggerFactory.getLogger(HardwareKeyStoreWrapper.class); - - private static final String pkcs11Provider = "SunPKCS11"; - - private final KeyStore keystore; - private final transient char[] keystorePassword; - - private final java.security.Provider provider; - - /** - * Instantiates a new Hardware key store wrapper. - * - * @param keystorePassword the keystore password - * @param provider the provider - * @param crlLocation the crl location - */ - public HardwareKeyStoreWrapper( - final String keystorePassword, final Provider provider, final Path crlLocation) { - super(crlLocation); - try { - if (provider == null) { - throw new IllegalArgumentException("Provider is null"); - } - this.keystorePassword = keystorePassword.toCharArray(); - - this.provider = provider; - if (Security.getProvider(provider.getName()) == null) { - Security.addProvider(provider); - } - - keystore = KeyStore.getInstance(KeyStoreWrapper.KEYSTORE_TYPE_PKCS11, provider); - keystore.load(null, this.keystorePassword); - - } catch (final Exception e) { - throw new PkiException("Failed to initialize HSM keystore", e); - } - } - - /** - * Instantiates a new Hardware key store wrapper. - * - * @param keystorePassword the keystore password - * @param config the config - * @param crlLocation the CRL location - */ - public HardwareKeyStoreWrapper( - final String keystorePassword, final Path config, final Path crlLocation) { - super(crlLocation); - try { - if (keystorePassword == null) { - throw new IllegalArgumentException("Keystore password is null"); - } - final Properties properties = new Properties(); - final File configFile = config.toFile(); - try (InputStream ins = new FileInputStream(configFile)) { - properties.load(ins); - } - final String name = properties.getProperty("name"); - this.keystorePassword = keystorePassword.toCharArray(); - final Optional existingProvider = - Stream.of(Security.getProviders()) - .filter(p -> p.getName().equals(String.format("%s-%s", pkcs11Provider, name))) - .findAny(); - if (existingProvider.isPresent()) { - provider = existingProvider.get(); - } else { - provider = getPkcs11Provider(configFile.getAbsolutePath()); - Security.addProvider(provider); - } - - keystore = KeyStore.getInstance(KeyStoreWrapper.KEYSTORE_TYPE_PKCS11, provider); - keystore.load(null, this.keystorePassword); - - } catch (final Exception e) { - throw new PkiException("Failed to initialize HSM keystore", e); - } - } - - /** - * Instantiates a new Hardware key store wrapper. - * - * @param crls the collection of X509CRL crls - * @param keystore the keystore - * @param password the password - */ - @VisibleForTesting - HardwareKeyStoreWrapper( - final Collection crls, final KeyStore keystore, final String password) { - super(crls); - this.keystore = keystore; - this.keystorePassword = password.toCharArray(); - this.provider = null; - } - - @Override - public PrivateKey getPrivateKey(final String keyAlias) { - try { - LOG.debug("Retrieving private key for alias: {}", keyAlias); - return (PrivateKey) keystore.getKey(keyAlias, this.keystorePassword); - } catch (final Exception e) { - throw new PkiException("Failed to get key: " + keyAlias, e); - } - } - - @Override - public PublicKey getPublicKey(final String keyAlias) { - try { - LOG.debug("Retrieving public key for alias: {}", keyAlias); - final Certificate certificate = keystore.getCertificate(keyAlias); - return (certificate != null) ? certificate.getPublicKey() : null; - } catch (final Exception e) { - throw new PkiException("Failed to get key: " + keyAlias, e); - } - } - - @Override - public Certificate getCertificate(final String certificateAlias) { - try { - LOG.debug("Retrieving certificate for alias: {}", certificateAlias); - return keystore.getCertificate(certificateAlias); - } catch (final Exception e) { - throw new PkiException("Failed to get certificate: " + certificateAlias, e); - } - } - - @Override - public Certificate[] getCertificateChain(final String certificateAlias) { - try { - LOG.debug("Retrieving certificate chain for alias: {}", certificateAlias); - return keystore.getCertificateChain(certificateAlias); - } catch (final Exception e) { - throw new PkiException("Failed to certificate chain for alias: " + certificateAlias, e); - } - } - - @Override - public KeyStore getKeyStore() { - return keystore; - } - - @Override - public KeyStore getTrustStore() { - return keystore; - } - - private Provider getPkcs11Provider(final String config) { - final Provider provider = Security.getProvider(pkcs11Provider); - if (null == provider) { - throw new IllegalArgumentException("Unable to load PKCS11 provider configuration."); - } else { - return provider.configure(config); - } - } - - /** - * Gets PKCS11 provider. - * - * @param config the config - * @return the PKCS11 provider - */ - @VisibleForTesting - public Provider getPkcs11ProviderForConfig(final String config) { - return getPkcs11Provider(config); - } -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/keystore/KeyStoreWrapper.java b/pki/src/main/java/org/hyperledger/besu/pki/keystore/KeyStoreWrapper.java deleted file mode 100644 index d9a5f199fc8..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/keystore/KeyStoreWrapper.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.pki.keystore; - -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.Certificate; -import java.security.cert.X509CRL; -import java.util.Collection; - -/** The interface Key store wrapper. */ -public interface KeyStoreWrapper { - - /** The constant KEYSTORE_TYPE_JKS. */ - String KEYSTORE_TYPE_JKS = "JKS"; - - /** The constant KEYSTORE_TYPE_PKCS11. */ - String KEYSTORE_TYPE_PKCS11 = "PKCS11"; - - /** The constant KEYSTORE_TYPE_PKCS12. */ - String KEYSTORE_TYPE_PKCS12 = "PKCS12"; - - /** - * Gets key store. - * - * @return the key store - */ - KeyStore getKeyStore(); - - /** - * Gets trust store. - * - * @return the trust store - */ - KeyStore getTrustStore(); - - /** - * Gets private key. - * - * @param keyAlias the key alias - * @return the private key - */ - PrivateKey getPrivateKey(String keyAlias); - - /** - * Gets public key. - * - * @param keyAlias the key alias - * @return the public key - */ - PublicKey getPublicKey(String keyAlias); - - /** - * Gets certificate. - * - * @param certificateAlias the certificate alias - * @return the certificate - */ - Certificate getCertificate(String certificateAlias); - - /** - * Get certificate chain array. - * - * @param certificateAlias the certificate alias - * @return the certificate [ ] - */ - Certificate[] getCertificateChain(String certificateAlias); - - /** - * Gets CRLs. - * - * @return the CRLs - */ - Collection getCRLs(); -} diff --git a/pki/src/main/java/org/hyperledger/besu/pki/keystore/SoftwareKeyStoreWrapper.java b/pki/src/main/java/org/hyperledger/besu/pki/keystore/SoftwareKeyStoreWrapper.java deleted file mode 100644 index d3d892dfc43..00000000000 --- a/pki/src/main/java/org/hyperledger/besu/pki/keystore/SoftwareKeyStoreWrapper.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * 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.pki.keystore; - -import org.hyperledger.besu.pki.PkiException; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.Certificate; -import java.security.cert.X509CRL; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import com.google.common.annotations.VisibleForTesting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** The Software key store wrapper. */ -public class SoftwareKeyStoreWrapper extends AbstractKeyStoreWrapper { - - private static final Logger LOG = LoggerFactory.getLogger(SoftwareKeyStoreWrapper.class); - - private final KeyStore keystore; - private final transient char[] keystorePassword; - private KeyStore truststore; - private transient char[] truststorePassword; - - private final Map cachedPrivateKeys = new HashMap<>(); - private final Map cachedPublicKeys = new HashMap<>(); - private final Map cachedCertificates = new HashMap<>(); - - /** - * Instantiates a new Software key store wrapper. - * - * @param keystoreType the keystore type - * @param keystoreLocation the keystore location - * @param keystorePassword the keystore password - * @param crlLocation the crl location - */ - public SoftwareKeyStoreWrapper( - final String keystoreType, - final Path keystoreLocation, - final String keystorePassword, - final Path crlLocation) { - this(keystoreType, keystoreLocation, keystorePassword, null, null, null, crlLocation); - } - - /** - * Instantiates a new Software key store wrapper. - * - * @param keystoreType the keystore type - * @param keystoreLocation the keystore location - * @param keystorePassword the keystore password - * @param truststoreType the truststore type - * @param truststoreLocation the truststore location - * @param truststorePassword the truststore password - * @param crlLocation the crl location - */ - public SoftwareKeyStoreWrapper( - final String keystoreType, - final Path keystoreLocation, - final String keystorePassword, - final String truststoreType, - final Path truststoreLocation, - final String truststorePassword, - final Path crlLocation) { - super(crlLocation); - - if (keystorePassword == null) { - throw new IllegalArgumentException("Keystore password is null"); - } - this.keystorePassword = keystorePassword.toCharArray(); - try (InputStream stream = new FileInputStream(keystoreLocation.toFile())) { - keystore = KeyStore.getInstance(keystoreType); - keystore.load(stream, this.keystorePassword); - - } catch (final Exception e) { - throw new PkiException("Failed to initialize software keystore: " + keystoreLocation, e); - } - - if (truststoreType != null && truststoreLocation != null) { - this.truststorePassword = - (truststorePassword != null) ? truststorePassword.toCharArray() : null; - try (InputStream stream = new FileInputStream(truststoreLocation.toFile())) { - truststore = KeyStore.getInstance(truststoreType); - truststore.load(stream, this.truststorePassword); - - } catch (final Exception e) { - throw new PkiException( - "Failed to initialize software truststore: " + truststoreLocation, e); - } - } - } - - /** - * Instantiates a new Software key store wrapper. - * - * @param keystore the keystore - * @param keystorePassword the keystore password - * @param truststore the truststore - * @param truststorePassword the truststore password - */ - @VisibleForTesting - public SoftwareKeyStoreWrapper( - final KeyStore keystore, - final String keystorePassword, - final KeyStore truststore, - final String truststorePassword) { - super((Path) null); - this.keystore = keystore; - this.keystorePassword = keystorePassword.toCharArray(); - this.truststore = truststore; - this.truststorePassword = truststorePassword.toCharArray(); - } - - /** - * Instantiates a new Software key store wrapper. - * - * @param crls the collection of X509CRL crls - * @param keystore the keystore - * @param keystorePassword the keystore password - */ - @VisibleForTesting - public SoftwareKeyStoreWrapper( - final Collection crls, final KeyStore keystore, final String keystorePassword) { - super(crls); - this.keystore = keystore; - this.keystorePassword = keystorePassword.toCharArray(); - this.truststore = null; - this.truststorePassword = null; - } - - @Override - public PrivateKey getPrivateKey(final String keyAlias) { - LOG.debug("Retrieving private key for alias: {}", keyAlias); - return (PrivateKey) getKey(keyAlias, PrivateKey.class, cachedPrivateKeys); - } - - @Override - public PublicKey getPublicKey(final String keyAlias) { - LOG.debug("Retrieving public key for alias: {}", keyAlias); - return (PublicKey) getKey(keyAlias, PublicKey.class, cachedPublicKeys); - } - - @Override - public Certificate getCertificate(final String certificateAlias) { - try { - LOG.debug("Retrieving certificate for alias: {}", certificateAlias); - Certificate certificate = cachedCertificates.get(certificateAlias); - if (certificate == null) { - LOG.debug("Certificate alias: {} not cached", certificateAlias); - - certificate = keystore.getCertificate(certificateAlias); - if (certificate == null && truststore != null) { - certificate = truststore.getCertificate(certificateAlias); - } - if (certificate != null) { - LOG.debug("Certificate alias: {} found in keystore/truststore", certificateAlias); - cachedCertificates.put(certificateAlias, certificate); - cachedPublicKeys.put(certificateAlias, certificate.getPublicKey()); - return certificate; - } else { - LOG.warn("Certificate alias: {} not found in keystore/truststore", certificateAlias); - } - } - return certificate; - - } catch (final Exception e) { - throw new PkiException("Failed to get certificate: " + certificateAlias, e); - } - } - - @Override - public Certificate[] getCertificateChain(final String certificateAlias) { - try { - LOG.debug("Retrieving certificate chain for alias: {}", certificateAlias); - - Certificate[] certificateChain = keystore.getCertificateChain(certificateAlias); - if (certificateChain == null && truststore != null) { - certificateChain = truststore.getCertificateChain(certificateAlias); - } - return certificateChain; - } catch (final Exception e) { - throw new PkiException( - "Failed to retrieve certificate chain for alias: " + certificateAlias, e); - } - } - - private Key getKey( - final String keyAlias, - final Class keyTypeClass, - final Map keyCache) { - Key cachedKey = keyCache.get(keyAlias); - if (cachedKey == null) { - LOG.debug("Key alias: {} not cached", keyAlias); - try { - cachedKey = loadAndCacheKey(this.keystore, this.keystorePassword, keyAlias, keyTypeClass); - if (cachedKey == null) { - cachedKey = - loadAndCacheKey(this.truststore, this.truststorePassword, keyAlias, keyTypeClass); - } - } catch (final Exception e) { - throw new PkiException("Failed to get key: " + keyAlias, e); - } - } - return cachedKey; - } - - @Override - public KeyStore getKeyStore() { - return keystore; - } - - @Override - public KeyStore getTrustStore() { - return truststore; - } - - private Key loadAndCacheKey( - final KeyStore keystore, - final char[] keystorePassword, - final String keyAlias, - final Class keyTypeClass) - throws GeneralSecurityException { - if (keystore != null && keystore.containsAlias(keyAlias)) { - - final Key key = keystore.getKey(keyAlias, keystorePassword); - if (key != null) { - LOG.debug("Key alias: {} found in keystore/truststore", keyAlias); - if (key instanceof PrivateKey && PrivateKey.class.isAssignableFrom(keyTypeClass)) { - cachedPrivateKeys.put(keyAlias, (PrivateKey) key); - return key; - } else if (key instanceof PublicKey && PublicKey.class.isAssignableFrom(keyTypeClass)) { - cachedPublicKeys.put(keyAlias, (PublicKey) key); - return key; - } - } - - if (PublicKey.class.isAssignableFrom(keyTypeClass)) { - final Certificate certificate = getCertificate(keyAlias); - if (certificate != null) { - return certificate.getPublicKey(); - } - } - } - - LOG.warn("Key alias: {} not found in keystore/truststore", keyAlias); - return null; - } -} diff --git a/pki/src/test/java/org/hyperledger/besu/pki/util/TestCertificateUtils.java b/pki/src/test/java/org/hyperledger/besu/pki/util/TestCertificateUtils.java deleted file mode 100644 index e9502e30e66..00000000000 --- a/pki/src/test/java/org/hyperledger/besu/pki/util/TestCertificateUtils.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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.pki.util; - -import org.hyperledger.besu.pki.cms.CmsCreator; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.Security; -import java.security.cert.CRLException; -import java.security.cert.CRLReason; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.security.spec.ECGenParameterSpec; -import java.sql.Date; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Collection; -import java.util.Random; - -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.cert.X509CRLHolder; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.X509v2CRLBuilder; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CRLConverter; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.jce.X509KeyUsage; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; - -/* - This class provides utility method for creating certificates used on tests. - - Based on https://stackoverflow.com/a/18648284/5021783 -*/ -public class TestCertificateUtils { - - static { - if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { - Security.addProvider(new BouncyCastleProvider()); - } - } - - public enum Algorithm { - RSA, - EC - } - - public static KeyPair createKeyPair(final Algorithm algorithm) { - try { - @SuppressWarnings("InsecureCryptoUsage") - final KeyPairGenerator kpg = KeyPairGenerator.getInstance(algorithm.name()); - if (algorithm == Algorithm.EC) { - kpg.initialize(new ECGenParameterSpec("secp256r1")); - } - return kpg.generateKeyPair(); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Error creating KeyPair", e); - } catch (InvalidAlgorithmParameterException e) { - throw new RuntimeException(e); - } - } - - public static X509Certificate createSelfSignedCertificate( - final String name, final Instant notBefore, final Instant notAfter, final KeyPair keyPair) { - try { - final String signatureAlgorithm = - CmsCreator.getPreferredSignatureAlgorithm(keyPair.getPublic()); - final ContentSigner signer = - new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate()); - - final X509v3CertificateBuilder certificateBuilder = - new JcaX509v3CertificateBuilder( - new X500Name("CN=" + name), - new BigInteger(32, new Random()), - Date.from(notBefore), - Date.from(notAfter), - new X500Name("CN=" + name), - keyPair.getPublic()) - .addExtension( - Extension.authorityKeyIdentifier, - false, - new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(keyPair.getPublic())) - .addExtension( - Extension.subjectKeyIdentifier, - false, - new JcaX509ExtensionUtils().createSubjectKeyIdentifier(keyPair.getPublic())) - .addExtension( - Extension.basicConstraints, - false, - new BasicConstraints(true)) // true if it is allowed to sign other certs - .addExtension( - Extension.keyUsage, - true, - new X509KeyUsage(X509KeyUsage.keyCertSign | X509KeyUsage.cRLSign)); - - final X509CertificateHolder certHolder = certificateBuilder.build(signer); - - return new JcaX509CertificateConverter() - .setProvider(BouncyCastleProvider.PROVIDER_NAME) - .getCertificate(certHolder); - - } catch (final Exception e) { - throw new RuntimeException("Error creating CA certificate", e); - } - } - - public static X509Certificate issueCertificate( - final X509Certificate issuer, - final KeyPair issuerKeyPair, - final String subject, - final Instant notBefore, - final Instant notAfter, - final KeyPair keyPair, - final boolean isCa) { - - try { - final String signatureAlgorithm = - CmsCreator.getPreferredSignatureAlgorithm(keyPair.getPublic()); - final ContentSigner signer = - new JcaContentSignerBuilder(signatureAlgorithm).build(issuerKeyPair.getPrivate()); - - final X509v3CertificateBuilder certificateBuilder = - new JcaX509v3CertificateBuilder( - issuer, - new BigInteger(32, new Random()), - Date.from(notBefore), - Date.from(notAfter), - new X500Name("CN=" + subject), - keyPair.getPublic()) - .addExtension( - Extension.authorityKeyIdentifier, - false, - new JcaX509ExtensionUtils() - .createAuthorityKeyIdentifier(issuerKeyPair.getPublic())) - .addExtension( - Extension.basicConstraints, - false, - new BasicConstraints(isCa)) // true if it is allowed to sign other certs - .addExtension( - Extension.keyUsage, - true, - new X509KeyUsage( - X509KeyUsage.digitalSignature - | X509KeyUsage.nonRepudiation - | X509KeyUsage.keyEncipherment - | X509KeyUsage.dataEncipherment - | X509KeyUsage.cRLSign - | X509KeyUsage.keyCertSign)); - - final X509CertificateHolder certHolder = certificateBuilder.build(signer); - - return new JcaX509CertificateConverter() - .setProvider(BouncyCastleProvider.PROVIDER_NAME) - .getCertificate(certHolder); - } catch (final Exception e) { - throw new RuntimeException("Error creating certificate", e); - } - } - - public static X509CRL createCRL( - final X509Certificate issuer, - final KeyPair issuerKeyPair, - final Collection revokedCertificates) { - try { - final X509CertificateHolder x509CertificateHolder = - new X509CertificateHolder(issuer.getEncoded()); - - final X509v2CRLBuilder crlBuilder = - new X509v2CRLBuilder(x509CertificateHolder.getSubject(), Date.from(Instant.now())); - - revokedCertificates.forEach( - c -> - crlBuilder.addCRLEntry( - c.getSerialNumber(), Date.from(Instant.now()), CRLReason.UNSPECIFIED.ordinal())); - - crlBuilder.setNextUpdate(Date.from(Instant.now().plus(1, ChronoUnit.DAYS))); - final String signatureAlgorithm = - CmsCreator.getPreferredSignatureAlgorithm(issuerKeyPair.getPublic()); - final ContentSigner signer = - new JcaContentSignerBuilder(signatureAlgorithm).build(issuerKeyPair.getPrivate()); - final X509CRLHolder crlHolder = crlBuilder.build(signer); - return new JcaX509CRLConverter() - .setProvider(BouncyCastleProvider.PROVIDER_NAME) - .getCRL(crlHolder); - } catch (OperatorCreationException - | CRLException - | CertificateEncodingException - | IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/pki/src/test/resources/keystore/invalidpartner1client1/crl.pem b/pki/src/test/resources/keystore/invalidpartner1client1/crl.pem deleted file mode 100644 index 659388f6525..00000000000 --- a/pki/src/test/resources/keystore/invalidpartner1client1/crl.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCVVMxCzAJBgNV -BAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJBgNVBAoMAk1DMQ0wCwYDVQQLDARyb290 -MRMwEQYDVQQDDApwYXJ0bmVyMWNhMSYwJAYJKoZIhvcNAQkBFhdwYXJ0bmVyMWNh -QHBhcnRuZXIxLmNvbRcNMjEwNjA3MTcwNjAwWhcNMjIwNjA3MTcwNjAwWjAnMCUC -FGltgEkvXupxY562dERH8+uKOf89Fw0yMTA2MDcxNzA2MDBaoA4wDDAKBgNVHRQE -AwIBADANBgkqhkiG9w0BAQsFAAOCAQEABF/7Kq+byYi/bRoftL8xqgSGcaLVuCOF -BZVZXDKjyYfISwBqbvPSqtIvnFO1ewicgD7dNIZwWcQ9Kx7OOz4BA6Pe8YPtiBfp -HZMabT8BS2eLePvViGumY7PTo3oIk3yXylOtzMDo59WQhCH/0vp5xjzJC+VFex/W -p/an5ii1y3Q1FpEZNer6jpU0xJEJ2mCaGT/zuj6Mg1awWqmmYce3BahZeCNj8Wyx -GIy8bGUjOdJyp99rAF9euCZ45pAjI12sg9lhPIVkp3Wnoy3La4Yj219Elc3MbJvF -8GEFEmZ0Lm5Ze/EG5VyLB+wRpggeSJTc20i/eGWdaWg8AEukCgMdCg== ------END X509 CRL----- ------BEGIN X509 CRL----- -MIICLDCCARQCAQEwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9v -dDETMBEGA1UEAwwKcGFydG5lcjJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcjJj -YUBwYXJ0bmVyMi5jb20XDTIxMDYwNzE3MDYwMFoXDTIyMDYwNzE3MDYwMFowTjAl -AhRpbYBJL17qcWOetnRER/Prijn/PRcNMjEwNjA3MTcwNjAwWjAlAhR+2Aa1zeVQ -jbXFGnXFu53h4vZEahcNMjEwNjA3MTcwNjAwWqAOMAwwCgYDVR0UBAMCAQEwDQYJ -KoZIhvcNAQELBQADggEBAFXQOMk+6FDP8bm9TGK079IHojhooipo+9x3I1y/kUhH -XY7xuyTXOvzv14//xenDuryIjSAC8pyqbls+DcUXkmGZ/nIWugtMykGLNgqqo/Oe -pfoUSXRJP7CtvfHa4ejfr3q1t5MXfM3nqBQumu65slWjDFtE6mZF4ANcsIlsNQ10 -GTkDIdDHgUWxmZlBzTkoofvYspixuUptpJfl5eei9SDA+T1uADKnjARkxVv8xeYi -QwTp6jVYq6YKc9z0l1UMadnFQz8osk7QNypWnsrD0+iBB1if8ikJwy+8BWayTkgQ -tWLFT4n/c1m/wYzSclvZUUOxkkkE4Q9fZ3ReCADC+bQ= ------END X509 CRL----- diff --git a/pki/src/test/resources/keystore/invalidpartner1client1/keys.p12 b/pki/src/test/resources/keystore/invalidpartner1client1/keys.p12 deleted file mode 100644 index 54531db7bbc747fdb49980923fb456d8176bdd6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6250 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 UHgqGLf8>+z+RG3S;X`u&1MWDG@c;k- diff --git a/pki/src/test/resources/keystore/invalidpartner1client1/nss.cfg b/pki/src/test/resources/keystore/invalidpartner1client1/nss.cfg deleted file mode 100644 index 08aba6591b4..00000000000 --- a/pki/src/test/resources/keystore/invalidpartner1client1/nss.cfg +++ /dev/null @@ -1,6 +0,0 @@ - -name = NSScrypto-invalidpartner1client1 -nssSecmodDirectory = ./src/test/resources/keystore/invalidpartner1client1/nssdb -nssDbMode = readOnly -nssModule = keystore - diff --git a/pki/src/test/resources/keystore/invalidpartner1client1/nssdb/cert8.db b/pki/src/test/resources/keystore/invalidpartner1client1/nssdb/cert8.db deleted file mode 100644 index b4acd9ef5962eaed2377f3fe120bbb7a4e56070a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 zcmeI*dpJ~kzX0&HX2vua5nIH#m0K#&MG{Reuj?pm-LM;%A;zVYs3>Ar zdX*$nJ5+L~Hj*f}bQN`WNf&l!2KAP_XYX@P&-=`Np6_@(vu3R|Gi!b3_x*j>{PFz` zLYzfM5Cn%Hgk}UW;VdG;2!e9%xc>-ga)Gmbd}d0;z6(-X4r#DpeoTBl4@UtXLyLC_gHx zHvMiUQ&wxb1^DBptebpAg!>C_Cfq;18Hf}X!H35p@B_#2I24DIm?75J?E0|qW>HP= zDOFPUhTfDpiI~vm13(4&5R94n>5TqgXD)+DPn@~v)Z?U6bujJE@5wo7#c%eQ?tHO% zQbO8P>_<$Gs)y<7YCB1bXj3^Wbg4R%EB*!_8Ww^6@Fh6Phu|Yn5rnf|02hIx$kDU$ z{cYNL5q4(=<`?{6lQ1i(pOuRA+E!~nPQItIRCjUm@dxw;G-mH9C9RSQ$v4_Nwwa*S z2?b)|JFx3BUf$QRVH*=kt-4yWA7z9(7biXXZF!hiLm^wMD=)ZwPpBJGYAk;P&baDIdm0Hh_m8Lm$lUdjv^>&~0 z9p}~dJ&Qj{jxze0Nbycs6I!(E{SYhjz|u2Xdg^VlHP0Vr##_49nmRu?KwH&X@snxP zsYfp~%8!TFD#f&!l?%&n9@9pgwz3j(-NOPlJK`O)e$$lu7>NJzh6b&xtUH8X^fnHU zBIxl5RG%ZFi-{8XH?gcx)>|_aB@pm9V#RnoQG^MS1PM`-&b0+g<4GB{J`HYpttVrP zo)(UWEJd7v!w^iEGyW(dDEg86Oun9pXDSjTF$p4R0TJcnn}J6^FX1p|6?cDm0<#Qb zUfwOCUeTNv$jl+6#1FiU*mo*nb3@^YEG9dLxd&sizDtBiVY4P8M0j%idozMP0^R6T zWlZtQ@R0s`vkBeZ-%Z1Wu&H#vCq3+;L!(luYgBX#Jm z+nsHCiLoD&3+5~=+_Tatk~G#?6LmV~f<;(`d+eplx%`pMdBb=EX1`=0rC_1jy{M$e znmMF`NV34GtE~65k{g!R)>qE&U7vYb<7&mPX_U14jFGJt-3q-UGjn_2nuT`y`EQt+ z8Ctn-TU=Q_#Ud2dpV zwVLx~cvcxPqFc)YBr9a4nx327LMy8pBIl=?l*NzMFIQ|SWIi|~F!(UV?p$MH%A1Q` zb>zQ26Y`{4_7YOp6+n? zh0{Y?qlhYwVLp*#JTdn#lF9lt&wf1Kx4kFkVi)0(R=mZ14V*V7H<1yfG0EK$rQvs8 z2bHK+yz7@Wm*LCZkr3*;4HM(;AkIxOB#g+p!=dQcX$NIZ8Pwy`abk#WNz33%L%O(( z&yj*<`$RJ%2TrXQ%wJL8_BKVOVw9F2R(-g1uZlkLV7KtWyX8;V)IO^oJ>yO(IoDL2 z!=}^q;?Lto(-sA)H?UWzzgEABZ$Dz`FLmpH%bT3#e`_p~^k=C=u5!)U2sw-v1nWNlTdt9|3vWul}by6()8eYe&TOcwln z`6sbz=PIeSnufkEzu9fQz}8*%M`?qQaZDX29>uM zquQQZ_PtSM>?Q}>43!S+TzvCb_!qONy{yQ1$8BXp%?te{d2%cxIX1L#5#5o(|N?cT+y>z zr6SUGxb+wQI{$(EflOn)`wK6mDcgj22AHyYuH3mzx^yy=X6CiauV+(XOi-8HELzja z$_?V3?g}~cwG)fODj2J4kFuj>4(!|>&swrN{wXG7^{TMs==yohs-<{&iZ5qV+D=T!;Z$E11dy#I;;+x1A4%n(MGRCwC z;ZHM$$mfi~hv7LHW6CHVPY+4&?=sIu?AJ0n&H8nCWm9x`uVupu+mWZ_0t@-drw(2R zEi;=vx&*JtuWhYtQj+Vi)p}JS!Y&gZS(2}pqFbD^yu;^-;!2B`)lbtq<77-$?QPwB zlO<3}s5#-A<@;KrQHdnybW26$PMH!*!qY}@yQs2$6@f3qdh?k!;y*M*6Q3)Q-#$Ke z($~!CgW`aZ`E`a_ViuMuFBm2{pfGH#{o>~SNI4g?eqsPFdT`*Snb7RQ2dT7ouiczj z&8(*}UH-HTb;>I%p`zat9A*9>mxy)iiuaJuxI9#IS?A%8cMr~fuvSM!(;{l77ptg- z7&kO;59z%mF8g%WtLI*u$KE7*MAnyPMB7qDWyBXi6p|mGP z_C{t#MTUnANrsHYu?BR5a{c-G&vYzwEEdWvWN4dcGqk@~*8zAP5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI-V`7aIekjFhxRvUdqJEm>6y~~WV$vV$V9EB)aP2uDbGQWd<6Mh)$McY zFBkkT&Yx3}$@9HuKG$jzq!BSrWxoWcR&#W+R`W0Pq~MvF)4x*H&#Ucl{;X!R5<6x} zo6}z=lD+kiXhAn_gRjSosP!%h*L+fwFZ=KZo2k_t7p-pEpHjN_9Akm5`(XneEL732 zY_>$m#XN#>WVmf*OJLlg+3~E#LxO#{fG{W7`C4I~d}${X+}KUOA70^qV&i%X|IXs< zU5A^R229`le3IyCyG!q<8%>mo2W1PfEA8YGGJDHo_wzF91%}=u%vWpwkz#ShP4}1R z?aK&#V}0wS-feMcOPlNZhjYLF=hj~cBR`dGt`$5hkDpgtXGgeTu{GA$P(!5oB_+sN_I|jMjcg6XcSG8LkHe`}ZY~D?r!en zjRfHrEW|*C{qCjMPMY_gt`IEfj(1Hx{o>URJ?rGd1yQZB)jsw$ow@lsbx~)Z#f^0g z?9a2HTybDix*RoD7?L#$`LVu!v>_{I)xLA*);pQkG$xn$l!Uo!ulUfycQYolv8_e< zJsQ$xf@4_gXvL|2NLI**Zd;{c@;EW}_M#{?&$@jr9oB7DtBiIB$E`mY-C&t~*IC;3 zdQG{jysN{h)ZVfdi|%B~O2z-mTQoRz&Z8sfv~vTmwA0}x)bxpj%A+y=O&X>D4;fVK z+YCxakPOb+>6!-d%7?&7mP+3YoN3RJlP7ufW8w~^Jre_oM_R&s8aR_3H@@iqz-=nT zI~}b)H4*yM8H6jDFd@l9?GlLprbp1^rK`Z_z;ojS9H&DF&ljG1of9X_c!-`m zToZWeh&~Nj&SyRL-Fi^M3xNO#fB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?x OfB*=900{hF1^yeQx<1hW diff --git a/pki/src/test/resources/keystore/invalidpartner1client1/nssdb/key3.db b/pki/src/test/resources/keystore/invalidpartner1client1/nssdb/key3.db deleted file mode 100644 index 6ee017228cf19b723d9ac04fee9f7f104810e489..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/pki/src/test/resources/keystore/partner1client1/nssdb/key3.db b/pki/src/test/resources/keystore/partner1client1/nssdb/key3.db deleted file mode 100644 index cd4773dc310efe27d1d30da2946fbcee4ba0e53c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI$XHe5y769;nNPs}V&_Y?75b{68_wyec@E`fd5ro*SbI9>i-}7$l-q~G$dLaKj&!65G zGz0=b00;m9AOHk_01yBIKmZ5;0U+>K5kNv4=ymiwx(;25&O_(zN#mpNrSa{600KY& z2mk>f00e*l5ctCd;E+(LM>vJ-6RzP!3h*IQG$3^<;;XtM4@x=JGIdQ5Ccq7Yt4kro zAni?MW=aw1S@vf_==gR~y6Jf$7Yv4=B04`tv&(vU=jndaB5%+0u(D*g4Y^qitW^7C z-BUY-6>i`8*&S=yl!qzFPm5JwFV^82PD}Hu!U}p$h@(CyTJj_ulgHSe2V`K3w znxq@~rX0Qa+;}k!Kbldt=1A^Z`p93DIl=jw3wIjUN*$_ZaT-iwk@&=NHGOS2@9m@q zP<)B`ZMZgmpbiCts_JQ1wC(#*XE9yRjk)fBA*fu`vyrPg|4Amjqf$9mX`k}kR;fi; z)D5rTc7f{Z(IK=geQHuilv92{uj+|FS|+Vwu2T71z9L)t3H-f;&sDRIDVV!{*Ka;P zF^a0u?9Qkh^BV(_!3~AOFQOk<#b~+O*~uqHzWLewn!)wI-@~6ipD*buB$WNCS5j`} zkvzfOC8{#3f-%X>h3dn4Tgmvv^3d2?Iu#2M>Vaj38}|&7PeMUXMI(BStuEYBPSM5A zjz0~b`F45a&CC}siYZfQWT|bV=0is`FDEHKd+IP1Guxw@%iAC1yD(tvVyS|m^s49! z;9+ZN!HM>7?+V0C7w3$nDVHQTACc{Rwja5DN+`0$*|fVgPWHBq=~RrtPe)F4U)B2f z&S-h`*F(cAQI+btxHU9}&SeiBBV}YG1vTmKl?(>%q9;Y^H;k^|A0pc6idvh{>S}Y- zVznM5HZlBFS`U~{U@8}Tb0p?EFA%0jyu{9w3YWXyCCj^;+KlI%T*3=$A`qS;x3itI zd9vZn;inf23*t;4;~Iwv^3XR z_t|xOO>-Vyq0cIKcj0s-KNvE&1d(6eGiNdy_QatMy@;gx=dd9N(>x6pqCo>?>xkoC^0N=m+RHPLd`TI7QNwV2TP>}U3_ip zN<~(vVJemvw*>g;Z2p9kId^dId<*-*Aq`@ppBU#tE$xsnLGR?d?yXh6Q%ruMRHxR9 zNfD_Np)!(u4kfjRtwZ*;6y0hGuWE{FJKDkupebyy3dyaWtFuxsZ`FkKqqDg>=H(1% zc~37_nMFIa9i`m5sraoTzO#>i++CV+aBomXg@D}MUp|%erQZ2iThJjR;=gFg8YBqu z|DKa7+$1mahLu8NQ)tJjf2+dz5~iGA1}@(SZDUp>Q;}ygh>d0e*JV(R=_TJBf^wkq zs|eH2@wvan{7&PX*=(os8x3=#Ju>kcc7;b!ItQL9?9U4AuJ!cxz8E(9)$a0;i<-Ilxc_FbT zH;dY;-W)eA5+7I_e;mp@m=sXU#J5I1_MSK{k}7d3EDjHUyNs_esb|@S+G3Ox z@b63DO&(&GptWoB_ju|cw#0nBl8f)hpU*gwYLqx>=|%;pvW}P|IKz|Np2Cga_?xe5 zZKdp-qqjN-ZDO1|>y0#CXA_oi_)1Zgl1lscD<-USeq(Ba8w;B2J=o@LX-^Ac^0sM4 z7TORy&WYFlVt;QTDTx3xR1qM1|FV$AvnJ@QM|lmC<3bfUQgU>HjpnSjv|D#doFCUc z6)O+%N>)F#JkHw~y%)OOtf={RI`UI_UOT7r&i?K9etWe0Hj)GOXCC+vY&;V-cDPyB zR6Nz9;YJ{5{=(5a!NQ9q{uFXj`>!g>Y!_FPTX=%BE%y~skxgt+AoZ(QM2{$SIes+n zxwe9S9J@iG=E>l}CIXWvoy;ss_9KOOdXVrD9wZ7}48~A?WF5blT-b|+$)7uoH*bRY z3DAGP6mgk5!>L%DvC)MIUd@?Nw@{CWh^UZoZ@ibkk5>@f$tOG_AcXu^`KJJL0s$ZZ z1b_e#00KY&2mk>f00e*l5C8)IyTJAz{;v%h00AHX1b_e#00KY&2mk>f00e*l5C8)I HZ-IXS8Vq?z diff --git a/pki/src/test/resources/keystore/partner1client1/nssdb/secmod.db b/pki/src/test/resources/keystore/partner1client1/nssdb/secmod.db deleted file mode 100644 index 0f6316142fbb445fa7194a1e3e45006a81152ac2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 N5I_I{1Q7V|0w0(%Q4atB diff --git a/pki/src/test/resources/keystore/partner2client1/nsspin.txt b/pki/src/test/resources/keystore/partner2client1/nsspin.txt deleted file mode 100644 index 5271a526801..00000000000 --- a/pki/src/test/resources/keystore/partner2client1/nsspin.txt +++ /dev/null @@ -1 +0,0 @@ -test123 diff --git a/pki/src/test/resources/keystore/partner2client1/ssl-ca.pem b/pki/src/test/resources/keystore/partner2client1/ssl-ca.pem deleted file mode 100644 index 3df5f10dc16..00000000000 --- a/pki/src/test/resources/keystore/partner2client1/ssl-ca.pem +++ /dev/null @@ -1,70 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIUNniG6StciHezbAqX+uNMciPW7jswDQYJKoZIhvcNAQEL -BQAweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRAwDgYDVQQDDAdpbnRlcmNhMSAwHgYJ -KoZIhvcNAQkBFhFpbnRlcmNhQGFkbWluLmNvbTAgFw0yMTA2MDcxNzA1NDlaGA8y -MTIxMDUxNDE3MDU0OVowgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoG -A1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwK -cGFydG5lcjJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcjJjYUBwYXJ0bmVyMi5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLvHvIuFFYmNYEA6P2 -/RB3LBDpxbnjl7SU4KCWcfBxQ1guw3aG/HzjenKt3m6UmmESFSh0k4/a/s9m4z/M -ubVqrm0ll2HvyodetFL40jLgSCIbP3taCIhLptaOCB2P6keYEfjGdb5YTNMgCqYk -NYA+dgXtw1VMJvI7aRpmVOIPtQx/nqncigYzxykGlTbeusSPAGp7CAmxTZSJUFLI -ig0ReaKSopiQE2j/ljJXFK26sMlkq3Lw41E4fPju+PBeubeb6eT8fzhn0IaCgTeO -cZgKzVUv3MsrrKfDHXUhGAspKBGDkqkrogZ6UYcvyCLfnRM0vVGc1L7oaFnMMZ1m -NYRpAgMBAAGjZjBkMB0GA1UdDgQWBBSsXIVGVfgo124o7djQsYtrkYPWYzAfBgNV -HSMEGDAWgBT8BlnPk8BS8+JHlIEoCp3sO8jDDjASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABSHI1SgQ1FBWmPRZ -nXDspyvbvPsjk/p6erUVGGuDyy/F2rJldz7musNCL5ijAmlQfYPNMNoLU1BR+fAl -WSYfdjL1mMygXtj/KlaNqM5hQMUfyYa4Yk1ODaScl+wfIsSmzTSl/j4fMf58GYpr -9rssVveQrFAipeWhxgGqQNJooAbqmZKE4tePhKzrsH+B2hDEUnFptkasnQEkQQEZ -rSzJlU72U8p3Gwq9t9rKYoBLSr0yoBbh4fdFcPsuN/mZS6TNEu1Uc4ui9eWheGTM -RCNGehiXAczfIhf9WfMfyNhp5/pZc2nTeV/LsSjuCFXUdoL5rAESPcHBc56vXtcV -1ywC0A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID6jCCAtKgAwIBAgIUTwPfI+2FxYq0V6uukemLf67qANowDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNjA3MTcwNTQ3 -WhgPMjEyMTA1MTQxNzA1NDdaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEQMA4GA1UE -AwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBhZG1pbi5jb20wggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxuUWq2F6MFQLeFVBB800pjiJv -pqrpMb8lv5aEOX87slRRkIVe0M/6mSlNvJSSclGindIhsWxaYD4Kend+o+ODhMqT -Jl7zvVTTluGg8SK22kyJ8DTWHnhnFhpoKVLc5qjgvglOf0h7S9F/tL5AkpGoBq7t -PkbOJPxKR7bvn34Iux3HgS1uzwZqHSYBcNHuYB6PSgyQJiNLIrA/019YqqUI5R+W -V/Nb/kkrnsUS+hU6ntAtewus0irO+4fJzBlpN+bvbEBdVHeVmIYhF6ILxtCGWX5l -lOlDrYNXiff0ksKtEvyUV/NFOASixEBMQ88Un7NGHR8y1NW3fCGiVkOhvaprAgMB -AAGjZjBkMB0GA1UdDgQWBBT8BlnPk8BS8+JHlIEoCp3sO8jDDjAfBgNVHSMEGDAW -gBTj0UDC6u67VvpJ2NmXE7vz77nHHTASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud -DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAZYQg0VUOQ1DGoU0y0TsTzAZ4 -IEy5xavV7Nma9AJI0ZVFpqGEBjTXjxi7r/co1EREN3bi7QnZfJhU4SGVZ0T7wq+p -/S3x16DEPEufa3JmP+brBPOOP/5EJX5+2BXMUWuDcY7MAokaAIAudjmVk32FoZgy -54FkZ+YRillU++7k0ie8EEYE8pN2ABIqNCdHxGEhwEc0wVwB6bBONmcEssYmipUh -DQH6+sfKBcd+sUMGG3qd79sE7BF9w8bAHhKcBm5eTdEks9jh6H1o0PgBvFP8fFzF -q89KGuLw7T0n/Khkmrv5cifwmTpg42Ivorv8qk02aeiOAGiMyFFJ38BQtH64LQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2zCCAsOgAwIBAgIURc832yfuirkVrhWhC4O1uBfTZXAwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNjA3MTcwNTQ3 -WhgPMjEyMTA1MTQxNzA1NDdaMHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEVMBMGA1UE -AwwMcm9vdGNhLmFkbWluMR8wHQYJKoZIhvcNAQkBFhByb290Y2FAYWRtaW4uY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzKd0JrZR3N0A3C7Gp7sT -zLurt0pVjAIBh3N+5NsyY7eAHJWA7wRR+JpG4q6MxmYVWsk4MjsnWB0ViCCm+fTY -a9tFms6lmsjM4fJgIs8/DP+zBEOien7sD3kfddmI4ClODynNv3ODbJKyhzKQEOZ8 -sdf61yWYuFzayEfNoon6BlqroPv9B0eAsgOFDndPo6vbqAFlrYAyVXx+7hmH7Hv6 -8RWDaSr0uI62uhvAQeK4a+p9aTSwLcHRh1/7NezW9rzI0/7yzP3w/RS7tevDuacU -XMr3sH5xEUahGF72qYUVejUlP48fPLrdGK76QZk0M8K2EOyvuNq66P+UMialx+83 -NwIDAQABo1MwUTAdBgNVHQ4EFgQU49FAwuruu1b6SdjZlxO78++5xx0wHwYDVR0j -BBgwFoAU49FAwuruu1b6SdjZlxO78++5xx0wDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAQEADfrsmYBaeV4/MTRVazsey/o0ZhBoLJ+3RFYC6+M2lYB1 -yT92tbAT3787aHTw/SdFvA11oT+lMDEmBWowzZ1bp/J7tqlqMcmwL4QyhZjp0gmK -eqDXy2Jui/fOTRzWQ1ka7mR6OTWxxVoIjKVvJ/AysqGCTFMXZXrMthtCuQDG+b85 -B3ALz6/j0ZFqgKzftCIuY0UnBtDEuKkAa0QkDMHLvcMAw7V/etpQPypCXqmwnc2e -vvL6cSvakEVE7rErhIeeL+1m2TBSWNrPVIvggLMv655meqkhGQn9uYyiGw6i/2V/ -ngBAs4gYDvk20Cyg0kxQONmzreAdFzArud+k7FofZw== ------END CERTIFICATE----- diff --git a/pki/src/test/resources/keystore/partner2client1/ssl.pem b/pki/src/test/resources/keystore/partner2client1/ssl.pem deleted file mode 100644 index 2b907374355..00000000000 --- a/pki/src/test/resources/keystore/partner2client1/ssl.pem +++ /dev/null @@ -1,126 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDGcHX9nWsO3oQy -9HlcTQAA9RxCpVqi5MmBG2HuTipppBdXphGyhQggpD1rL5I26vdq1FIuPBlFI1pg -Hd/hw7FOr5HuQ12GZpmmPW5KIbEzeY0MVJNXOw+iUuoaQNHLQSKtV5ZOmIJURIWE -0tjicDOewW/yR9MMStOQladn7WICwwfpgLQeX9EkZqko4iOK9K6ZKUeyRf9kI/86 -2M7/DAi0pxvaBGcW0F9XmBlqQu7Ma6q0fyR1qf2q3OZL3mSWuNV8S4hYyPqgKAce -s5w7zzRSNaeGX644RWU1XY8ze6Zik61aRLI2clHrI8wta8HDCdV1GvHvPj1Y7kqB -xDg0yBqpAgMBAAECggEBAJ2ipshSLcKBFylXNbUR4efgzpNOwaJW9o+eDfx9kYmb -9YMGBFb5AMzVS4kDIDaKDwOJKMNbsINQozFpafjxOL+WDunkD759cJ8ze5JeE2Md -suNRqD4KR9Ad56P1S/MXihGDW36R/i4sxJgP2oR+tzLs3R3s2oWQR2I6z+JqG4qu -tf4gDP6UIrJOirkn7TQD1VQi+8HMWx1BSER6yR86tKKTnwIlgVh0mowWXKXsB5aS -Y38Kfu+OG8FWAkCaVjFZdvg6xQcjI8MEmRqumPPf3OETrE/D6u4+qvpy1D7b8nsf -utYgv1mKYqkU0wvdDt6WTrPn/0fteLw6yMaoPmhim1ECgYEA9eFj889HojPzF7fx -67yWICah9vqd9OPYIPOtQ5rrgnTkiSxk1QyAG6i2Jl15sr8lGuVcVhTyXk/M75Ct -4gWanwbUI6khDKOM3kVN1nx/kvYFrzSuWkswB55OBEbDY/qhGu73ERNaIJdJVrY+ -p5wn1sbT5I1fqAuKwpj2A5B++x0CgYEAzps6ZujBOq896QoiR4MmLEI6rzqprIsL -LHCWnGtwn4SJhPwSUD3yDbyjA5rpodjWatLtX/MV7hWlWARj/ERSOLZlU2rCPNwO -gRgGnpGcSZYhVs7WSa675OEhjmhdUmqcl88pO+14+WLN9Bj8ECqkxyD+srUe5zxo -IisJYBK/e/0CgYADI+bH5VzP2IQBSIshbJ4qOPQWmGrOBt7qxNHwrBjX6LBGhDeh -dPBp6gSxhr4YJ1LM/iLowom55KEEaj+eRF4OK+MntXBDng8dg5sT4zEp6lR2QWD8 -rDsnzcDHUzQJodjO5EBpimq7QdNg9SDluRvVJWLtZ1TSa5tREu0JbJ4CjQKBgADK -kWexfoP2BdutoUH625uRyV3AcMPraGiMKdeBhdXmkQxEVuGdyx6IWWt7HWf0R6Xz -FtumN7BIvvBeW++sZ1A2Sp8OKp5HDXsrF2NmFV4myAvoEOQJWkjfH9zGw4y8QctH -DNZg63SxDy7fJZ/+OdFVbARNM0gZcCCpX4jRqZAVAoGBALz0ELUMj1s42+G6UAZ3 -toBHOBI7o/4R7hRoim21dmpmyz1XJrL17wIZO4vvftNxYI4n/0U0QMFopaakMrCi -E0/I9sU9R/4MyOK0VCPtkeuxznp3xkX8zoNeewK+9EGiEZFcOpsbyRSmwjLCyTKU -G8HIMfRI71A7qj+5Me3q62K2 ------END PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIEyDCCA7CgAwIBAgIUftgGtc3lUI21xRp1xbud4eL2RGkwDQYJKoZIhvcNAQEL -BQAwgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0ZPMQsw -CQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwKcGFydG5lcjJjYTEm -MCQGCSqGSIb3DQEJARYXcGFydG5lcjJjYUBwYXJ0bmVyMi5jb20wIBcNMjEwNjA3 -MTcwNTQ5WhgPMjEyMTA1MTQxNzA1NDlaMIGLMQswCQYDVQQGEwJVUzELMAkGA1UE -CAwCQ0ExDDAKBgNVBAcMA1NGTzELMAkGA1UECgwCTUMxDTALBgNVBAsMBHJvb3Qx -GDAWBgNVBAMMD3BhcnRuZXIyY2xpZW50MTErMCkGCSqGSIb3DQEJARYccGFydG5l -cjJjbGllbnQxQHBhcnRuZXIyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMZwdf2daw7ehDL0eVxNAAD1HEKlWqLkyYEbYe5OKmmkF1emEbKFCCCk -PWsvkjbq92rUUi48GUUjWmAd3+HDsU6vke5DXYZmmaY9bkohsTN5jQxUk1c7D6JS -6hpA0ctBIq1Xlk6YglREhYTS2OJwM57Bb/JH0wxK05CVp2ftYgLDB+mAtB5f0SRm -qSjiI4r0rpkpR7JF/2Qj/zrYzv8MCLSnG9oEZxbQX1eYGWpC7sxrqrR/JHWp/arc -5kveZJa41XxLiFjI+qAoBx6znDvPNFI1p4ZfrjhFZTVdjzN7pmKTrVpEsjZyUesj -zC1rwcMJ1XUa8e8+PVjuSoHEODTIGqkCAwEAAaOCASgwggEkMBEGCWCGSAGG+EIB -AQQEAwIGwDAdBgNVHQ4EFgQUojh+oPjTK6xgPMtbz+XEy4tl7iwwCQYDVR0TBAIw -ADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC -MIG1BgNVHSMEga0wgaqAFKxchUZV+CjXbijt2NCxi2uRg9ZjoXykejB4MQswCQYD -VQQGEwJVUzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NGTzELMAkGA1UECgwCTUMx -DTALBgNVBAsMBHJvb3QxEDAOBgNVBAMMB2ludGVyY2ExIDAeBgkqhkiG9w0BCQEW -EWludGVyY2FAYWRtaW4uY29tghQ2eIbpK1yId7NsCpf640xyI9buOzANBgkqhkiG -9w0BAQsFAAOCAQEAbhEisOmfG5/Ks7MHu9cl17R9ISIFbMVv4wBiztLt2tWv5o5P -ul9DG2s9tBuOzs3xB4v2aZg7H2kPnUPDaTe7z5Ulc5+IyHDGSdsBzBqONH3sElue -HyZo1cOXU6nBIineYGYc0Bs9QnLRA0dmaYWZyjqB5S5GCs9Z5mk/JWzA1d110uio -RzStTpbSFlYvBpLTPShLREfFp56SMHDEaHBIoVERzfULvQwZLDsIAyqE/W+WE0FF -Lxhz3jxvztoOE6Sr5cmOp7nuwo3ALlWOjFCHOZRs/1qDDnIgXFnPKsZohtvVK2TG -a+/zW8wRyAAo4FgBTfqICXpOtK+Yg479Aj2GbQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIUNniG6StciHezbAqX+uNMciPW7jswDQYJKoZIhvcNAQEL -BQAweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRAwDgYDVQQDDAdpbnRlcmNhMSAwHgYJ -KoZIhvcNAQkBFhFpbnRlcmNhQGFkbWluLmNvbTAgFw0yMTA2MDcxNzA1NDlaGA8y -MTIxMDUxNDE3MDU0OVowgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoG -A1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDETMBEGA1UEAwwK -cGFydG5lcjJjYTEmMCQGCSqGSIb3DQEJARYXcGFydG5lcjJjYUBwYXJ0bmVyMi5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLvHvIuFFYmNYEA6P2 -/RB3LBDpxbnjl7SU4KCWcfBxQ1guw3aG/HzjenKt3m6UmmESFSh0k4/a/s9m4z/M -ubVqrm0ll2HvyodetFL40jLgSCIbP3taCIhLptaOCB2P6keYEfjGdb5YTNMgCqYk -NYA+dgXtw1VMJvI7aRpmVOIPtQx/nqncigYzxykGlTbeusSPAGp7CAmxTZSJUFLI -ig0ReaKSopiQE2j/ljJXFK26sMlkq3Lw41E4fPju+PBeubeb6eT8fzhn0IaCgTeO -cZgKzVUv3MsrrKfDHXUhGAspKBGDkqkrogZ6UYcvyCLfnRM0vVGc1L7oaFnMMZ1m -NYRpAgMBAAGjZjBkMB0GA1UdDgQWBBSsXIVGVfgo124o7djQsYtrkYPWYzAfBgNV -HSMEGDAWgBT8BlnPk8BS8+JHlIEoCp3sO8jDDjASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABSHI1SgQ1FBWmPRZ -nXDspyvbvPsjk/p6erUVGGuDyy/F2rJldz7musNCL5ijAmlQfYPNMNoLU1BR+fAl -WSYfdjL1mMygXtj/KlaNqM5hQMUfyYa4Yk1ODaScl+wfIsSmzTSl/j4fMf58GYpr -9rssVveQrFAipeWhxgGqQNJooAbqmZKE4tePhKzrsH+B2hDEUnFptkasnQEkQQEZ -rSzJlU72U8p3Gwq9t9rKYoBLSr0yoBbh4fdFcPsuN/mZS6TNEu1Uc4ui9eWheGTM -RCNGehiXAczfIhf9WfMfyNhp5/pZc2nTeV/LsSjuCFXUdoL5rAESPcHBc56vXtcV -1ywC0A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID6jCCAtKgAwIBAgIUTwPfI+2FxYq0V6uukemLf67qANowDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNjA3MTcwNTQ3 -WhgPMjEyMTA1MTQxNzA1NDdaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEQMA4GA1UE -AwwHaW50ZXJjYTEgMB4GCSqGSIb3DQEJARYRaW50ZXJjYUBhZG1pbi5jb20wggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxuUWq2F6MFQLeFVBB800pjiJv -pqrpMb8lv5aEOX87slRRkIVe0M/6mSlNvJSSclGindIhsWxaYD4Kend+o+ODhMqT -Jl7zvVTTluGg8SK22kyJ8DTWHnhnFhpoKVLc5qjgvglOf0h7S9F/tL5AkpGoBq7t -PkbOJPxKR7bvn34Iux3HgS1uzwZqHSYBcNHuYB6PSgyQJiNLIrA/019YqqUI5R+W -V/Nb/kkrnsUS+hU6ntAtewus0irO+4fJzBlpN+bvbEBdVHeVmIYhF6ILxtCGWX5l -lOlDrYNXiff0ksKtEvyUV/NFOASixEBMQ88Un7NGHR8y1NW3fCGiVkOhvaprAgMB -AAGjZjBkMB0GA1UdDgQWBBT8BlnPk8BS8+JHlIEoCp3sO8jDDjAfBgNVHSMEGDAW -gBTj0UDC6u67VvpJ2NmXE7vz77nHHTASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud -DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAZYQg0VUOQ1DGoU0y0TsTzAZ4 -IEy5xavV7Nma9AJI0ZVFpqGEBjTXjxi7r/co1EREN3bi7QnZfJhU4SGVZ0T7wq+p -/S3x16DEPEufa3JmP+brBPOOP/5EJX5+2BXMUWuDcY7MAokaAIAudjmVk32FoZgy -54FkZ+YRillU++7k0ie8EEYE8pN2ABIqNCdHxGEhwEc0wVwB6bBONmcEssYmipUh -DQH6+sfKBcd+sUMGG3qd79sE7BF9w8bAHhKcBm5eTdEks9jh6H1o0PgBvFP8fFzF -q89KGuLw7T0n/Khkmrv5cifwmTpg42Ivorv8qk02aeiOAGiMyFFJ38BQtH64LQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID2zCCAsOgAwIBAgIURc832yfuirkVrhWhC4O1uBfTZXAwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTRk8xCzAJ -BgNVBAoMAk1DMQ0wCwYDVQQLDARyb290MRUwEwYDVQQDDAxyb290Y2EuYWRtaW4x -HzAdBgkqhkiG9w0BCQEWEHJvb3RjYUBhZG1pbi5jb20wIBcNMjEwNjA3MTcwNTQ3 -WhgPMjEyMTA1MTQxNzA1NDdaMHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEM -MAoGA1UEBwwDU0ZPMQswCQYDVQQKDAJNQzENMAsGA1UECwwEcm9vdDEVMBMGA1UE -AwwMcm9vdGNhLmFkbWluMR8wHQYJKoZIhvcNAQkBFhByb290Y2FAYWRtaW4uY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzKd0JrZR3N0A3C7Gp7sT -zLurt0pVjAIBh3N+5NsyY7eAHJWA7wRR+JpG4q6MxmYVWsk4MjsnWB0ViCCm+fTY -a9tFms6lmsjM4fJgIs8/DP+zBEOien7sD3kfddmI4ClODynNv3ODbJKyhzKQEOZ8 -sdf61yWYuFzayEfNoon6BlqroPv9B0eAsgOFDndPo6vbqAFlrYAyVXx+7hmH7Hv6 -8RWDaSr0uI62uhvAQeK4a+p9aTSwLcHRh1/7NezW9rzI0/7yzP3w/RS7tevDuacU -XMr3sH5xEUahGF72qYUVejUlP48fPLrdGK76QZk0M8K2EOyvuNq66P+UMialx+83 -NwIDAQABo1MwUTAdBgNVHQ4EFgQU49FAwuruu1b6SdjZlxO78++5xx0wHwYDVR0j -BBgwFoAU49FAwuruu1b6SdjZlxO78++5xx0wDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAQEADfrsmYBaeV4/MTRVazsey/o0ZhBoLJ+3RFYC6+M2lYB1 -yT92tbAT3787aHTw/SdFvA11oT+lMDEmBWowzZ1bp/J7tqlqMcmwL4QyhZjp0gmK -eqDXy2Jui/fOTRzWQ1ka7mR6OTWxxVoIjKVvJ/AysqGCTFMXZXrMthtCuQDG+b85 -B3ALz6/j0ZFqgKzftCIuY0UnBtDEuKkAa0QkDMHLvcMAw7V/etpQPypCXqmwnc2e -vvL6cSvakEVE7rErhIeeL+1m2TBSWNrPVIvggLMv655meqkhGQn9uYyiGw6i/2V/ -ngBAs4gYDvk20Cyg0kxQONmzreAdFzArud+k7FofZw== ------END CERTIFICATE----- diff --git a/pki/src/test/resources/keystore/partner2client1/truststore.jks b/pki/src/test/resources/keystore/partner2client1/truststore.jks deleted file mode 100644 index f2a54903b30054e525051f0897c3e55d51c1d8eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3135 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 diff --git a/pki/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/pki/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea8e..00000000000 --- a/pki/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file From 56ba35752ff3841e55fdd17f9a0b76e90f0fde36 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 27 Nov 2024 14:06:55 +1000 Subject: [PATCH 2/5] removed pki Signed-off-by: Sally MacFarlane --- acceptance-tests/dsl/build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/acceptance-tests/dsl/build.gradle b/acceptance-tests/dsl/build.gradle index 0b664c52556..6602fda58b8 100644 --- a/acceptance-tests/dsl/build.gradle +++ b/acceptance-tests/dsl/build.gradle @@ -18,8 +18,6 @@ dependencies { implementation project(':ethereum:permissioning') implementation project(':ethereum:rlp') implementation project(':metrics:core') - implementation project(':pki') - implementation project(path: ':pki', configuration: 'testArtifacts') implementation project(':plugin-api') implementation project(':plugins:rocksdb') implementation project(':services:kvstore') From a3d3ecacd933ca009a02c07c19f6de808d8cd7cb Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 27 Nov 2024 14:08:50 +1000 Subject: [PATCH 3/5] remove TLS p2p classes Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../tests/acceptance/dsl/node/BesuNode.java | 8 - .../dsl/node/ProcessBesuNodeRunner.java | 21 - .../dsl/node/ThreadBesuNodeRunner.java | 1 - .../configuration/BesuNodeConfiguration.java | 8 - .../BesuNodeConfigurationBuilder.java | 66 --- .../node/configuration/BesuNodeFactory.java | 18 - .../node/configuration/pki/PKCS11Utils.java | 60 --- .../org/hyperledger/besu/RunnerBuilder.java | 27 - .../org/hyperledger/besu/cli/BesuCommand.java | 12 - .../besu/cli/options/P2PTLSConfigOptions.java | 163 ------ .../src/test/resources/everything_config.toml | 11 - .../p2p/network/DefaultP2PNetwork.java | 9 - .../besu/ethereum/p2p/rlpx/RlpxAgent.java | 29 +- .../netty/NettyTLSConnectionInitializer.java | 159 ------ .../connections/netty/TLSConfiguration.java | 197 ------- .../connections/netty/TLSContextFactory.java | 230 -------- .../p2p/network/DefaultP2PNetworkTest.java | 2 +- .../p2p/network/P2PPlainNetworkTest.java | 156 +----- .../NettyTLSConnectionInitializerTest.java | 195 ------- .../netty/TLSContextFactoryTest.java | 504 ------------------ 21 files changed, 20 insertions(+), 1857 deletions(-) delete mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/pki/PKCS11Utils.java delete mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/P2PTLSConfigOptions.java delete mode 100644 ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializer.java delete mode 100644 ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSConfiguration.java delete mode 100644 ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactory.java delete mode 100644 ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializerTest.java delete mode 100644 ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e02ad1bc026..86c382701a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Breaking Changes - Removed Retesteth rpc service and commands [#7833](https://github.com/hyperledger/besu/pull/7783) +- TLS for P2P (early access feature) has been removed []() ### Upcoming Breaking Changes - Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java index 76e18812b09..3f18a543152 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java @@ -32,7 +32,6 @@ import org.hyperledger.besu.ethereum.core.Util; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; @@ -96,7 +95,6 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable private final Properties portsProperties = new Properties(); private final Boolean p2pEnabled; private final int p2pPort; - private final Optional tlsConfiguration; private final NetworkingConfiguration networkingConfiguration; private final boolean revertReasonEnabled; @@ -156,7 +154,6 @@ public BesuNode( final GenesisConfigurationProvider genesisConfigProvider, final boolean p2pEnabled, final int p2pPort, - final Optional tlsConfiguration, final NetworkingConfiguration networkingConfiguration, final boolean discoveryEnabled, final boolean bootnodeEligible, @@ -207,7 +204,6 @@ public BesuNode( this.network = network; this.p2pEnabled = p2pEnabled; this.p2pPort = p2pPort; - this.tlsConfiguration = tlsConfiguration; this.networkingConfiguration = networkingConfiguration; this.discoveryEnabled = discoveryEnabled; this.bootnodeEligible = bootnodeEligible; @@ -659,10 +655,6 @@ public boolean isP2pEnabled() { return p2pEnabled; } - public Optional getTLSConfiguration() { - return tlsConfiguration; - } - public NetworkingConfiguration getNetworkingConfiguration() { return networkingConfiguration; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java index ee865a81425..33a9a1cfba2 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java @@ -22,7 +22,6 @@ import org.hyperledger.besu.cli.options.storage.DataStorageOptions; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.plugin.services.metrics.MetricCategory; @@ -365,26 +364,6 @@ private List commandlineArgs(final BesuNode node, final Path dataDir) { final List networkConfigParams = NetworkingOptions.fromConfig(node.getNetworkingConfiguration()).getCLIOptions(); params.addAll(networkConfigParams); - if (node.getTLSConfiguration().isPresent()) { - final TLSConfiguration config = node.getTLSConfiguration().get(); - params.add("--Xp2p-tls-enabled"); - params.add("--Xp2p-tls-keystore-type"); - params.add(config.getKeyStoreType()); - params.add("--Xp2p-tls-keystore-file"); - params.add(config.getKeyStorePath().toAbsolutePath().toString()); - params.add("--Xp2p-tls-keystore-password-file"); - params.add(config.getKeyStorePasswordPath().toAbsolutePath().toString()); - params.add("--Xp2p-tls-crl-file"); - params.add(config.getCrlPath().toAbsolutePath().toString()); - if (null != config.getTrustStoreType()) { - params.add("--Xp2p-tls-truststore-type"); - params.add(config.getTrustStoreType()); - params.add("--Xp2p-tls-truststore-file"); - params.add(config.getTrustStorePath().toAbsolutePath().toString()); - params.add("--Xp2p-tls-truststore-password-file"); - params.add(config.getTrustStorePasswordPath().toAbsolutePath().toString()); - } - } } if (node.isRevertReasonEnabled()) { diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index 9effaff4d44..3baa6ee0273 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -197,7 +197,6 @@ public void startNode(final BesuNode node) { .permissioningService(permissioningService) .metricsConfiguration(node.getMetricsConfiguration()) .p2pEnabled(node.isP2pEnabled()) - .p2pTLSConfiguration(node.getTLSConfiguration()) .graphQLConfiguration(GraphQLConfiguration.createDefault()) .staticNodes(node.getStaticNodes().stream().map(EnodeURLImpl::fromString).toList()) .besuPluginContext(besuPluginContext) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java index 5840f1e4f1f..f6a8cfb57ae 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java @@ -25,7 +25,6 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; @@ -56,7 +55,6 @@ public class BesuNodeConfiguration { private final GenesisConfigurationProvider genesisConfigProvider; private final boolean p2pEnabled; private final int p2pPort; - private final Optional tlsConfiguration; private final NetworkingConfiguration networkingConfiguration; private final boolean discoveryEnabled; private final boolean bootnodeEligible; @@ -95,7 +93,6 @@ public class BesuNodeConfiguration { final GenesisConfigurationProvider genesisConfigProvider, final boolean p2pEnabled, final int p2pPort, - final Optional tlsConfiguration, final NetworkingConfiguration networkingConfiguration, final boolean discoveryEnabled, final boolean bootnodeEligible, @@ -131,7 +128,6 @@ public class BesuNodeConfiguration { this.genesisConfigProvider = genesisConfigProvider; this.p2pEnabled = p2pEnabled; this.p2pPort = p2pPort; - this.tlsConfiguration = tlsConfiguration; this.networkingConfiguration = networkingConfiguration; this.discoveryEnabled = discoveryEnabled; this.bootnodeEligible = bootnodeEligible; @@ -226,10 +222,6 @@ public int getP2pPort() { return p2pPort; } - public Optional getTLSConfiguration() { - return tlsConfiguration; - } - public NetworkingConfiguration getNetworkingConfiguration() { return networkingConfiguration; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java index 9b000f56f12..f7342a4c8fb 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java @@ -16,9 +16,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Collections.singletonList; -import static org.hyperledger.besu.pki.keystore.KeyStoreWrapper.KEYSTORE_TYPE_JKS; -import static org.hyperledger.besu.pki.keystore.KeyStoreWrapper.KEYSTORE_TYPE_PKCS11; -import static org.hyperledger.besu.pki.keystore.KeyStoreWrapper.KEYSTORE_TYPE_PKCS12; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.crypto.KeyPair; @@ -31,7 +28,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.authentication.JwtAlgorithm; import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; -import org.hyperledger.besu.ethereum.api.tls.FileBasedPasswordProvider; import org.hyperledger.besu.ethereum.core.AddressHelpers; import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration; import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration.MutableInitValues; @@ -39,12 +35,10 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.pki.PKCS11Utils; import java.io.File; import java.net.URISyntaxException; @@ -84,7 +78,6 @@ public class BesuNodeConfigurationBuilder { private GenesisConfigurationProvider genesisConfigProvider = ignore -> Optional.empty(); private Boolean p2pEnabled = true; private int p2pPort = 0; - private Optional tlsConfiguration = Optional.empty(); private final NetworkingConfiguration networkingConfiguration = NetworkingConfiguration.create(); private boolean discoveryEnabled = true; private boolean bootnodeEligible = true; @@ -381,64 +374,6 @@ public BesuNodeConfigurationBuilder p2pPort(final int p2pPort) { return this; } - private static Path toPath(final String path) throws Exception { - return Path.of(BesuNodeConfigurationBuilder.class.getResource(path).toURI()); - } - - public BesuNodeConfigurationBuilder p2pTLSEnabled(final String name, final String type) { - final TLSConfiguration.Builder builder = TLSConfiguration.Builder.tlsConfiguration(); - try { - final String nsspin = "/pki-certs/%s/nsspin.txt"; - final String truststore = "/pki-certs/%s/truststore.p12"; - final String crl = "/pki-certs/crl/crl.pem"; - switch (type) { - case KEYSTORE_TYPE_JKS: - builder - .withKeyStoreType(type) - .withKeyStorePath(toPath(String.format("/pki-certs/%s/% bannedNodeIds = new ArrayList<>(); private boolean p2pEnabled = true; - private Optional p2pTLSConfiguration = Optional.empty(); private boolean discovery; private String p2pAdvertisedHost; private String p2pListenInterface = NetworkUtility.INADDR_ANY; @@ -235,30 +233,6 @@ public RunnerBuilder p2pEnabled(final boolean p2pEnabled) { return this; } - /** - * TLSConfiguration p2pTLSConfiguration. - * - * @param p2pTLSConfiguration the TLSConfiguration p2pTLSConfiguration - * @return the runner builder - */ - public RunnerBuilder p2pTLSConfiguration(final TLSConfiguration p2pTLSConfiguration) { - this.p2pTLSConfiguration = Optional.of(p2pTLSConfiguration); - return this; - } - - /** - * Optional TLSConfiguration p2pTLSConfiguration. - * - * @param p2pTLSConfiguration the TLSConfiguration p2pTLSConfiguration - * @return the runner builder - */ - public RunnerBuilder p2pTLSConfiguration(final Optional p2pTLSConfiguration) { - if (null != p2pTLSConfiguration) { - this.p2pTLSConfiguration = p2pTLSConfiguration; - } - return this; - } - /** * Enable Discovery. * @@ -735,7 +709,6 @@ public Runner build() { .supportedCapabilities(caps) .natService(natService) .storageProvider(storageProvider) - .p2pTLSConfiguration(p2pTLSConfiguration) .blockchain(context.getBlockchain()) .blockNumberForks(besuController.getGenesisConfigOptions().getForkBlockNumbers()) .timestampForks(besuController.getGenesisConfigOptions().getForkBlockTimestamps()) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index e2c657dd18d..c4c3da6e8dc 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -60,7 +60,6 @@ import org.hyperledger.besu.cli.options.NetworkingOptions; import org.hyperledger.besu.cli.options.NodePrivateKeyFileOption; import org.hyperledger.besu.cli.options.P2PDiscoveryOptions; -import org.hyperledger.besu.cli.options.P2PTLSConfigOptions; import org.hyperledger.besu.cli.options.PermissionsOptions; import org.hyperledger.besu.cli.options.PluginsConfigurationOptions; import org.hyperledger.besu.cli.options.PrivacyPluginOptions; @@ -127,7 +126,6 @@ import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; import org.hyperledger.besu.ethereum.p2p.peers.StaticNodesParser; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.permissioning.LocalPermissioningConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProvider; @@ -259,7 +257,6 @@ import picocli.CommandLine.Command; import picocli.CommandLine.ExecutionException; import picocli.CommandLine.IExecutionStrategy; -import picocli.CommandLine.Mixin; import picocli.CommandLine.Option; import picocli.CommandLine.ParameterException; @@ -704,8 +701,6 @@ static class PrivacyOptionGroup { description = "Specifies the number of last blocks to cache (default: ${DEFAULT-VALUE})") private final Integer numberOfblocksToCache = 0; - @Mixin private P2PTLSConfigOptions p2pTLSConfigOptions; - // Plugins Configuration Option Group @CommandLine.ArgGroup(validate = false) PluginsConfigurationOptions pluginsConfigurationOptions = new PluginsConfigurationOptions(); @@ -720,7 +715,6 @@ static class PrivacyOptionGroup { private ApiConfiguration apiConfiguration; private MetricsConfiguration metricsConfiguration; private Optional permissioningConfiguration; - private Optional p2pTLSConfiguration; private DataStorageConfiguration dataStorageConfiguration; private Collection staticNodes; private BesuController besuController; @@ -1232,7 +1226,6 @@ private Runner buildRunner() { return synchronize( besuController, p2PDiscoveryConfig.p2pEnabled(), - p2pTLSConfiguration, p2PDiscoveryConfig.peerDiscoveryEnabled(), ethNetworkConfig, p2PDiscoveryConfig.p2pHost(), @@ -1457,7 +1450,6 @@ private void validateOptions() { validateApiOptions(); validateConsensusSyncCompatibilityOptions(); validatePluginOptions(); - p2pTLSConfigOptions.checkP2PTLSOptionsDependencies(logger, commandLine); } private void validateConsensusSyncCompatibilityOptions() { @@ -1696,7 +1688,6 @@ private void configure() throws Exception { if (isEngineApiEnabled()) { engineJsonRpcConfiguration = createEngineJsonRpcConfiguration(); } - p2pTLSConfiguration = p2pTLSConfigOptions.p2pTLSConfiguration(commandLine); graphQLConfiguration = graphQlOptions.graphQLConfiguration( hostsAllowlist, p2PDiscoveryOptions.p2pHost, unstableRPCOptions.getHttpTimeoutSec()); @@ -2221,7 +2212,6 @@ private OptionalInt getGenesisBlockPeriodSeconds( private Runner synchronize( final BesuController controller, final boolean p2pEnabled, - final Optional p2pTLSConfiguration, final boolean peerDiscoveryEnabled, final EthNetworkConfig ethNetworkConfig, final String p2pAdvertisedHost, @@ -2241,8 +2231,6 @@ private Runner synchronize( checkNotNull(runnerBuilder); - p2pTLSConfiguration.ifPresent(runnerBuilder::p2pTLSConfiguration); - final Runner runner = runnerBuilder .vertx(vertx) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/P2PTLSConfigOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/P2PTLSConfigOptions.java deleted file mode 100644 index ee53a5e96f4..00000000000 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/P2PTLSConfigOptions.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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; - -import static java.util.Arrays.asList; -import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_KEYSTORE_TYPE; -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.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; - -import java.nio.file.Path; -import java.util.Optional; - -import org.slf4j.Logger; -import picocli.CommandLine; -import picocli.CommandLine.Option; -import picocli.CommandLine.ParameterException; - -/** The P2P TLS Config Cli Options. */ -public class P2PTLSConfigOptions { - @Option( - names = {"--Xp2p-tls-enabled"}, - hidden = true, - description = "Enable P2P TLS functionality (default: ${DEFAULT-VALUE})") - private final Boolean p2pTLSEnabled = false; - - @SuppressWarnings({ - "FieldCanBeFinal", - "FieldMayBeFinal" - }) // p2pTLSKeyStoreType requires non-final Strings. - @Option( - names = {"--Xp2p-tls-keystore-type"}, - hidden = true, - paramLabel = "", - description = "P2P service keystore type. Required if P2P TLS is enabled.") - private String p2pTLSKeyStoreType = DEFAULT_KEYSTORE_TYPE; - - @Option( - names = {"--Xp2p-tls-keystore-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "Keystore containing key/certificate for the P2P service.") - private final Path p2pTLSKeyStoreFile = null; - - @Option( - names = {"--Xp2p-tls-keystore-password-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = - "File containing password to unlock keystore for the P2P service. Required if P2P TLS is enabled.") - private final Path p2pTLSKeyStorePasswordFile = null; - - @SuppressWarnings({ - "FieldCanBeFinal", - "FieldMayBeFinal" - }) // p2pTLSTrustStoreType requires non-final Strings. - @Option( - names = {"--Xp2p-tls-truststore-type"}, - hidden = true, - paramLabel = "", - description = "P2P service truststore type.") - private String p2pTLSTrustStoreType = DEFAULT_KEYSTORE_TYPE; - - @Option( - names = {"--Xp2p-tls-truststore-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "Truststore containing trusted certificates for the P2P service.") - private final Path p2pTLSTrustStoreFile = null; - - @Option( - names = {"--Xp2p-tls-truststore-password-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "File containing password to unlock truststore for the P2P service.") - private final Path p2pTLSTrustStorePasswordFile = null; - - @Option( - names = {"--Xp2p-tls-crl-file"}, - hidden = true, - paramLabel = MANDATORY_FILE_FORMAT_HELP, - description = "Certificate revocation list for the P2P service.") - private final Path p2pCrlFile = null; - - @Option( - names = {"--Xp2p-tls-clienthello-sni"}, - hidden = true, - description = - "Whether to send a SNI header in the TLS ClientHello message (default: ${DEFAULT-VALUE})") - private final Boolean p2pTlsClientHelloSniHeaderEnabled = false; - - /** Default constructor. */ - P2PTLSConfigOptions() {} - - /** - * Generate P2p tls configuration. - * - * @param commandLine the command line object to report exceptions - * @return the optional TLSConfiguration - */ - public Optional p2pTLSConfiguration(final CommandLine commandLine) { - if (!p2pTLSEnabled) { - return Optional.empty(); - } - - if (p2pTLSKeyStoreType == null) { - throw new ParameterException( - commandLine, "Keystore type is required when p2p TLS is enabled"); - } - - if (p2pTLSKeyStorePasswordFile == null) { - throw new ParameterException( - commandLine, - "File containing password to unlock keystore is required when p2p TLS is enabled"); - } - - return Optional.of( - TLSConfiguration.Builder.tlsConfiguration() - .withKeyStoreType(p2pTLSKeyStoreType) - .withKeyStorePath(p2pTLSKeyStoreFile) - .withKeyStorePasswordSupplier(new FileBasedPasswordProvider(p2pTLSKeyStorePasswordFile)) - .withKeyStorePasswordPath(p2pTLSKeyStorePasswordFile) - .withTrustStoreType(p2pTLSTrustStoreType) - .withTrustStorePath(p2pTLSTrustStoreFile) - .withTrustStorePasswordSupplier( - null == p2pTLSTrustStorePasswordFile - ? null - : new FileBasedPasswordProvider(p2pTLSTrustStorePasswordFile)) - .withTrustStorePasswordPath(p2pTLSTrustStorePasswordFile) - .withCrlPath(p2pCrlFile) - .withClientHelloSniEnabled(p2pTlsClientHelloSniHeaderEnabled) - .build()); - } - - /** - * Check P2P Tls options dependencies. - * - * @param logger the logger - * @param commandLine the command line - */ - public void checkP2PTLSOptionsDependencies(final Logger logger, final CommandLine commandLine) { - CommandLineUtils.checkOptionDependencies( - logger, - commandLine, - "--Xp2p-tls-enabled", - !p2pTLSEnabled, - asList("--Xp2p-tls-keystore-type", "--Xp2p-tls-keystore-password-file")); - } -} diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index 960b2b5772c..e210d9fa92e 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -244,17 +244,6 @@ Xpeertask-system-enabled=false # compatibility flags compatibility-eth64-forkid-enabled=false -#p2p over ssl -Xp2p-tls-enabled=false -Xp2p-tls-keystore-type="none" -Xp2p-tls-keystore-file="none.file" -Xp2p-tls-truststore-password-file="none" -Xp2p-tls-truststore-type="none" -Xp2p-tls-truststore-file="none.file" -Xp2p-tls-keystore-password-file="none" -Xp2p-tls-crl-file="none.file" -Xp2p-tls-clienthello-sni=false - #contracts Xevm-jumpdest-cache-weight-kb=32000 diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java index 55a536976fe..610ebd39d8a 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java @@ -44,7 +44,6 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.MessageCallback; import org.hyperledger.besu.ethereum.p2p.rlpx.RlpxAgent; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.ShouldConnectCallback; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; @@ -520,7 +519,6 @@ public static class Builder { private NatService natService = new NatService(Optional.empty()); private MetricsSystem metricsSystem; private StorageProvider storageProvider; - private Optional p2pTLSConfiguration = Optional.empty(); private Blockchain blockchain; private List blockNumberForks; private List timestampForks; @@ -605,7 +603,6 @@ private RlpxAgent createRlpxAgent( .peerPrivileges(peerPrivileges) .localNode(localNode) .metricsSystem(metricsSystem) - .p2pTLSConfiguration(p2pTLSConfiguration) .allConnectionsSupplier(allConnectionsSupplier) .allActiveConnectionsSupplier(allActiveConnectionsSupplier) .maxPeers(maxPeers) @@ -684,12 +681,6 @@ public Builder storageProvider(final StorageProvider storageProvider) { return this; } - public Builder p2pTLSConfiguration(final Optional p2pTLSConfiguration) { - checkNotNull(p2pTLSConfiguration); - this.p2pTLSConfiguration = p2pTLSConfiguration; - return this; - } - public Builder blockchain(final MutableBlockchain blockchain) { checkNotNull(blockchain); this.blockchain = blockchain; diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/RlpxAgent.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/RlpxAgent.java index 7363b765d4d..48c417fda44 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/RlpxAgent.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/RlpxAgent.java @@ -30,8 +30,6 @@ import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnectionEvents; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerRlpxPermissions; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.NettyConnectionInitializer; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.NettyTLSConnectionInitializer; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.ShouldConnectCallback; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.messages.DisconnectMessage.DisconnectReason; @@ -371,7 +369,6 @@ public static class Builder { private ConnectionInitializer connectionInitializer; private PeerConnectionEvents connectionEvents; private MetricsSystem metricsSystem; - private Optional p2pTLSConfiguration; private Supplier> allConnectionsSupplier; private Supplier> allActiveConnectionsSupplier; private int maxPeers; @@ -386,23 +383,10 @@ public RlpxAgent build() { connectionEvents = new PeerConnectionEvents(metricsSystem); } if (connectionInitializer == null) { - if (p2pTLSConfiguration.isPresent()) { - LOG.debug("TLS Configuration found using NettyTLSConnectionInitializer"); - connectionInitializer = - new NettyTLSConnectionInitializer( - nodeKey, - config, - localNode, - connectionEvents, - metricsSystem, - p2pTLSConfiguration.get(), - peerTable); - } else { - LOG.debug("Using default NettyConnectionInitializer"); - connectionInitializer = - new NettyConnectionInitializer( - nodeKey, config, localNode, connectionEvents, metricsSystem, peerTable); - } + LOG.debug("Using default NettyConnectionInitializer"); + connectionInitializer = + new NettyConnectionInitializer( + nodeKey, config, localNode, connectionEvents, metricsSystem, peerTable); } final PeerRlpxPermissions rlpxPermissions = @@ -475,11 +459,6 @@ public Builder metricsSystem(final MetricsSystem metricsSystem) { return this; } - public Builder p2pTLSConfiguration(final Optional p2pTLSConfiguration) { - this.p2pTLSConfiguration = p2pTLSConfiguration; - return this; - } - public Builder allConnectionsSupplier( final Supplier> allConnectionsSupplier) { this.allConnectionsSupplier = allConnectionsSupplier; diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializer.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializer.java deleted file mode 100644 index db41c1574c7..00000000000 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializer.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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.ethereum.p2p.rlpx.connections.netty; - -import static org.hyperledger.besu.ethereum.p2p.rlpx.RlpxFrameConstants.LENGTH_FRAME_SIZE; -import static org.hyperledger.besu.ethereum.p2p.rlpx.RlpxFrameConstants.LENGTH_MAX_MESSAGE_FRAME; - -import org.hyperledger.besu.cryptoservices.NodeKey; -import org.hyperledger.besu.ethereum.p2p.config.RlpxConfiguration; -import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerTable; -import org.hyperledger.besu.ethereum.p2p.peers.LocalNode; -import org.hyperledger.besu.ethereum.p2p.peers.Peer; -import org.hyperledger.besu.ethereum.p2p.plain.PlainFramer; -import org.hyperledger.besu.ethereum.p2p.plain.PlainHandshaker; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnectionEventDispatcher; -import org.hyperledger.besu.ethereum.p2p.rlpx.framing.Framer; -import org.hyperledger.besu.ethereum.p2p.rlpx.handshake.HandshakeSecrets; -import org.hyperledger.besu.ethereum.p2p.rlpx.handshake.Handshaker; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.plugin.services.MetricsSystem; - -import java.security.GeneralSecurityException; -import java.util.Optional; -import java.util.function.Supplier; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Suppliers; -import io.netty.channel.Channel; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import io.netty.handler.codec.LengthFieldPrepender; -import io.netty.handler.codec.compression.SnappyFrameDecoder; -import io.netty.handler.codec.compression.SnappyFrameEncoder; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslHandler; - -public class NettyTLSConnectionInitializer extends NettyConnectionInitializer { - - private final Optional> tlsContextFactorySupplier; - private final Boolean clientHelloSniHeaderEnabled; - - public NettyTLSConnectionInitializer( - final NodeKey nodeKey, - final RlpxConfiguration config, - final LocalNode localNode, - final PeerConnectionEventDispatcher eventDispatcher, - final MetricsSystem metricsSystem, - final TLSConfiguration p2pTLSConfiguration, - final PeerTable peerTable) { - this( - nodeKey, - config, - localNode, - eventDispatcher, - metricsSystem, - defaultTlsContextFactorySupplier(p2pTLSConfiguration), - p2pTLSConfiguration.getClientHelloSniHeaderEnabled(), - peerTable); - } - - @VisibleForTesting - NettyTLSConnectionInitializer( - final NodeKey nodeKey, - final RlpxConfiguration config, - final LocalNode localNode, - final PeerConnectionEventDispatcher eventDispatcher, - final MetricsSystem metricsSystem, - final Supplier tlsContextFactorySupplier, - final Boolean clientHelloSniHeaderEnabled, - final PeerTable peerTable) { - super(nodeKey, config, localNode, eventDispatcher, metricsSystem, peerTable); - if (tlsContextFactorySupplier != null) { - this.tlsContextFactorySupplier = - Optional.of(Suppliers.memoize(tlsContextFactorySupplier::get)); - } else { - this.tlsContextFactorySupplier = Optional.empty(); - } - this.clientHelloSniHeaderEnabled = clientHelloSniHeaderEnabled; - } - - @Override - void addAdditionalOutboundHandlers(final Channel ch, final Peer peer) - throws GeneralSecurityException { - if (tlsContextFactorySupplier.isPresent()) { - final SslContext clientSslContext = - tlsContextFactorySupplier.get().get().createNettyClientSslContext(); - final EnodeURL enode = peer.getEnodeURL(); - final SslHandler sslHandler = createClientSslHandler(ch, clientSslContext, enode); - addHandlersToChannelPipeline(ch, sslHandler); - } - } - - private SslHandler createClientSslHandler( - final Channel ch, final SslContext sslContext, final EnodeURL enode) { - if (this.clientHelloSniHeaderEnabled) { - return sslContext.newHandler( - ch.alloc(), enode.getHost(), enode.getListeningPort().orElseThrow()); - } else { - return sslContext.newHandler(ch.alloc()); - } - } - - @Override - void addAdditionalInboundHandlers(final Channel ch) throws GeneralSecurityException { - if (tlsContextFactorySupplier.isPresent()) { - final SslContext serverSslContext = - tlsContextFactorySupplier.get().get().createNettyServerSslContext(); - addHandlersToChannelPipeline(ch, serverSslContext.newHandler(ch.alloc())); - } - } - - private void addHandlersToChannelPipeline(final Channel ch, final SslHandler sslHandler) { - ch.pipeline().addLast(sslHandler); - ch.pipeline().addLast(new SnappyFrameDecoder()); - ch.pipeline().addLast(new SnappyFrameEncoder()); - ch.pipeline() - .addLast( - new LengthFieldBasedFrameDecoder( - LENGTH_MAX_MESSAGE_FRAME, 0, LENGTH_FRAME_SIZE, 0, LENGTH_FRAME_SIZE)); - ch.pipeline().addLast(new LengthFieldPrepender(LENGTH_FRAME_SIZE)); - } - - @Override - public Handshaker buildInstance() { - return new PlainHandshaker(); - } - - @Override - public Framer buildFramer(final HandshakeSecrets secrets) { - return new PlainFramer(); - } - - @VisibleForTesting - static Supplier defaultTlsContextFactorySupplier( - final TLSConfiguration tlsConfiguration) { - if (tlsConfiguration == null) { - throw new IllegalStateException("TLSConfiguration cannot be null when using TLS"); - } - - return () -> { - try { - return TLSContextFactory.buildFrom(tlsConfiguration); - } catch (final Exception e) { - throw new IllegalStateException("Error creating TLSContextFactory", e); - } - }; - } -} diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSConfiguration.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSConfiguration.java deleted file mode 100644 index 2bcb6ddbc65..00000000000 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSConfiguration.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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.ethereum.p2p.rlpx.connections.netty; - -import static java.util.Objects.requireNonNull; - -import java.nio.file.Path; -import java.util.function.Supplier; - -public class TLSConfiguration { - - private final String keyStoreType; - private final Path keyStorePath; - private final Supplier keyStorePasswordSupplier; - private final Path keyStorePasswordPath; - private final String trustStoreType; - private final Path trustStorePath; - private final Supplier trustStorePasswordSupplier; - private final Path trustStorePasswordPath; - private final Path crlPath; - private final String[] allowedProtocols; - private final Boolean clientHelloSniHeaderEnabled; - - private TLSConfiguration( - final String keyStoreType, - final Path keyStorePath, - final Supplier keyStorePasswordSupplier, - final Path keyStorePasswordPath, - final String trustStoreType, - final Path trustStorePath, - final Supplier trustStorePasswordSupplier, - final Path trustStorePasswordPath, - final Path crlPath, - final String[] allowedProtocols, - final Boolean clientHelloSniHeaderEnabled) { - this.keyStoreType = keyStoreType; - this.keyStorePath = keyStorePath; - this.keyStorePasswordSupplier = keyStorePasswordSupplier; - this.keyStorePasswordPath = keyStorePasswordPath; - this.trustStoreType = trustStoreType; - this.trustStorePath = trustStorePath; - this.trustStorePasswordSupplier = trustStorePasswordSupplier; - this.trustStorePasswordPath = trustStorePasswordPath; - this.crlPath = crlPath; - this.allowedProtocols = allowedProtocols; - this.clientHelloSniHeaderEnabled = clientHelloSniHeaderEnabled; - } - - public String getKeyStoreType() { - return keyStoreType; - } - - public Path getKeyStorePath() { - return keyStorePath; - } - - public String getKeyStorePassword() { - return null == keyStorePasswordSupplier ? null : keyStorePasswordSupplier.get(); - } - - public Path getKeyStorePasswordPath() { - return keyStorePasswordPath; - } - - public String getTrustStoreType() { - return trustStoreType; - } - - public Path getTrustStorePath() { - return trustStorePath; - } - - public String getTrustStorePassword() { - return null == trustStorePasswordSupplier ? null : trustStorePasswordSupplier.get(); - } - - public Path getTrustStorePasswordPath() { - return trustStorePasswordPath; - } - - public Path getCrlPath() { - return crlPath; - } - - public String[] getAllowedProtocols() { - return allowedProtocols; - } - - public Boolean getClientHelloSniHeaderEnabled() { - return clientHelloSniHeaderEnabled; - } - - public static final class Builder { - private String keyStoreType; - private Path keyStorePath; - private Supplier keyStorePasswordSupplier; - private Path keyStorePasswordPath; - private String trustStoreType; - private Path trustStorePath; - private Supplier trustStorePasswordSupplier; - private Path trustStorePasswordPath; - private Path crlPath; - private String[] allowedProtocols; - private Boolean clientHelloSniHeaderEnabled; - - private Builder() {} - - public static Builder tlsConfiguration() { - return new Builder(); - } - - public Builder withKeyStoreType(final String keyStoreType) { - this.keyStoreType = keyStoreType; - return this; - } - - public Builder withKeyStorePath(final Path keyStorePath) { - this.keyStorePath = keyStorePath; - return this; - } - - public Builder withKeyStorePasswordPath(final Path keyStorePasswordPath) { - this.keyStorePasswordPath = keyStorePasswordPath; - return this; - } - - public Builder withKeyStorePasswordSupplier(final Supplier keyStorePasswordSupplier) { - this.keyStorePasswordSupplier = keyStorePasswordSupplier; - return this; - } - - public Builder withTrustStoreType(final String trustStoreType) { - this.trustStoreType = trustStoreType; - return this; - } - - public Builder withTrustStorePath(final Path trustStorePath) { - this.trustStorePath = trustStorePath; - return this; - } - - public Builder withTrustStorePasswordSupplier( - final Supplier trustStorePasswordSupplier) { - this.trustStorePasswordSupplier = trustStorePasswordSupplier; - return this; - } - - public Builder withTrustStorePasswordPath(final Path trustStorePasswordPath) { - this.trustStorePasswordPath = trustStorePasswordPath; - return this; - } - - public Builder withCrlPath(final Path crlPath) { - this.crlPath = crlPath; - return this; - } - - public Builder withAllowedProtocols(final String[] allowedProtocols) { - this.allowedProtocols = allowedProtocols; - return this; - } - - public Builder withClientHelloSniEnabled(final Boolean clientHelloSniHeaderEnabled) { - this.clientHelloSniHeaderEnabled = clientHelloSniHeaderEnabled; - return this; - } - - public TLSConfiguration build() { - requireNonNull(keyStoreType, "Key Store Type must not be null"); - requireNonNull(keyStorePasswordSupplier, "Key Store password supplier must not be null"); - return new TLSConfiguration( - keyStoreType, - keyStorePath, - keyStorePasswordSupplier, - keyStorePasswordPath, - trustStoreType, - trustStorePath, - trustStorePasswordSupplier, - trustStorePasswordPath, - crlPath, - allowedProtocols, - clientHelloSniHeaderEnabled); - } - } -} diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactory.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactory.java deleted file mode 100644 index d3d6c6e280a..00000000000 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactory.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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.ethereum.p2p.rlpx.connections.netty; - -import org.hyperledger.besu.pki.keystore.HardwareKeyStoreWrapper; -import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; -import org.hyperledger.besu.pki.keystore.SoftwareKeyStoreWrapper; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import io.netty.handler.ssl.ClientAuth; -import io.netty.handler.ssl.IdentityCipherSuiteFilter; -import io.netty.handler.ssl.JdkSslContext; -import io.netty.handler.ssl.SslContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TLSContextFactory { - - private static final Logger LOG = LoggerFactory.getLogger(TLSContextFactory.class); - - private static final String[] ALLOWED_PROTOCOLS = {"TLSv1.3"}; - private static final String KEYMANAGER_FACTORY_ALGORITHM = "PKIX"; - private static final String TRUSTMANAGER_FACTORY_ALGORITHM = "PKIX"; - - private List enabledCipherSuites = null; - private KeyManagerFactory kmf; - private TrustManagerFactory tmf; - private Collection crls; - private String[] allowedProtocols; - - protected TLSContextFactory() {} - - protected TLSContextFactory( - final String keystorePass, - final KeyStoreWrapper keystoreWrapper, - final List configuredCipherSuites, - final String[] allowedProtocols) - throws GeneralSecurityException, IOException { - kmf = getKeyManagerFactory(keystoreWrapper.getKeyStore(), keystorePass); - tmf = getTrustManagerFactory(keystoreWrapper.getTrustStore()); - crls = keystoreWrapper.getCRLs(); - if (configuredCipherSuites != null && !configuredCipherSuites.isEmpty()) { - enabledCipherSuites = configuredCipherSuites; - } - this.allowedProtocols = null == allowedProtocols ? ALLOWED_PROTOCOLS : allowedProtocols; - } - - public static TLSContextFactory getInstance( - final String keyStorePassword, final KeyStoreWrapper wrapper, final String[] allowedProtocols) - throws GeneralSecurityException, IOException { - return new TLSContextFactory(keyStorePassword, wrapper, null, allowedProtocols); - } - - public static TLSContextFactory getInstance( - final String keyStorePassword, final KeyStoreWrapper wrapper) - throws GeneralSecurityException, IOException { - return new TLSContextFactory(keyStorePassword, wrapper, null, null); - } - - public SslContext createNettyServerSslContext() - throws NoSuchAlgorithmException, KeyManagementException { - final List enabledCipherSuites = getEnabledCipherSuites(); - - return new JdkSslContext( - createJavaSslContext(), - false, - enabledCipherSuites, - IdentityCipherSuiteFilter.INSTANCE, - null, - ClientAuth.REQUIRE, - null, - false); - } - - public SslContext createNettyClientSslContext() - throws NoSuchAlgorithmException, KeyManagementException { - final List enabledCipherSuites = getEnabledCipherSuites(); - - return new JdkSslContext( - createJavaSslContext(), - true, - enabledCipherSuites, - IdentityCipherSuiteFilter.INSTANCE, - null, - ClientAuth.NONE, - null, - false); - } - - public SSLContext createJavaSslContext() throws NoSuchAlgorithmException, KeyManagementException { - final SSLContext context = SSLContext.getInstance(getTlsProtocol()); - context.init( - kmf.getKeyManagers(), - null == crls || crls.isEmpty() ? tmf.getTrustManagers() : wrap(tmf.getTrustManagers()), - null); - return context; - } - - protected TrustManager[] wrap(final TrustManager[] trustMgrs) { - final TrustManager[] ret = trustMgrs.clone(); - for (int i = 0; i < ret.length; i++) { - TrustManager trustMgr = ret[i]; - if (trustMgr instanceof X509TrustManager) { - X509TrustManager x509TrustManager = (X509TrustManager) trustMgr; - ret[i] = - new X509TrustManager() { - @Override - public void checkClientTrusted( - final X509Certificate[] x509Certificates, final String s) - throws CertificateException { - checkRevoked(x509Certificates); - x509TrustManager.checkClientTrusted(x509Certificates, s); - } - - @Override - public void checkServerTrusted( - final X509Certificate[] x509Certificates, final String s) - throws CertificateException { - checkRevoked(x509Certificates); - x509TrustManager.checkServerTrusted(x509Certificates, s); - } - - private void checkRevoked(final X509Certificate[] x509Certificates) - throws CertificateException { - for (X509CRL crl : crls) { - for (X509Certificate cert : x509Certificates) { - if (crl.isRevoked(cert)) { - throw new CertificateException("Certificate revoked"); - } - } - } - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return x509TrustManager.getAcceptedIssuers(); - } - }; - } - } - return ret; - } - - protected TrustManagerFactory getTrustManagerFactory(final KeyStore truststore) - throws GeneralSecurityException { - final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TRUSTMANAGER_FACTORY_ALGORITHM); - tmf.init(truststore); - return tmf; - } - - protected KeyManagerFactory getKeyManagerFactory( - final KeyStore keystore, final String keystorePassword) throws GeneralSecurityException { - final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYMANAGER_FACTORY_ALGORITHM); - kmf.init(keystore, keystorePassword.toCharArray()); - return kmf; - } - - private List getEnabledCipherSuites() { - final String protocol = getTlsProtocol(); - try { - if (enabledCipherSuites == null || enabledCipherSuites.isEmpty()) { - final SSLContext sslcontext = SSLContext.getInstance(protocol); - sslcontext.init(null, null, null); - enabledCipherSuites = Arrays.asList(sslcontext.createSSLEngine().getEnabledCipherSuites()); - } - } catch (final NoSuchAlgorithmException | KeyManagementException e) { - LOG.warn( - "Could not get list of enabled (JDK) cipher suites for protocol:{}, reverting to Netty's default ones.", - protocol); - } - return enabledCipherSuites; - } - - private String getTlsProtocol() { - return Arrays.stream(allowedProtocols).max(Comparator.naturalOrder()).orElse(null); - } - - public static TLSContextFactory buildFrom(final TLSConfiguration config) - throws GeneralSecurityException, IOException { - TLSContextFactory ret = null; - if (null != config) { - LOG.info("Initializing SSL Context using {} keystore.", config.getKeyStoreType()); - KeyStoreWrapper wrapper = - KeyStoreWrapper.KEYSTORE_TYPE_PKCS11.equalsIgnoreCase(config.getKeyStoreType()) - ? new HardwareKeyStoreWrapper( - config.getKeyStorePassword(), config.getKeyStorePath(), config.getCrlPath()) - : new SoftwareKeyStoreWrapper( - config.getKeyStoreType(), - config.getKeyStorePath(), - config.getKeyStorePassword(), - config.getTrustStoreType(), - config.getTrustStorePath(), - config.getTrustStorePassword(), - config.getCrlPath()); - ret = - TLSContextFactory.getInstance( - config.getKeyStorePassword(), wrapper, config.getAllowedProtocols()); - } - return ret; - } -} diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetworkTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetworkTest.java index 88b9197262a..327edbaf47c 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetworkTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetworkTest.java @@ -97,7 +97,7 @@ public void before() { lenient().when(discoveryAgent.checkForkId(any())).thenReturn(true); lenient() .when(discoveryAgent.start(anyInt())) - .thenReturn(CompletableFuture.completedFuture(Integer.valueOf(30301))); + .thenReturn(CompletableFuture.completedFuture(30301)); } @Test diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/P2PPlainNetworkTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/P2PPlainNetworkTest.java index d02cb1ff83f..5a5d40907d2 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/P2PPlainNetworkTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/network/P2PPlainNetworkTest.java @@ -16,8 +16,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Fail.fail; -import static org.hyperledger.besu.pki.keystore.KeyStoreWrapper.KEYSTORE_TYPE_PKCS12; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -39,10 +37,7 @@ import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions; import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissionsDenylist; import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.AbstractMessageData; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Message; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MockSubProtocol; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.ShouldConnectCallback; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; @@ -51,12 +46,8 @@ import org.hyperledger.besu.plugin.data.EnodeURL; import java.net.InetAddress; -import java.net.URISyntaxException; -import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; -import java.util.Objects; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -89,8 +80,8 @@ public void closeVertx() { @Test public void handshaking() throws Exception { final NodeKey nodeKey = NodeKeyUtils.generate(); - try (final P2PNetwork listener = builder("partner1client1").nodeKey(nodeKey).build(); - final P2PNetwork connector = builder("partner2client1").build()) { + try (final P2PNetwork listener = builder().nodeKey(nodeKey).build(); + final P2PNetwork connector = builder().build()) { listener.getRlpxAgent().subscribeConnectRequest(testCallback); connector.getRlpxAgent().subscribeConnectRequest(testCallback); @@ -113,8 +104,8 @@ public void handshaking() throws Exception { @Test public void preventMultipleConnections() throws Exception { final NodeKey listenNodeKey = NodeKeyUtils.generate(); - try (final P2PNetwork listener = builder("partner1client1").nodeKey(listenNodeKey).build(); - final P2PNetwork connector = builder("partner2client1").build()) { + try (final P2PNetwork listener = builder().nodeKey(listenNodeKey).build(); + final P2PNetwork connector = builder().build()) { listener.getRlpxAgent().subscribeConnectRequest(testCallback); connector.getRlpxAgent().subscribeConnectRequest(testCallback); @@ -155,10 +146,9 @@ public void limitMaxPeers() throws Exception { RlpxConfiguration.create() .setBindPort(0) .setSupportedProtocols(MockSubProtocol.create())); - try (final P2PNetwork listener = - builder("partner1client1").nodeKey(nodeKey).config(listenerConfig).build(); - final P2PNetwork connector1 = builder("partner1client1").build(); - final P2PNetwork connector2 = builder("partner2client1").build()) { + try (final P2PNetwork listener = builder().nodeKey(nodeKey).config(listenerConfig).build(); + final P2PNetwork connector1 = builder().build(); + final P2PNetwork connector2 = builder().build()) { listener.getRlpxAgent().subscribeConnectRequest(testCallback); connector1.getRlpxAgent().subscribeConnectRequest(testCallback); connector2.getRlpxAgent().subscribeConnectRequest((p, d) -> false); @@ -202,15 +192,9 @@ public void rejectPeerWithNoSharedCaps() throws Exception { final SubProtocol subprotocol2 = MockSubProtocol.create("oth"); final Capability cap2 = Capability.create(subprotocol2.getName(), 63); try (final P2PNetwork listener = - builder("partner1client1") - .nodeKey(listenerNodeKey) - .supportedCapabilities(cap1) - .build(); + builder().nodeKey(listenerNodeKey).supportedCapabilities(cap1).build(); final P2PNetwork connector = - builder("partner2client1") - .nodeKey(connectorNodeKey) - .supportedCapabilities(cap2) - .build()) { + builder().nodeKey(connectorNodeKey).supportedCapabilities(cap2).build()) { listener.getRlpxAgent().subscribeConnectRequest(testCallback); connector.getRlpxAgent().subscribeConnectRequest(testCallback); @@ -230,9 +214,8 @@ public void rejectPeerWithNoSharedCaps() throws Exception { public void rejectIncomingConnectionFromDenylistedPeer() throws Exception { final PeerPermissionsDenylist localDenylist = PeerPermissionsDenylist.create(); - try (final P2PNetwork localNetwork = - builder("partner1client1").peerPermissions(localDenylist).build(); - final P2PNetwork remoteNetwork = builder("partner2client1").build()) { + try (final P2PNetwork localNetwork = builder().peerPermissions(localDenylist).build(); + final P2PNetwork remoteNetwork = builder().build()) { localNetwork.getRlpxAgent().subscribeConnectRequest(testCallback); remoteNetwork.getRlpxAgent().subscribeConnectRequest(testCallback); @@ -280,9 +263,8 @@ public void rejectIncomingConnectionFromDisallowedPeer() throws Exception { final PeerPermissions peerPermissions = mock(PeerPermissions.class); when(peerPermissions.isPermitted(any(), any(), any())).thenReturn(true); - try (final P2PNetwork localNetwork = - builder("partner1client1").peerPermissions(peerPermissions).build(); - final P2PNetwork remoteNetwork = builder("partner2client1").build()) { + try (final P2PNetwork localNetwork = builder().peerPermissions(peerPermissions).build(); + final P2PNetwork remoteNetwork = builder().build()) { localNetwork.getRlpxAgent().subscribeConnectRequest(testCallback); remoteNetwork.getRlpxAgent().subscribeConnectRequest(testCallback); @@ -323,89 +305,8 @@ public void rejectIncomingConnectionFromDisallowedPeer() throws Exception { } } - @Test - public void p2pOverTlsCanHandleRecordFragmentation() throws Exception { - // Given - final int tlsRecordSize = 16 * 1024; - final int threeTlsRecords = 2 * tlsRecordSize + 1; - final LargeMessageData largeMessageData = - new LargeMessageData(Bytes.of(buildPaddedMessage(threeTlsRecords))); - - final NodeKey nodeKey = NodeKeyUtils.generate(); - try (final P2PNetwork listener = builder("partner1client1").nodeKey(nodeKey).build(); - final P2PNetwork connector = builder("partner2client1").build()) { - listener.getRlpxAgent().subscribeConnectRequest(testCallback); - connector.getRlpxAgent().subscribeConnectRequest(testCallback); - - final CompletableFuture disconnectReasonFuture = new CompletableFuture<>(); - listener.subscribeDisconnect( - (peerConnection, reason, initiatedByPeer) -> { - if (!DisconnectReason.CLIENT_QUITTING.equals( - reason)) { // client quitting is the valid end state - disconnectReasonFuture.complete(reason); - } - }); - final CompletableFuture successfulMessageFuture = new CompletableFuture<>(); - listener.subscribe( - Capability.create("eth", 63), - (capability, message) -> { - if (message.getData().getCode() == LargeMessageData.VALID_ETH_MESSAGE_CODE) { - successfulMessageFuture.complete(message); - } - }); - - listener.start(); - connector.start(); - - final EnodeURL listenerEnode = listener.getLocalEnode().get(); - final Bytes listenId = listenerEnode.getNodeId(); - final int listenPort = listenerEnode.getListeningPort().get(); - final PeerConnection peerConnection = - connector.connect(createPeer(listenId, listenPort)).get(30000L, TimeUnit.SECONDS); - - // When - peerConnection.sendForProtocol("eth", largeMessageData); - - // Then - CompletableFuture.anyOf(disconnectReasonFuture, successfulMessageFuture) - .thenAccept( - successOrFailure -> { - if (successOrFailure instanceof DisconnectReason) { - fail( - "listener disconnected due to " - + ((DisconnectReason) successOrFailure).name()); - } else { - final Message receivedMessage = (Message) successOrFailure; - assertThat(receivedMessage.getData().getData()) - .isEqualTo(largeMessageData.getData()); - } - }) - .get(30L, TimeUnit.SECONDS); - } - } - private final ShouldConnectCallback testCallback = (p, d) -> true; - private static class LargeMessageData extends AbstractMessageData { - - public static final int VALID_ETH_MESSAGE_CODE = 0x07; - - private LargeMessageData(final Bytes data) { - super(data); - } - - @Override - public int getCode() { - return VALID_ETH_MESSAGE_CODE; - } - } - - private byte[] buildPaddedMessage(final int messageSize) { - final byte[] bytes = new byte[messageSize]; - Arrays.fill(bytes, (byte) 9); - return bytes; - } - private Peer createPeer(final Bytes nodeId, final int listenPort) { return DefaultPeer.fromEnodeURL( EnodeURLImpl.builder() @@ -415,35 +316,7 @@ private Peer createPeer(final Bytes nodeId, final int listenPort) { .build()); } - private static Path toPath(final String path) { - try { - return Path.of(Objects.requireNonNull(P2PPlainNetworkTest.class.getResource(path)).toURI()); - } catch (final URISyntaxException e) { - throw new RuntimeException("Error converting to URI.", e); - } - } - - public Optional p2pTLSEnabled(final String clientDirName) { - final String parentPath = "/keys"; - final String keystorePath = parentPath + "/%s/client1.p12"; - final String truststorePath = parentPath + "/%s/truststore.p12"; - final String crl = parentPath + "/crl/crl.pem"; - final TLSConfiguration.Builder builder = TLSConfiguration.Builder.tlsConfiguration(); - builder - .withKeyStoreType(KEYSTORE_TYPE_PKCS12) - .withKeyStorePath(toPath(String.format(keystorePath, clientDirName))) - .withKeyStorePasswordSupplier(() -> "test123") - // .withKeyStorePasswordPath(toPath(String.format(nsspin, name))) - .withTrustStoreType(KEYSTORE_TYPE_PKCS12) - .withTrustStorePath(toPath(String.format(truststorePath, clientDirName))) - .withTrustStorePasswordSupplier(() -> "test123") - .withCrlPath(toPath(crl)) - .withClientHelloSniEnabled(false); - - return Optional.of(builder.build()); - } - - private DefaultP2PNetwork.Builder builder(final String clientDirName) { + private DefaultP2PNetwork.Builder builder() { final MutableBlockchain blockchainMock = mock(MutableBlockchain.class); final Block blockMock = mock(Block.class); when(blockMock.getHash()).thenReturn(Hash.ZERO); @@ -452,7 +325,6 @@ private DefaultP2PNetwork.Builder builder(final String clientDirName) { .vertx(vertx) .config(config) .nodeKey(NodeKeyUtils.generate()) - .p2pTLSConfiguration(p2pTLSEnabled(clientDirName)) .metricsSystem(new NoOpMetricsSystem()) .supportedCapabilities(Arrays.asList(Capability.create("eth", 63))) .storageProvider(new InMemoryKeyValueStorageProvider()) diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializerTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializerTest.java deleted file mode 100644 index ac39d81bb07..00000000000 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/NettyTLSConnectionInitializerTest.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright contributors to Hyperledger Besu. - * - * 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.ethereum.p2p.rlpx.connections.netty; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.cryptoservices.NodeKey; -import org.hyperledger.besu.ethereum.p2p.config.RlpxConfiguration; -import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerTable; -import org.hyperledger.besu.ethereum.p2p.peers.LocalNode; -import org.hyperledger.besu.ethereum.p2p.peers.Peer; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnectionEventDispatcher; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.data.EnodeURL; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import com.google.common.collect.ImmutableList; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import io.netty.handler.codec.LengthFieldPrepender; -import io.netty.handler.codec.compression.SnappyFrameDecoder; -import io.netty.handler.codec.compression.SnappyFrameEncoder; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslHandler; -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; - -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -public class NettyTLSConnectionInitializerTest { - - private static final String PEER_HOST = "hyperledger.org"; - private static final int PEER_PORT = 30303; - @Mock private NodeKey nodeKey; - @Mock private RlpxConfiguration rlpxConfiguration; - @Mock private LocalNode localNode; - @Mock private PeerConnectionEventDispatcher eventDispatcher; - @Mock private TLSContextFactory tlsContextFactory; - @Mock private SslContext clientSslContext; - @Mock private SslContext serverSslContext; - @Mock private SslHandler clientSslHandler; - @Mock private SslHandler serverSslHandler; - @Mock private Peer peer; - @Mock private EnodeURL enodeURL; - - private NettyTLSConnectionInitializer nettyTLSConnectionInitializer; - - @BeforeEach - public void before() throws Exception { - nettyTLSConnectionInitializer = createNettyTLSConnectionInitializer(false); - - when(tlsContextFactory.createNettyServerSslContext()).thenReturn(serverSslContext); - when(serverSslContext.newHandler(any())).thenReturn(serverSslHandler); - - when(tlsContextFactory.createNettyClientSslContext()).thenReturn(clientSslContext); - when(clientSslContext.newHandler(any())).thenReturn(clientSslHandler); - when(peer.getEnodeURL()).thenReturn(enodeURL); - when(enodeURL.getHost()).thenReturn(PEER_HOST); - when(enodeURL.getListeningPort()).thenReturn(Optional.of(PEER_PORT)); - } - - private NettyTLSConnectionInitializer createNettyTLSConnectionInitializer( - final boolean clientHelloSniHeaderEnabled) { - return new NettyTLSConnectionInitializer( - nodeKey, - rlpxConfiguration, - localNode, - eventDispatcher, - new NoOpMetricsSystem(), - () -> tlsContextFactory, - clientHelloSniHeaderEnabled, - new PeerTable(Bytes.random(64))); - } - - @Test - public void addAdditionalOutboundHandlersIncludesAllExpectedHandlersToChannelPipeline() - throws Exception { - final EmbeddedChannel embeddedChannel = new EmbeddedChannel(); - nettyTLSConnectionInitializer.addAdditionalOutboundHandlers(embeddedChannel, peer); - - // TLS - assertThat(embeddedChannel.pipeline().get(SslHandler.class)).isEqualTo(clientSslHandler); - - // Snappy compression - assertThat(embeddedChannel.pipeline().get(SnappyFrameDecoder.class)).isNotNull(); - assertThat(embeddedChannel.pipeline().get(SnappyFrameEncoder.class)).isNotNull(); - - // Message Framing - assertThat(embeddedChannel.pipeline().get(LengthFieldBasedFrameDecoder.class)).isNotNull(); - assertThat(embeddedChannel.pipeline().get(LengthFieldPrepender.class)).isNotNull(); - - assertHandlersOrderInPipeline(embeddedChannel.pipeline()); - } - - @Test - public void addAdditionalOutboundHandlersUsesSslHandlerWithSniHeaderEnabledIfConfigured() - throws Exception { - nettyTLSConnectionInitializer = createNettyTLSConnectionInitializer(true); - when(clientSslContext.newHandler(any(), eq(PEER_HOST), eq(PEER_PORT))) - .thenReturn(clientSslHandler); - - final EmbeddedChannel embeddedChannel = new EmbeddedChannel(); - nettyTLSConnectionInitializer.addAdditionalOutboundHandlers(embeddedChannel, peer); - - // Handler with SNI params was created - verify(clientSslContext).newHandler(any(), eq(PEER_HOST), eq(PEER_PORT)); - - // Other handlers are still present as expected - assertHandlersOrderInPipeline(embeddedChannel.pipeline()); - } - - @Test - public void addAdditionalInboundHandlersIncludesAllExpectedHandlersToChannelPipeline() - throws Exception { - final EmbeddedChannel embeddedChannel = new EmbeddedChannel(); - nettyTLSConnectionInitializer.addAdditionalInboundHandlers(embeddedChannel); - - // TLS - assertThat(embeddedChannel.pipeline().get(SslHandler.class)).isEqualTo(serverSslHandler); - - // Snappy compression - assertThat(embeddedChannel.pipeline().get(SnappyFrameDecoder.class)).isNotNull(); - assertThat(embeddedChannel.pipeline().get(SnappyFrameEncoder.class)).isNotNull(); - - // Message Framing - assertThat(embeddedChannel.pipeline().get(LengthFieldBasedFrameDecoder.class)).isNotNull(); - assertThat(embeddedChannel.pipeline().get(LengthFieldPrepender.class)).isNotNull(); - - assertHandlersOrderInPipeline(embeddedChannel.pipeline()); - } - - private void assertHandlersOrderInPipeline(final ChannelPipeline pipeline) { - // Appending '#0' because Netty adds it to the handler's names - final ArrayList expectedHandlerNamesInOrder = - new ArrayList<>( - ImmutableList.of( - "SslHandler#0", - "SnappyFrameDecoder#0", - "SnappyFrameEncoder#0", - "LengthFieldBasedFrameDecoder#0", - "LengthFieldPrepender#0", - "DefaultChannelPipeline$TailContext#0")); // This final handler is Netty's default - - final List actualHandlerNamesInOrder = pipeline.names(); - assertThat(actualHandlerNamesInOrder).isEqualTo(expectedHandlerNamesInOrder); - } - - @Test - public void defaultTlsContextFactorySupplierThrowsErrorWithNullTLSConfiguration() { - assertThatThrownBy(() -> NettyTLSConnectionInitializer.defaultTlsContextFactorySupplier(null)) - .isInstanceOf(IllegalStateException.class) - .hasMessage("TLSConfiguration cannot be null when using TLS"); - } - - @Test - public void defaultTlsContextFactorySupplierCapturesInternalError() { - final TLSConfiguration tlsConfiguration = mock(TLSConfiguration.class); - when(tlsConfiguration.getKeyStoreType()).thenThrow(new RuntimeException()); - - assertThatThrownBy( - () -> - NettyTLSConnectionInitializer.defaultTlsContextFactorySupplier(tlsConfiguration) - .get()) - .isInstanceOf(IllegalStateException.class) - .hasMessage("Error creating TLSContextFactory"); - } -} diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java deleted file mode 100644 index d7763892c5d..00000000000 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/rlpx/connections/netty/TLSContextFactoryTest.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * 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.ethereum.p2p.rlpx.connections.netty; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.pki.keystore.KeyStoreWrapper.KEYSTORE_TYPE_PKCS12; - -import org.hyperledger.besu.pki.PkiException; -import org.hyperledger.besu.pki.keystore.HardwareKeyStoreWrapper; -import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; -import org.hyperledger.besu.pki.keystore.SoftwareKeyStoreWrapper; - -import java.net.InetSocketAddress; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslHandler; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.DisabledOnOs; -import org.junit.jupiter.api.condition.OS; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class TLSContextFactoryTest { - - // see resources/keys/README.md for setup details. - private static final String keystorePassword = "test123"; - - private static final Logger LOG = LoggerFactory.getLogger(TLSContextFactoryTest.class); - - private static final int MAX_NUMBER_MESSAGES = 10; - private static final String CRL_PEM = "/keys/crl/crl.pem"; - private static final String PARTNER1_CLIENT1_PKCS11 = "/keys/partner1client1/nss.cfg"; - private static final String PARTNER1_CLIENT1_KEYSTORE = "/keys/partner1client1/client1.p12"; - private static final String PARTNET1_CLIENT2_KEYSTORE = "/keys/partner1client2rvk/client2.p12"; - private static final String PARTNER2_CLIENT1_KEYSTORE = "/keys/partner2client1/client1.p12"; - private static final String PARTNER2_CLIENT2_KEYSTORE = "/keys/partner2client2rvk/client2.p12"; - private static final String INVALIDPARTNER1_CLIENT1_KEYSTORE = - "/keys/invalidpartner1client1/client1.p12"; - - private static final String PARTNER1_CLIENT1_TRUSTSTORE = "/keys/partner1client1/truststore.p12"; - private static final String PARTNET1_CLIENT2_TRUSTSTORE = - "/keys/partner1client2rvk/truststore.p12"; - private static final String PARTNER2_CLIENT1_TRUSTSTORE = "/keys/partner2client1/truststore.p12"; - private static final String PARTNER2_CLIENT2_TRUSTSTORE = - "/keys/partner2client2rvk/truststore.p12"; - private static final String INVALIDPARTNER1_CLIENT1_TRUSTSTORE = - "/keys/invalidpartner1client1/truststore.p12"; - - private Server server; - private Client client; - - static Collection hardwareKeysData() { - return Arrays.asList( - new Object[][] { - { - "PKCS11 server Partner1 Client1 -> PKCS12 client Partner2 Client1 SuccessfulConnection", - true, - getHardwareKeyStoreWrapper(PARTNER1_CLIENT1_PKCS11, CRL_PEM), - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT1_KEYSTORE, PARTNER2_CLIENT1_TRUSTSTORE, CRL_PEM), - Optional.empty(), - Optional.empty() - }, - { - "PKCS11 server Partner1 Client1 -> PKCS12 client InvalidPartner1 Client1 FailedConnection", - false, - getHardwareKeyStoreWrapper(PARTNER1_CLIENT1_PKCS11, CRL_PEM), - getSoftwareKeyStoreWrapper( - INVALIDPARTNER1_CLIENT1_KEYSTORE, INVALIDPARTNER1_CLIENT1_TRUSTSTORE, null), - Optional.empty(), - Optional.of("certificate_unknown") - }, - { - "PKCS11 server Partner1 Client1 -> PKCS12 client Partner2 Client2 revoked FailedConnection", - false, - getHardwareKeyStoreWrapper(PARTNER1_CLIENT1_PKCS11, CRL_PEM), - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT2_KEYSTORE, PARTNER2_CLIENT2_TRUSTSTORE, null), - Optional.of("Certificate revoked"), - Optional.of("certificate_unknown") - }, - }); - } - - static Collection softwareKeysData() { - return Arrays.asList( - new Object[][] { - { - "PKCS12 server Partner1 Client1 -> PKCS12 client Partner2 Client1 SuccessfulConnection", - true, - getSoftwareKeyStoreWrapper( - PARTNER1_CLIENT1_KEYSTORE, PARTNER1_CLIENT1_TRUSTSTORE, CRL_PEM), - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT1_KEYSTORE, PARTNER2_CLIENT1_TRUSTSTORE, CRL_PEM), - Optional.empty(), - Optional.empty() - }, - { - "PKCS12 server Partner2 Client1 -> PKCS12 client Partner1 Client1 SuccessfulConnection", - true, - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT1_KEYSTORE, PARTNER2_CLIENT1_TRUSTSTORE, CRL_PEM), - getSoftwareKeyStoreWrapper( - PARTNER1_CLIENT1_KEYSTORE, PARTNER1_CLIENT1_TRUSTSTORE, CRL_PEM), - Optional.empty(), - Optional.empty() - }, - { - "PKCS12 server Partner1 Client1 -> PKCS12 client InvalidPartner1 Client1 FailedConnection", - false, - getSoftwareKeyStoreWrapper( - PARTNER1_CLIENT1_KEYSTORE, PARTNER1_CLIENT1_TRUSTSTORE, CRL_PEM), - getSoftwareKeyStoreWrapper( - INVALIDPARTNER1_CLIENT1_KEYSTORE, INVALIDPARTNER1_CLIENT1_TRUSTSTORE, null), - Optional.empty(), - Optional.of("certificate_unknown") - }, - { - "PKCS12 server InvalidPartner1 Client1 -> PKCS12 client Partner1 Client1 FailedConnection", - false, - getSoftwareKeyStoreWrapper( - INVALIDPARTNER1_CLIENT1_KEYSTORE, INVALIDPARTNER1_CLIENT1_TRUSTSTORE, null), - getSoftwareKeyStoreWrapper( - PARTNER1_CLIENT1_KEYSTORE, PARTNER1_CLIENT1_TRUSTSTORE, CRL_PEM), - Optional.of("certificate_unknown"), - Optional.empty() - }, - { - "PKCS12 server Partner1 Client2 (revoked) -> PKCS12 client Partner2 Client1 FailedConnection", - false, - getSoftwareKeyStoreWrapper( - PARTNET1_CLIENT2_KEYSTORE, PARTNET1_CLIENT2_TRUSTSTORE, null), - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT1_KEYSTORE, PARTNER2_CLIENT1_TRUSTSTORE, CRL_PEM), - Optional.empty(), - Optional.of("Certificate revoked") - }, - { - "PKCS12 server Partner2 Client1 -> PKCS12 client Partner1 Client2 (revoked) FailedConnection", - false, - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT1_KEYSTORE, PARTNER2_CLIENT1_TRUSTSTORE, CRL_PEM), - getSoftwareKeyStoreWrapper( - PARTNET1_CLIENT2_KEYSTORE, PARTNET1_CLIENT2_TRUSTSTORE, null), - Optional.of("Certificate revoked"), - Optional.of("certificate_unknown") - }, - { - "PKCS12 server Partner2 Client2 (revoked) -> PKCS12 client Partner1 Client1 FailedConnection", - false, - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT2_KEYSTORE, PARTNER2_CLIENT2_TRUSTSTORE, null), - getSoftwareKeyStoreWrapper( - PARTNER1_CLIENT1_KEYSTORE, PARTNER1_CLIENT1_TRUSTSTORE, CRL_PEM), - Optional.empty(), - Optional.of("Certificate revoked"), - }, - { - "PKCS12 server Partner1 Client1 -> PKCS12 client Partner2 Client2 (revoked) FailedConnection", - false, - getSoftwareKeyStoreWrapper( - PARTNER1_CLIENT1_KEYSTORE, PARTNER1_CLIENT1_TRUSTSTORE, CRL_PEM), - getSoftwareKeyStoreWrapper( - PARTNER2_CLIENT2_KEYSTORE, PARTNER2_CLIENT2_TRUSTSTORE, null), - Optional.of("Certificate revoked"), - Optional.of("certificate_unknown") - } - }); - } - - @BeforeEach - void init() {} - - @AfterEach - void tearDown() { - if (client != null) { - client.stop(); - } - if (server != null) { - server.stop(); - } - } - - private static Path toPath(final String path) throws Exception { - return null == path ? null : Path.of(TLSContextFactoryTest.class.getResource(path).toURI()); - } - - private static KeyStoreWrapper getHardwareKeyStoreWrapper( - final String config, final String crlLocation) { - try { - return new HardwareKeyStoreWrapper(keystorePassword, toPath(config), toPath(crlLocation)); - } catch (final Exception e) { - // Not a mac, probably a production build. Full failure. - throw new PkiException("Failed to initialize hardware keystore", e); - } - } - - private static KeyStoreWrapper getSoftwareKeyStoreWrapper( - final String jksKeyStore, final String trustStore, final String crl) { - try { - return new SoftwareKeyStoreWrapper( - KEYSTORE_TYPE_PKCS12, - toPath(jksKeyStore), - keystorePassword, - KEYSTORE_TYPE_PKCS12, - toPath(trustStore), - keystorePassword, - toPath(crl)); - } catch (final Exception e) { - throw new PkiException("Failed to initialize software keystore", e); - } - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("softwareKeysData") - @DisabledOnOs(OS.MAC) - void testConnectionSoftwareKeys( - final String ignoredTestDescription, - final boolean testSuccess, - final KeyStoreWrapper serverKeyStoreWrapper, - final KeyStoreWrapper clientKeyStoreWrapper, - final Optional serverFailureMessage, - final Optional clientFailureMessage) - throws Exception { - testConnection( - testSuccess, - serverKeyStoreWrapper, - clientKeyStoreWrapper, - serverFailureMessage, - clientFailureMessage); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("hardwareKeysData") - @DisabledOnOs(OS.MAC) - void testConnectionHardwareKeys( - final String ignoredTestDescription, - final boolean testSuccess, - final KeyStoreWrapper serverKeyStoreWrapper, - final KeyStoreWrapper clientKeyStoreWrapper, - final Optional serverFailureMessage, - final Optional clientFailureMessage) - throws Exception { - testConnection( - testSuccess, - serverKeyStoreWrapper, - clientKeyStoreWrapper, - serverFailureMessage, - clientFailureMessage); - } - - private void testConnection( - final boolean testSuccess, - final KeyStoreWrapper serverKeyStoreWrapper, - final KeyStoreWrapper clientKeyStoreWrapper, - final Optional serverFailureMessage, - final Optional clientFailureMessage) - throws Exception { - final CountDownLatch serverLatch = new CountDownLatch(MAX_NUMBER_MESSAGES); - final CountDownLatch clientLatch = new CountDownLatch(MAX_NUMBER_MESSAGES); - server = startServer(serverKeyStoreWrapper, serverLatch); - client = startClient(server.port, clientKeyStoreWrapper, clientLatch); - - if (testSuccess) { - client.getChannelFuture().channel().writeAndFlush(Unpooled.copyInt(0)); - final boolean allMessagesServerExchanged = serverLatch.await(10, TimeUnit.SECONDS); - final boolean allMessagesClientExchanged = clientLatch.await(10, TimeUnit.SECONDS); - assertThat(allMessagesClientExchanged && allMessagesServerExchanged).isTrue(); - } else { - try { - client.getChannelFuture().channel().writeAndFlush(Unpooled.copyInt(0)).sync(); - serverLatch.await(2, TimeUnit.SECONDS); - assertThat(client.getChannelFuture().channel().isActive()).isFalse(); - - if (serverFailureMessage.isPresent()) { - assertThat(server.getCause()).isNotEmpty(); - assertThat(server.getCause().get()).hasMessageContaining(serverFailureMessage.get()); - } else { - assertThat(server.getCause()).isEmpty(); - } - - if (clientFailureMessage.isPresent()) { - assertThat(client.getCause()).isNotEmpty(); - assertThat(client.getCause().get()).hasMessageContaining(clientFailureMessage.get()); - } else { - assertThat(client.getCause()).isEmpty(); - } - } catch (final Exception e) { - // NOOP - } - } - } - - private Server startServer(final KeyStoreWrapper keyStoreWrapper, final CountDownLatch latch) - throws Exception { - - final Server nettyServer = new Server(keystorePassword, keyStoreWrapper, latch); - nettyServer.start(); - return nettyServer; - } - - private Client startClient( - final int port, final KeyStoreWrapper keyStoreWrapper, final CountDownLatch latch) - throws Exception { - - final Client nettyClient = new Client(port, keystorePassword, keyStoreWrapper, latch); - nettyClient.start(); - return nettyClient; - } - - static class MessageHandler extends ChannelInboundHandlerAdapter { - private final String id; - private final CountDownLatch latch; - - private Throwable cause; - - MessageHandler(final String id, final CountDownLatch latch) { - this.id = id; - this.latch = latch; - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, final Object msg) - throws InterruptedException { - final int message = ((ByteBuf) msg).readInt(); - LOG.info("[" + id + "] Received message: " + message); - - if (message < 2 * MAX_NUMBER_MESSAGES) { - final int replyMessage = message + 1; - ctx.writeAndFlush(Unpooled.copyInt(replyMessage)).sync(); - LOG.info("[" + id + "] Sent message: " + replyMessage); - this.latch.countDown(); - LOG.info("Remaining {}", this.latch.getCount()); - } - } - - @Override - public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) - throws Exception { - this.cause = cause; - } - - public Optional getCause() { - return Optional.ofNullable(cause); - } - } - - static class Client { - int port; - private final String keystorePassword; - private final KeyStoreWrapper keyStoreWrapper; - private final CountDownLatch latch; - - private ChannelFuture channelFuture; - private final EventLoopGroup group = new NioEventLoopGroup(); - private MessageHandler messageHandler; - - ChannelFuture getChannelFuture() { - return channelFuture; - } - - Client( - final int port, - final String keystorePassword, - final KeyStoreWrapper keyStoreWrapper, - final CountDownLatch latch) { - this.port = port; - this.keystorePassword = keystorePassword; - this.keyStoreWrapper = keyStoreWrapper; - this.latch = latch; - } - - void start() throws Exception { - final Bootstrap b = new Bootstrap(); - b.group(group); - b.channel(NioSocketChannel.class); - b.handler( - new ChannelInitializer() { - @Override - protected void initChannel(final SocketChannel socketChannel) throws Exception { - final SslContext sslContext = - TLSContextFactory.getInstance(keystorePassword, keyStoreWrapper) - .createNettyClientSslContext(); - - final SslHandler sslHandler = sslContext.newHandler(socketChannel.alloc()); - socketChannel.pipeline().addFirst("ssl", sslHandler); - messageHandler = new MessageHandler("Client", latch); - socketChannel.pipeline().addLast(messageHandler); - } - }); - - this.channelFuture = b.connect("127.0.0.1", this.port).sync(); - } - - void stop() { - group.shutdownGracefully(); - messageHandler = null; - } - - Optional getCause() { - return messageHandler != null ? messageHandler.getCause() : Optional.empty(); - } - } - - static class Server { - private int port; - private final String keystorePassword; - private final KeyStoreWrapper keyStoreWrapper; - private final CountDownLatch latch; - - private Channel channel; - - private final EventLoopGroup parentGroup = new NioEventLoopGroup(); - private final EventLoopGroup childGroup = new NioEventLoopGroup(); - - private MessageHandler messageHandler; - - Server( - final String keystorePassword, - final KeyStoreWrapper keyStoreWrapper, - final CountDownLatch latch) { - this.keystorePassword = keystorePassword; - this.keyStoreWrapper = keyStoreWrapper; - this.latch = latch; - } - - void start() throws Exception { - final ServerBootstrap sb = new ServerBootstrap(); - sb.group(parentGroup, childGroup) - .channel(NioServerSocketChannel.class) - .childHandler( - new ChannelInitializer() { - @Override - public void initChannel(final SocketChannel socketChannel) throws Exception { - final SslContext sslContext = - TLSContextFactory.getInstance(keystorePassword, keyStoreWrapper) - .createNettyServerSslContext(); - final SslHandler sslHandler = sslContext.newHandler(channel.alloc()); - socketChannel.pipeline().addFirst("ssl", sslHandler); - - socketChannel - .pipeline() - .addLast(messageHandler = new MessageHandler("Server", latch)); - } - }); - - final ChannelFuture cf = sb.bind(0).sync(); - this.channel = cf.channel(); - this.port = ((InetSocketAddress) channel.localAddress()).getPort(); - } - - void stop() { - childGroup.shutdownGracefully(); - parentGroup.shutdownGracefully(); - } - - Optional getCause() { - return messageHandler != null ? messageHandler.getCause() : Optional.empty(); - } - } - - @Test - void dryRunDetector() { - assertThat(true) - .withFailMessage("This test is here so gradle --dry-run executes this class") - .isTrue(); - } -} From 6d089b28f8088549e704c4ab46672b4d7a741ca1 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 27 Nov 2024 16:08:12 +1000 Subject: [PATCH 4/5] changelog Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86c382701a3..bc54ec859fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Breaking Changes - Removed Retesteth rpc service and commands [#7833](https://github.com/hyperledger/besu/pull/7783) -- TLS for P2P (early access feature) has been removed []() +- TLS for P2P (early access feature) has been removed [#7942](https://github.com/hyperledger/besu/pull/7942) ### Upcoming Breaking Changes - Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. From 44bfd574d6ee62f1fcae6182d59562814712e9d2 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 28 Nov 2024 06:54:28 +1000 Subject: [PATCH 5/5] removed references to pki module Signed-off-by: Sally MacFarlane --- besu/build.gradle | 1 - ethereum/p2p/build.gradle | 1 - settings.gradle | 1 - 3 files changed, 3 deletions(-) diff --git a/besu/build.gradle b/besu/build.gradle index b6e506d9c14..01b0b4bead7 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -34,7 +34,6 @@ dependencies { api 'org.slf4j:slf4j-api' implementation project(':config') - implementation project(':pki') implementation project(':consensus:clique') implementation project(':consensus:common') implementation project(':consensus:ibft') diff --git a/ethereum/p2p/build.gradle b/ethereum/p2p/build.gradle index 7cfcf2f8d58..6ed42425e0a 100644 --- a/ethereum/p2p/build.gradle +++ b/ethereum/p2p/build.gradle @@ -35,7 +35,6 @@ dependencies { implementation project(':datatypes') implementation project(':ethereum:core') implementation project(':ethereum:rlp') - implementation project(':pki') implementation project(':metrics:core') implementation project(':nat') implementation project(':util') diff --git a/settings.gradle b/settings.gradle index 83363f70e49..761449b6ca1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -60,7 +60,6 @@ include 'evm' include 'metrics:core' include 'metrics:rocksdb' include 'nat' -include 'pki' include 'platform' include 'plugin-api' include 'plugins:rocksdb'