summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--certServiceClient/pom.xml10
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java22
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java4
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java8
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java51
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java55
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java35
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java73
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java42
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java133
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java47
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java34
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java39
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java35
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java (renamed from certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Coder.java)9
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java2
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java5
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java2
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java66
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java80
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java111
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java197
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java32
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java41
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java129
-rw-r--r--certServiceClient/src/test/resources/cert1.pem21
-rw-r--r--certServiceClient/src/test/resources/cert2.pem22
-rw-r--r--certServiceClient/src/test/resources/expectedKeystore.jksbin0 -> 3823 bytes
-rw-r--r--certServiceClient/src/test/resources/expectedTruststore.jksbin0 -> 2306 bytes
-rw-r--r--certServiceClient/src/test/resources/privateKeybin0 -> 1217 bytes
-rw-r--r--certServiceClient/src/test/resources/rsaPrivateKeyPem28
-rw-r--r--pom.xml14
32 files changed, 1286 insertions, 61 deletions
diff --git a/certServiceClient/pom.xml b/certServiceClient/pom.xml
index 9e828839..4b7c0cf9 100644
--- a/certServiceClient/pom.xml
+++ b/certServiceClient/pom.xml
@@ -146,16 +146,16 @@
<artifactId>bcpkix-jdk15on</artifactId>
</dependency>
<dependency>
- <groupId>org.assertj</groupId>
- <artifactId>assertj-core</artifactId>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-engine</artifactId>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
+ <artifactId>junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java
index 59d0c032..d3d7f26d 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java
@@ -19,9 +19,14 @@
package org.onap.aaf.certservice.client;
+import java.security.KeyPair;
import org.onap.aaf.certservice.client.api.ExitableException;
+import org.onap.aaf.certservice.client.certification.PrivateKeyToPemEncoder;
import org.onap.aaf.certservice.client.certification.CsrFactory;
import org.onap.aaf.certservice.client.certification.KeyPairFactory;
+import org.onap.aaf.certservice.client.certification.conversion.KeystoreTruststoreCreator;
+import org.onap.aaf.certservice.client.certification.conversion.KeystoreTruststoreCreatorFactory;
+import org.onap.aaf.certservice.client.common.Base64Encoder;
import org.onap.aaf.certservice.client.configuration.EnvsForClient;
import org.onap.aaf.certservice.client.configuration.EnvsForCsr;
import org.onap.aaf.certservice.client.configuration.factory.ClientConfigurationFactory;
@@ -32,14 +37,12 @@ import org.onap.aaf.certservice.client.httpclient.CloseableHttpClientProvider;
import org.onap.aaf.certservice.client.httpclient.HttpClient;
import org.onap.aaf.certservice.client.httpclient.model.CertServiceResponse;
-import java.security.KeyPair;
-
import static org.onap.aaf.certservice.client.api.ExitCode.SUCCESS_EXIT_CODE;
import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.KEY_SIZE;
import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.RSA_ENCRYPTION_ALGORITHM;
-import static org.onap.aaf.certservice.client.common.Base64Coder.encode;
public class CertServiceClient {
+
private AppExitHandler appExitHandler;
public CertServiceClient(AppExitHandler appExitHandler) {
@@ -48,21 +51,28 @@ public class CertServiceClient {
public void run() {
KeyPairFactory keyPairFactory = new KeyPairFactory(RSA_ENCRYPTION_ALGORITHM, KEY_SIZE);
+ PrivateKeyToPemEncoder pkEncoder = new PrivateKeyToPemEncoder();
+ Base64Encoder base64Encoder = new Base64Encoder();
try {
ClientConfiguration clientConfiguration = new ClientConfigurationFactory(new EnvsForClient()).create();
CsrConfiguration csrConfiguration = new CsrConfigurationFactory(new EnvsForCsr()).create();
KeyPair keyPair = keyPairFactory.create();
CsrFactory csrFactory = new CsrFactory(csrConfiguration);
- CloseableHttpClientProvider provider = new CloseableHttpClientProvider(clientConfiguration.getRequestTimeout());
+ CloseableHttpClientProvider provider = new CloseableHttpClientProvider(
+ clientConfiguration.getRequestTimeout());
HttpClient httpClient = new HttpClient(provider, clientConfiguration.getUrlToCertService());
CertServiceResponse certServiceData =
httpClient.retrieveCertServiceData(
clientConfiguration.getCaName(),
- csrFactory.createEncodedCsr(keyPair),
- encode(keyPair.getPrivate().toString()));
+ base64Encoder.encode(csrFactory.createCsrInPem(keyPair)),
+ base64Encoder.encode(pkEncoder.encodePrivateKeyToPem(keyPair.getPrivate())));
+ KeystoreTruststoreCreator filesCreator = new KeystoreTruststoreCreatorFactory(
+ clientConfiguration.getCertsOutputPath()).create();
+ filesCreator.createKeystore(certServiceData.getCertificateChain(), keyPair.getPrivate());
+ filesCreator.createTruststore(certServiceData.getTrustedCertificates());
} catch (ExitableException e) {
appExitHandler.exit(e.applicationExitCode());
}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java
index b72a0e2d..670cbe90 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java
@@ -25,7 +25,9 @@ public enum ExitCode {
KEY_PAIR_GENERATION_EXCEPTION(3),
CSR_GENERATION_EXCEPTION(4),
CERT_SERVICE_API_CONNECTION_EXCEPTION(5),
- HTTP_CLIENT_EXCEPTION(6);
+ HTTP_CLIENT_EXCEPTION(6),
+ PKCS12_CONVERSION_EXCEPTION(7),
+ PK_TO_PEM_ENCODING_EXCEPTION(8);
private final int value;
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java
index f936636a..83fa6d44 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java
@@ -66,12 +66,12 @@ public class CsrFactory {
}
- public String createEncodedCsr(KeyPair keyPair) throws CsrGenerationException {
+ public String createCsrInPem(KeyPair keyPair) throws CsrGenerationException {
PKCS10CertificationRequest request;
String csrParameters = getMandatoryParameters().append(getOptionalParameters()).toString();
X500Principal subject = new X500Principal(csrParameters);
request = createPKCS10Csr(subject, keyPair);
- return encodeToBase64(convertPKC10CsrToPem(request));
+ return convertPKC10CsrToPem(request);
}
@@ -151,8 +151,4 @@ public class CsrFactory {
private static Boolean isParameterPresent(String parameter) {
return parameter != null && !"".equals(parameter);
}
-
- private static String encodeToBase64(String csrInPem) {
- return Base64.getEncoder().encodeToString(csrInPem.getBytes(StandardCharsets.UTF_8));
- }
}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java
new file mode 100644
index 00000000..77995958
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification;
+
+
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.security.PrivateKey;
+
+import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
+import org.bouncycastle.util.io.pem.PemObject;
+import org.onap.aaf.certservice.client.certification.exception.PkEncodingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PrivateKeyToPemEncoder {
+
+ public static final String PEM_OBJECT_TYPE = "RSA PRIVATE KEY";
+ private final Logger LOGGER = LoggerFactory.getLogger(PrivateKeyToPemEncoder.class);
+
+ public String encodePrivateKeyToPem(PrivateKey pk) throws PkEncodingException {
+ LOGGER.info("Encoding PrivateKey to PEM");
+ StringWriter stringWriter = new StringWriter();
+ try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) {
+ pemWriter.writeObject(new PemObject(PEM_OBJECT_TYPE, pk.getEncoded()));
+ } catch (IOException e) {
+ LOGGER.error("Exception occurred during encoding PrivateKey to PEM", e);
+ throw new PkEncodingException(e);
+ }
+ return stringWriter.toString();
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java
new file mode 100644
index 00000000..6dc2ef87
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java
@@ -0,0 +1,55 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import java.security.PrivateKey;
+import java.util.List;
+import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException;
+
+public class KeystoreTruststoreCreator {
+
+ private static final String CERTIFICATE_ALIAS = "certificate";
+ private static final String TRUSTED_CERTIFICATE_ALIAS = "trusted-certificate-";
+ private static final int PASSWORD_LENGTH = 24;
+ private final RandomPasswordGenerator generator;
+ private final PemToPKCS12Converter converter;
+ private final PKCS12FilesCreator creator;
+
+ public KeystoreTruststoreCreator(PKCS12FilesCreator creator, RandomPasswordGenerator generator,
+ PemToPKCS12Converter converter) {
+ this.generator = generator;
+ this.converter = converter;
+ this.creator = creator;
+ }
+
+ public void createKeystore(List<String> data, PrivateKey privateKey)
+ throws PemToPKCS12ConverterException {
+ Password password = generator.generate(PASSWORD_LENGTH);
+ creator.saveKeystoreData(converter.convertKeystore(data, password, CERTIFICATE_ALIAS, privateKey),
+ password.getPassword());
+ }
+
+ public void createTruststore(List<String> data)
+ throws PemToPKCS12ConverterException {
+ Password password = generator.generate(PASSWORD_LENGTH);
+ creator.saveTruststoreData(converter.convertTruststore(data, password, TRUSTED_CERTIFICATE_ALIAS),
+ password.getPassword());
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java
new file mode 100644
index 00000000..8c719535
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java
@@ -0,0 +1,35 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+public class KeystoreTruststoreCreatorFactory {
+ private final String outputPath;
+
+ public KeystoreTruststoreCreatorFactory(String outputPath) {
+ this.outputPath = outputPath;
+ }
+
+ public KeystoreTruststoreCreator create() {
+ return new KeystoreTruststoreCreator(
+ new PKCS12FilesCreator(outputPath),
+ new RandomPasswordGenerator(),
+ new PemToPKCS12Converter());
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java
new file mode 100644
index 00000000..d8c41bfd
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java
@@ -0,0 +1,73 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class PKCS12FilesCreator {
+
+ private static final String KEYSTORE_JKS = "keystore.jks";
+ private static final String KEYSTORE_PASS = "keystore.pass";
+ private static final String TRUSTSTORE_JKS = "truststore.jks";
+ private static final String TRUSTSTORE_PASS = "truststore.pass";
+ private final String keystoreJksPath;
+ private final String keystorePassPath;
+ private final String truststoreJksPath;
+ private final String truststorePassPath;
+ private final Logger LOGGER = LoggerFactory.getLogger(PKCS12FilesCreator.class);
+
+
+ PKCS12FilesCreator(String path) {
+ keystoreJksPath = Path.of(path, KEYSTORE_JKS).toString();
+ keystorePassPath = Path.of(path, KEYSTORE_PASS).toString();
+ truststoreJksPath = Path.of(path, TRUSTSTORE_JKS).toString();
+ truststorePassPath = Path.of(path, TRUSTSTORE_PASS).toString();
+ }
+
+ void saveKeystoreData(byte[] keystoreData, String keystorePassword) throws PemToPKCS12ConverterException {
+ LOGGER.debug("Creating PKCS12 keystore files and saving data. Keystore path: {}", keystoreJksPath);
+
+ saveDataToLocation(keystoreData, keystoreJksPath);
+ saveDataToLocation(keystorePassword.getBytes(), keystorePassPath);
+ }
+
+ void saveTruststoreData(byte[] truststoreData, String truststorePassword)
+ throws PemToPKCS12ConverterException {
+ LOGGER.debug("Creating PKCS12 truststore files and saving data. Truststore path: {}", truststoreJksPath);
+
+ saveDataToLocation(truststoreData, truststoreJksPath);
+ saveDataToLocation(truststorePassword.getBytes(), truststorePassPath);
+ }
+
+ private void saveDataToLocation(byte[] data, String path) throws PemToPKCS12ConverterException {
+ try (FileOutputStream fos = new FileOutputStream(path)) {
+ fos.write(data);
+ } catch (IOException e) {
+ LOGGER.error("PKCS12 files creation failed", e);
+ throw new PemToPKCS12ConverterException(e);
+ }
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java
new file mode 100644
index 00000000..f0ee419c
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java
@@ -0,0 +1,42 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+class Password {
+ private final static String PASSWORD_PATTERN = "[\\w$#]{16,}";
+ private final String password;
+
+ Password(String password) {
+ this.password = password;
+ }
+
+ String getPassword() {
+ return password;
+ }
+
+ char[] toCharArray() {
+ return password.toCharArray();
+ }
+
+ boolean isCorrectPasswordPattern() {
+ return password.matches(PASSWORD_PATTERN);
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java
new file mode 100644
index 00000000..eab9bf7c
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java
@@ -0,0 +1,133 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.security.KeyStore;
+import java.security.KeyStore.LoadStoreParameter;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.List;
+import java.util.Optional;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.PEMParser;
+import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class PemToPKCS12Converter {
+
+ private final static String PKCS12 = "PKCS12";
+ private final static String PASSWORD_ERROR_MSG = "Password should be min. 16 chars long and should contain only alphanumeric characters and special characters like Underscore (_), Dollar ($) and Pound (#)";
+ private final LoadStoreParameter EMPTY_KEYSTORE_CONFIGURATION = null;
+ private final Logger LOGGER = LoggerFactory.getLogger(PemToPKCS12Converter.class);
+
+ byte[] convertKeystore(List<String> certificateChain, Password password, String alias, PrivateKey privateKey)
+ throws PemToPKCS12ConverterException {
+ LOGGER.debug("Converting PEM certificates to PKCS12 keystore.");
+ return convert(certificateChain, password, certs -> getKeyStore(alias, password, certs, privateKey));
+ }
+
+ byte[] convertTruststore(List<String> trustAnchors, Password password, String alias)
+ throws PemToPKCS12ConverterException {
+ LOGGER.debug("Converting PEM certificates to PKCS12 truststore.");
+ return convert(trustAnchors, password, certs -> getTrustStore(alias, certs));
+ }
+
+ private byte[] convert(List<String> certificates, Password password, StoreEntryOperation operation)
+ throws PemToPKCS12ConverterException {
+ checkPassword(password);
+ final Certificate[] X509Certificates = convertToCertificateArray(certificates);
+ return getKeyStoreBytes(password, operation, X509Certificates);
+ }
+
+ private void checkPassword(Password password) throws PemToPKCS12ConverterException {
+ if (!password.isCorrectPasswordPattern()) {
+ LOGGER.error(PASSWORD_ERROR_MSG);
+ throw new PemToPKCS12ConverterException(PASSWORD_ERROR_MSG);
+ }
+ }
+
+ private byte[] getKeyStoreBytes(Password password, StoreEntryOperation op, Certificate[] x509Certificates)
+ throws PemToPKCS12ConverterException {
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+ KeyStore ks = op.getStore(x509Certificates);
+ ks.store(bos, password.toCharArray());
+ return bos.toByteArray();
+ } catch (IOException | CertificateException | NoSuchAlgorithmException | KeyStoreException e) {
+ LOGGER.error("Pem to PKCS12 converter failed", e);
+ throw new PemToPKCS12ConverterException(e);
+ }
+ }
+
+ private KeyStore getKeyStore(String alias, Password password, Certificate[] certificates, PrivateKey privateKey)
+ throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
+ KeyStore ks = getKeyStoreInstance();
+ ks.setKeyEntry(alias, privateKey, password.toCharArray(), certificates);
+ return ks;
+ }
+
+ private KeyStore getTrustStore(String alias, Certificate[] certificates)
+ throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
+ KeyStore ks = getKeyStoreInstance();
+ long i = 1L;
+ for (Certificate c : certificates) {
+ ks.setCertificateEntry(alias + i++, c);
+ }
+ return ks;
+ }
+
+ private KeyStore getKeyStoreInstance()
+ throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
+ KeyStore ks = KeyStore.getInstance(PKCS12);
+ ks.load(EMPTY_KEYSTORE_CONFIGURATION);
+ return ks;
+ }
+
+ private Certificate[] convertToCertificateArray(List<String> certificates)
+ throws PemToPKCS12ConverterException {
+ Certificate[] parsedCertificates = new Certificate[certificates.size()];
+ for (String certificate : certificates) {
+ parsedCertificates[certificates.indexOf(certificate)] = parseCertificate(certificate);
+ }
+ return parsedCertificates;
+ }
+
+ private Certificate parseCertificate(String certificate) throws PemToPKCS12ConverterException {
+ try (PEMParser pem = new PEMParser(new StringReader(certificate))) {
+ X509CertificateHolder certHolder = Optional.ofNullable((X509CertificateHolder) pem.readObject())
+ .orElseThrow(
+ () -> new PemToPKCS12ConverterException("The certificate couldn't be parsed correctly. " + certificate));
+ return new JcaX509CertificateConverter()
+ .setProvider(new BouncyCastleProvider())
+ .getCertificate(certHolder);
+ } catch (IOException | CertificateException e) {
+ LOGGER.error("Certificates conversion failed", e);
+ throw new PemToPKCS12ConverterException(e);
+ }
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java
new file mode 100644
index 00000000..5db7b26f
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java
@@ -0,0 +1,47 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import java.security.SecureRandom;
+import org.apache.commons.lang3.RandomStringUtils;
+
+class RandomPasswordGenerator {
+
+ private static final String ALPHA = "abcdefghijklmnopqrstuvwxyz";
+ private static final String NUMBERS = "0123456789";
+ private static final String SPECIAL_CHARS = "_$#";
+ private static final char[] SET_OF_CHARS = (ALPHA + ALPHA.toUpperCase() + NUMBERS + SPECIAL_CHARS).toCharArray();
+ private static final char START_POSITION_IN_ASCII_CHARS = 0;
+ private static final char END_POSITION_IN_ASCII_CHARS = 0;
+ private static final boolean USE_LETTERS_ONLY = false;
+ private static final boolean USE_NUMBERS_ONLY = false;
+
+ Password generate(int passwordLength) {
+ return new Password(RandomStringUtils.random(
+ passwordLength,
+ START_POSITION_IN_ASCII_CHARS,
+ END_POSITION_IN_ASCII_CHARS,
+ USE_LETTERS_ONLY,
+ USE_NUMBERS_ONLY,
+ SET_OF_CHARS,
+ new SecureRandom()));
+ }
+}
+
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java
new file mode 100644
index 00000000..6ee7817b
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java
@@ -0,0 +1,34 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+
+@FunctionalInterface
+public interface StoreEntryOperation {
+
+ KeyStore getStore(Certificate[] certificates)
+ throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException;
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java
new file mode 100644
index 00000000..87020d6f
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java
@@ -0,0 +1,39 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.exception;
+
+import org.onap.aaf.certservice.client.api.ExitCode;
+import org.onap.aaf.certservice.client.api.ExitableException;
+
+public class PemToPKCS12ConverterException extends ExitableException {
+ private static final ExitCode EXIT_CODE = ExitCode.PKCS12_CONVERSION_EXCEPTION;
+
+ public PemToPKCS12ConverterException(Throwable e) {
+ super(e);
+ }
+ public PemToPKCS12ConverterException(String message) {
+ super(message);
+ }
+
+ @Override
+ public int applicationExitCode() {
+ return EXIT_CODE.getValue();
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java
new file mode 100644
index 00000000..596a6a44
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java
@@ -0,0 +1,35 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.exception;
+
+import org.onap.aaf.certservice.client.api.ExitCode;
+import org.onap.aaf.certservice.client.api.ExitableException;
+
+public class PkEncodingException extends ExitableException {
+ private static final ExitCode EXIT_CODE = ExitCode.PK_TO_PEM_ENCODING_EXCEPTION;
+
+ public PkEncodingException(Throwable e) {
+ super(e);
+ }
+
+ public int applicationExitCode() {
+ return EXIT_CODE.getValue();
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Coder.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java
index c066187d..1f90db1b 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Coder.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java
@@ -1,5 +1,4 @@
-/*
- * ============LICENSE_START=======================================================
+/*============LICENSE_START=======================================================
* aaf-certservice-client
* ================================================================================
* Copyright (C) 2020 Nokia. All rights reserved.
@@ -22,8 +21,8 @@ package org.onap.aaf.certservice.client.common;
import org.bouncycastle.util.encoders.Base64;
-public class Base64Coder {
- public static String encode(String string){
+public class Base64Encoder {
+ public String encode(String string){
return new String(Base64.encode(string.getBytes()));
}
-}
+} \ No newline at end of file
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java
index e65d688d..b0405274 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java
@@ -27,7 +27,7 @@ public final class EnvValidationUtils {
private EnvValidationUtils() {}
public static Boolean isPathValid(String path) {
- return path.matches("^/|(/[a-zA-Z0-9_-]+)+$");
+ return path.matches("^/|(/[a-zA-Z0-9_-]+)+/?$");
}
public static Boolean isAlphaNumeric(String caName) {
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java
index b7ee5d32..3bd15288 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java
@@ -20,14 +20,15 @@
package org.onap.aaf.certservice.client.configuration.factory;
+
+
+import java.util.Optional;
import org.onap.aaf.certservice.client.configuration.ClientConfigurationEnvs;
import org.onap.aaf.certservice.client.configuration.EnvValidationUtils;
import org.onap.aaf.certservice.client.configuration.EnvsForClient;
import org.onap.aaf.certservice.client.configuration.exception.ClientConfigurationException;
import org.onap.aaf.certservice.client.configuration.model.ClientConfiguration;
-import java.util.Optional;
-
public class ClientConfigurationFactory implements AbstractConfigurationFactory<ClientConfiguration> {
private final EnvsForClient envsForClient;
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java
index 16b5e03b..809a91f2 100644
--- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java
@@ -52,7 +52,7 @@ public class CsrFactoryTest {
when(config.getOrganizationUnit()).thenReturn("ONAP");
when(config.getState()).thenReturn("California");
- assertThat(new CsrFactory(config).createEncodedCsr(keyPair)).isNotEmpty();
+ assertThat(new CsrFactory(config).createCsrInPem(keyPair)).isNotEmpty();
}
}
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java
new file mode 100644
index 00000000..def9c1d5
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java
@@ -0,0 +1,66 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification;
+
+
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemReader;
+import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.client.certification.exception.PkEncodingException;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class PrivateKeyToPemEncoderTest {
+
+ private static final String ENCRYPTION_ALGORITHM = "RSA";
+ private static final String RESOURCES_DIR = "src/test/resources/";
+ private static final String PRIVATE_KEY_PEM_PATH = RESOURCES_DIR + "rsaPrivateKeyPem";
+
+ @Test
+ public void shouldReturnProperlyEncodedPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException, PkEncodingException, IOException {
+ //given
+ String expectedPem = Files.readString(Paths.get(PRIVATE_KEY_PEM_PATH));
+ PrivateKeyToPemEncoder testedPkEncoder = new PrivateKeyToPemEncoder();
+ //when
+ PrivateKey privateKey = extractPrivateKeyFromPem(expectedPem);
+ String resultPkInPem = testedPkEncoder.encodePrivateKeyToPem(privateKey);
+ //then
+ assertThat(resultPkInPem).isEqualTo(expectedPem);
+ }
+
+ private PrivateKey extractPrivateKeyFromPem(String pem) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
+ PemReader pemReader = new PemReader(new StringReader(pem));
+ PemObject pemObject = pemReader.readPemObject();
+ pemReader.close();
+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pemObject.getContent());
+ KeyFactory kf = KeyFactory.getInstance(ENCRYPTION_ALGORITHM);
+ return kf.generatePrivate(spec);
+ }
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java
new file mode 100644
index 00000000..04bccf0b
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java
@@ -0,0 +1,80 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.security.PrivateKey;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException;
+
+class KeystoreTruststoreCreatorTest {
+
+ private PKCS12FilesCreator filesCreator = mock(PKCS12FilesCreator.class);
+ private RandomPasswordGenerator passwordGenerator = mock(RandomPasswordGenerator.class);
+ private PemToPKCS12Converter converter = mock(PemToPKCS12Converter.class);
+ private PrivateKey privateKey = mock(PrivateKey.class);
+
+ @Test
+ void createKeystoreShouldCallRequiredMethods() throws PemToPKCS12ConverterException {
+ // given
+ final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
+ final List<String> certificates = List.of("a", "b");
+ final int passwordLength = 24;
+ final String alias = "certificate";
+ final byte[] keystoreBytes = "this is a keystore test".getBytes();
+ KeystoreTruststoreCreator creator = new KeystoreTruststoreCreator(filesCreator, passwordGenerator, converter);
+
+ // when
+ when(passwordGenerator.generate(passwordLength)).thenReturn(password);
+ when(converter.convertKeystore(certificates, password, alias, privateKey)).thenReturn(keystoreBytes);
+ creator.createKeystore(certificates, privateKey);
+
+ // then
+ verify(passwordGenerator, times(1)).generate(passwordLength);
+ verify(converter, times(1)).convertKeystore(certificates, password, alias, privateKey);
+ verify(filesCreator, times(1)).saveKeystoreData(keystoreBytes, password.getPassword());
+ }
+
+ @Test
+ void createTruststoreShouldCallRequiredMethods() throws PemToPKCS12ConverterException {
+ // given
+ final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
+ final List<String> certificates = List.of("a", "b");
+ final int passwordLength = 24;
+ final String alias = "trusted-certificate-";
+ final byte[] truststoreBytes = "this is a truststore test".getBytes();
+ KeystoreTruststoreCreator creator = new KeystoreTruststoreCreator(filesCreator, passwordGenerator, converter);
+
+ // when
+ when(passwordGenerator.generate(passwordLength)).thenReturn(password);
+ when(converter.convertTruststore(certificates, password, alias)).thenReturn(truststoreBytes);
+ creator.createTruststore(certificates);
+
+ // then
+ verify(passwordGenerator, times(1)).generate(passwordLength);
+ verify(converter, times(1)).convertTruststore(certificates, password, alias);
+ verify(filesCreator, times(1)).saveTruststoreData(truststoreBytes, password.getPassword());
+ }
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java
new file mode 100644
index 00000000..8e6e03c6
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java
@@ -0,0 +1,111 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException;
+
+class PKCS12FilesCreatorTest {
+
+ private static final String RESOURCES_PATH = "src/test/resources";
+ private static final String OUTPUT_PATH = RESOURCES_PATH + "/generatedFiles/";
+ private static final String KEYSTORE_PATH = OUTPUT_PATH + "keystore.jks";
+ private static final String KEYSTORE_PASS_PATH = OUTPUT_PATH + "keystore.pass";
+ private static final String TRUSTSTORE_PATH = OUTPUT_PATH + "truststore.jks";
+ private static final String TRUSTSTORE_PASS_PATH = OUTPUT_PATH + "truststore.pass";
+ private static final String ERROR_MESSAGE = "java.io.FileNotFoundException: src/test/resources/generatedFiles/thisPathDoesNotExist/keystore.jks (No such file or directory)";
+
+ private File outputDirectory = new File(OUTPUT_PATH);
+
+ @BeforeEach
+ void createDirectory() {
+ outputDirectory.mkdir();
+ }
+
+ @AfterEach
+ void cleanUpFiles() {
+ List.of(outputDirectory.listFiles()).forEach(f -> f.delete());
+ outputDirectory.delete();
+ }
+
+ @Test
+ void saveKeystoreDataShouldCreateFilesWithDataInGivenLocation() throws PemToPKCS12ConverterException, IOException {
+ // given
+ final byte[] data = new byte[]{-128, 1, 127};
+ final String password = "onap123";
+ File keystore = new File(KEYSTORE_PATH);
+ File keystorePass = new File(KEYSTORE_PASS_PATH);
+ PKCS12FilesCreator filesCreator = new PKCS12FilesCreator(OUTPUT_PATH);
+
+ // when
+ filesCreator.saveKeystoreData(data, password);
+
+ // then
+ assertTrue(keystore.exists());
+ assertTrue(keystorePass.exists());
+ assertArrayEquals(data, Files.readAllBytes(Path.of(KEYSTORE_PATH)));
+ assertEquals(password, Files.readString(Path.of(KEYSTORE_PASS_PATH), StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void saveTruststoreDataShouldCreateFilesWithDataInGivenLocation()
+ throws PemToPKCS12ConverterException, IOException {
+ // given
+ final byte[] data = new byte[]{-128, 1, 2, 3, 127};
+ final String password = "nokia321";
+ File truststore = new File(TRUSTSTORE_PATH);
+ File truststorePass = new File(TRUSTSTORE_PASS_PATH);
+ PKCS12FilesCreator filesCreator = new PKCS12FilesCreator(OUTPUT_PATH);
+
+ // when
+ filesCreator.saveTruststoreData(data, password);
+
+ // then
+ assertTrue(truststore.exists());
+ assertTrue(truststorePass.exists());
+ assertArrayEquals(data, Files.readAllBytes(Path.of(TRUSTSTORE_PATH)));
+ assertEquals(password, Files.readString(Path.of(TRUSTSTORE_PASS_PATH), StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void saveKeystoreDataShouldThrowPemToPKCS12ConverterExceptionWhenOutputDirectoryDoesNotExist() {
+ // given
+ final byte[] data = new byte[]{-128, 1, 2, 3, 0};
+ final String password = "123aikon";
+ PKCS12FilesCreator filesCreator = new PKCS12FilesCreator(OUTPUT_PATH + "thisPathDoesNotExist/");
+
+ // when then
+ assertThatThrownBy(() -> filesCreator.saveKeystoreData(data, password))
+ .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(ERROR_MESSAGE);
+ }
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java
new file mode 100644
index 00000000..35043409
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java
@@ -0,0 +1,197 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.List;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants;
+import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException;
+
+class PemToPKCS12ConverterTest {
+
+ private static final String RESOURCES_PATH = "src/test/resources";
+ private static final String CERT1_PATH = RESOURCES_PATH + "/cert1.pem";
+ private static final String CERT2_PATH = RESOURCES_PATH + "/cert2.pem";
+ private static final String KEY_PATH = RESOURCES_PATH + "/privateKey";
+ private static final String EXPECTED_KEYSTORE_PATH = RESOURCES_PATH + "/expectedKeystore.jks";
+ private static final String EXPECTED_TRUSTSTORE_PATH = RESOURCES_PATH + "/expectedTruststore.jks";
+ private static final String PKCS12 = "PKCS12";
+ private static final String PKCS8 = "PKCS#8";
+ private static final String KEY_ERROR_MSG = "java.security.KeyStoreException: Key protection algorithm not found: java.lang.NullPointerException";
+ private static final String CERTIFICATES_ERROR_MSG = "The certificate couldn't be parsed correctly. certificate1";
+ private static final String PASSWORD_ERROR_MSG = "Password should be min. 16 chars long and should contain only alphanumeric characters and special characters like Underscore (_), Dollar ($) and Pound (#)";
+ private static byte[] key;
+ private PrivateKey privateKey = mock(PrivateKey.class);
+
+ @BeforeAll
+ static void setUpForAll() throws IOException {
+ key = Files.readAllBytes(Path.of(KEY_PATH));
+ }
+
+ @Test
+ void convertKeystoreShouldReturnKeystoreWithGivenPrivateKeyAndCertificateChain()
+ throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, PemToPKCS12ConverterException {
+ // given
+ final String alias = "keystore-entry";
+ final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
+ final List<String> certificateChain = getCertificates();
+ final PemToPKCS12Converter converter = new PemToPKCS12Converter();
+ final KeyStore expectedKeyStore = KeyStore.getInstance(PKCS12);
+ expectedKeyStore.load(new ByteArrayInputStream(Files.readAllBytes(Path.of(EXPECTED_KEYSTORE_PATH))),
+ password.toCharArray());
+ final Certificate[] expectedChain = expectedKeyStore.getCertificateChain(alias);
+ privateKeyMockSetup();
+
+ // when
+ final byte[] result = converter.convertKeystore(certificateChain, password, alias, privateKey);
+
+ // then
+ final KeyStore actualKeyStore = KeyStore.getInstance(PKCS12);
+ actualKeyStore.load(new ByteArrayInputStream(result), password.toCharArray());
+ final Certificate[] actualChain = actualKeyStore.getCertificateChain(alias);
+
+ assertArrayEquals(key, actualKeyStore.getKey(alias, password.toCharArray()).getEncoded());
+ assertEquals(2, expectedChain.length);
+ assertArrayEquals(expectedChain, actualChain);
+ }
+
+ @Test
+ void convertKeystoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongPassword() throws IOException {
+ // given
+ final String alias = "keystore-entry";
+ final Password password = new Password("apple");
+ final List<String> certificateChain = getCertificates();
+ final PemToPKCS12Converter converter = new PemToPKCS12Converter();
+ privateKeyMockSetup();
+
+ // when
+ Exception exception = assertThrows(PemToPKCS12ConverterException.class, () ->
+ converter.convertKeystore(certificateChain, password, alias, privateKey)
+ );
+
+ // then
+ assertEquals(PASSWORD_ERROR_MSG, exception.getMessage());
+ }
+
+ @Test
+ void convertTruststoreShouldReturnTruststoreWithGivenCertificatesArray()
+ throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, PemToPKCS12ConverterException {
+
+ // given
+ final PemToPKCS12Converter converter = new PemToPKCS12Converter();
+ final String alias = "trusted-certificate-";
+ final String alias1 = alias + 1;
+ final String alias2 = alias + 2;
+ final Password password = new Password("9z6oFx1epRSCuBWU4Er8i_0y");
+ final List<String> trustedCertificates = getCertificates();
+ final KeyStore expectedTrustStore = KeyStore.getInstance(PKCS12);
+ expectedTrustStore.load(new ByteArrayInputStream(Files.readAllBytes(Path.of(EXPECTED_TRUSTSTORE_PATH))),
+ password.toCharArray());
+
+ // when
+ final byte[] result = converter.convertTruststore(trustedCertificates, password, alias);
+
+ // then
+ final KeyStore actualKeyStore = KeyStore.getInstance(PKCS12);
+ actualKeyStore.load(new ByteArrayInputStream(result), password.toCharArray());
+
+ assertTrue(actualKeyStore.containsAlias(alias1));
+ assertTrue(actualKeyStore.containsAlias(alias2));
+ assertEquals(expectedTrustStore.getCertificate(alias1), actualKeyStore.getCertificate(alias1));
+ assertEquals(expectedTrustStore.getCertificate(alias2), actualKeyStore.getCertificate(alias2));
+ }
+
+ @Test
+ void convertTruststoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongPassword() throws IOException {
+ // given
+ final String alias = "trusted-certificate-";
+ final Password password = new Password("nokia");
+ final List<String> trustedCertificates = getCertificates();
+ final PemToPKCS12Converter converter = new PemToPKCS12Converter();
+
+ // when then
+ assertThatThrownBy(() ->
+ converter.convertTruststore(trustedCertificates, password, alias))
+ .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(PASSWORD_ERROR_MSG);
+ }
+
+ @Test
+ void convertKeystoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongPrivateKey() throws IOException {
+ // given
+ final String alias = "keystore-entry";
+ final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
+ final List<String> certificateChain = getCertificates();
+ final PemToPKCS12Converter converter = new PemToPKCS12Converter();
+
+ // when then
+ assertThatThrownBy(() -> converter.convertKeystore(certificateChain, password, alias, privateKey))
+ .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(KEY_ERROR_MSG);
+ }
+
+ @Test
+ void convertKeystoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongCertificates() {
+ // given
+ final String alias = "keystore-entry";
+ final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
+ final List<String> certificateChain = List.of("certificate1", "certificate2");
+ final PemToPKCS12Converter converter = new PemToPKCS12Converter();
+ privateKeyMockSetup();
+
+ // when then
+ assertThatThrownBy(() -> converter.convertKeystore(certificateChain, password, alias, privateKey))
+ .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(CERTIFICATES_ERROR_MSG);
+ }
+
+ private void privateKeyMockSetup() {
+ when(privateKey.getEncoded()).thenReturn(key);
+ when(privateKey.getAlgorithm()).thenReturn(EncryptionAlgorithmConstants.RSA_ENCRYPTION_ALGORITHM);
+ when(privateKey.getFormat()).thenReturn(PKCS8);
+ }
+
+ private List<String> getCertificates() throws IOException {
+ return List.of(
+ Files.readString(
+ Path.of(CERT1_PATH), StandardCharsets.UTF_8),
+ Files.readString(
+ Path.of(CERT2_PATH), StandardCharsets.UTF_8)
+ );
+ }
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java
new file mode 100644
index 00000000..169ce98a
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java
@@ -0,0 +1,32 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.certification.conversion;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.Test;
+
+class RandomPasswordGeneratorTest {
+
+ @Test
+ void shouldGenerateRandomPasswordOfGivenLengthMatchingThePattern() {
+ Password password = new RandomPasswordGenerator().generate(24);
+ assertTrue(password.isCorrectPasswordPattern());
+ }
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java
new file mode 100644
index 00000000..8f4fe6a3
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java
@@ -0,0 +1,41 @@
+/*============LICENSE_START=======================================================
+ * aaf-certservice-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aaf.certservice.client.configuration;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class EnvValidationUtilsTest {
+
+ @ParameterizedTest
+ @ValueSource(strings = {"/var/log", "/", "/var/log/", "/second_var", "/second-var"})
+ public void shouldAcceptValidPath(String path){
+ assertTrue(EnvValidationUtils.isPathValid(path));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"/var/log?", "", "var_", "var", "//", "/var//log"})
+ public void shouldRejectInvalidPath(String path){
+ assertFalse(EnvValidationUtils.isPathValid(path));
+ }
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java
index 707094c0..bb566e81 100644
--- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java
@@ -20,13 +20,17 @@
package org.onap.aaf.certservice.client.configuration.model;
+import org.assertj.core.api.Condition;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.client.api.ExitCode;
import org.onap.aaf.certservice.client.configuration.CsrConfigurationEnvs;
import org.onap.aaf.certservice.client.configuration.EnvsForCsr;
import org.onap.aaf.certservice.client.configuration.exception.CsrConfigurationException;
import org.onap.aaf.certservice.client.configuration.factory.CsrConfigurationFactory;
import java.util.Optional;
+import java.util.function.Predicate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -43,23 +47,30 @@ public class CsrConfigurationFactoryTest {
private final String ORGANIZATION_UNIT_VALID = "ONAP";
private final String STATE_VALID = "California";
private final String COMMON_NAME_INVALID = "onap.org*&";
+ private final String COUNTRY_INVALID = "PLA";
+ private final String ORGANIZATION_INVALID = "Linux?Foundation";
private EnvsForCsr envsForCsr = mock(EnvsForCsr.class);
-
+ private CsrConfigurationFactory testedFactory;
+ private Condition<CsrConfigurationException> expectedExitCodeCondition = new Condition<>("Correct exit code"){
+ @Override
+ public boolean matches(CsrConfigurationException e) {
+ return e.applicationExitCode() == ExitCode.CSR_CONFIGURATION_EXCEPTION.getValue();
+ }
+ };
+
+ @BeforeEach
+ void setUp() {
+ testedFactory = new CsrConfigurationFactory(envsForCsr);
+ }
@Test
- void create_shouldReturnSuccessWhenAllVariablesAreSetAndValid() throws CsrConfigurationException {
+ void shouldReturnCorrectConfiguration_WhenAllVariablesAreSetAndValid() throws CsrConfigurationException {
// given
- when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_VALID));
- when(envsForCsr.getSubjectAlternativesName()).thenReturn(Optional.of(SANS_VALID));
- when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_VALID));
- when(envsForCsr.getLocation()).thenReturn(Optional.of(LOCATION_VALID));
- when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID));
- when(envsForCsr.getOrganizationUnit()).thenReturn(Optional.of(ORGANIZATION_UNIT_VALID));
- when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID));
+ mockEnvsWithAllValidParameters();
// when
- CsrConfiguration configuration = new CsrConfigurationFactory(envsForCsr).create();
+ CsrConfiguration configuration = testedFactory.create();
// then
assertThat(configuration.getCommonName()).isEqualTo(COMMON_NAME_VALID);
@@ -72,15 +83,12 @@ public class CsrConfigurationFactoryTest {
}
@Test
- void create_shouldReturnSuccessWhenNotRequiredVariablesAreNotSet() throws CsrConfigurationException {
+ void shouldReturnCorrectConfiguration_WhenNotRequiredVariablesAreNotSet() throws CsrConfigurationException {
// given
- when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_VALID));
- when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID));
- when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_VALID));
- when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID));
+ mockEnvsWithValidRequiredParameters();
// when
- CsrConfiguration configuration = new CsrConfigurationFactory(envsForCsr).create();
+ CsrConfiguration configuration = testedFactory.create();
// then
assertThat(configuration.getCommonName()).isEqualTo(COMMON_NAME_VALID);
@@ -91,22 +99,89 @@ public class CsrConfigurationFactoryTest {
@Test
- void create_shouldReturnCsrConfigurationExceptionWhenCommonNameContainsSpecialCharacters() {
+ void shouldThrowCsrConfigurationException_WhenCommonNameInvalid() {
// given
- when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_INVALID));
+ mockEnvsWithInvalidCommonName();
+
+ // when/then
+ assertThatExceptionOfType(CsrConfigurationException.class)
+ .isThrownBy(testedFactory::create)
+ .withMessageContaining(CsrConfigurationEnvs.COMMON_NAME + " is invalid.")
+ .has(expectedExitCodeCondition);
+ }
+
+ @Test
+ void shouldThrowCsrConfigurationException_WhenOrganizationInvalid() {
+ // given
+ mockEnvsWithInvalidOrganization();
+
+ // when/then
+ assertThatExceptionOfType(CsrConfigurationException.class)
+ .isThrownBy(testedFactory::create)
+ .withMessageContaining(CsrConfigurationEnvs.ORGANIZATION + " is invalid.")
+ .has(expectedExitCodeCondition);
+
+ }
+
+ @Test
+ void shouldThrowCsrConfigurationException_WhenCountryInvalid() {
+ // given
+ mockEnvsWithInvalidCountry();
+
+ // when/then
+ assertThatExceptionOfType(CsrConfigurationException.class)
+ .isThrownBy(testedFactory::create)
+ .withMessageContaining(CsrConfigurationEnvs.COUNTRY + " is invalid.")
+ .has(expectedExitCodeCondition);
+
+ }
+
+ @Test
+ void shouldThrowCsrConfigurationExceptionWhenStateInvalid() {
+ // given
+ mockEnvsWithInvalidState();
+ // when/then
+ assertThatExceptionOfType(CsrConfigurationException.class)
+ .isThrownBy(testedFactory::create)
+ .withMessageContaining(CsrConfigurationEnvs.STATE + " is invalid.")
+ .has(expectedExitCodeCondition);
+ }
+
+ private void mockEnvsWithAllValidParameters() {
+ mockEnvsWithValidRequiredParameters();
+ mockEnvsWithValidOptionalParameters();
+ }
+
+ private void mockEnvsWithValidOptionalParameters() {
+ when(envsForCsr.getOrganizationUnit()).thenReturn(Optional.of(ORGANIZATION_UNIT_VALID));
+ when(envsForCsr.getLocation()).thenReturn(Optional.of(LOCATION_VALID));
when(envsForCsr.getSubjectAlternativesName()).thenReturn(Optional.of(SANS_VALID));
+ }
+
+ private void mockEnvsWithValidRequiredParameters() {
+ when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_VALID));
when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_VALID));
- when(envsForCsr.getLocation()).thenReturn(Optional.of(LOCATION_VALID));
when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID));
- when(envsForCsr.getOrganizationUnit()).thenReturn(Optional.of(ORGANIZATION_UNIT_VALID));
- when(envsForCsr.getState()).thenReturn(Optional.of(SANS_VALID));
+ when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID));
+ }
- // when
- CsrConfigurationFactory configurationFactory = new CsrConfigurationFactory(envsForCsr);
+ private void mockEnvsWithInvalidCommonName() {
+ mockEnvsWithAllValidParameters();
+ when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_INVALID));
+ }
- // when/then
- assertThatExceptionOfType(CsrConfigurationException.class)
- .isThrownBy(configurationFactory::create)
- .withMessageContaining(CsrConfigurationEnvs.COMMON_NAME + " is invalid.");
+ private void mockEnvsWithInvalidCountry() {
+ mockEnvsWithAllValidParameters();
+ when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_INVALID));
+ }
+
+ private void mockEnvsWithInvalidOrganization() {
+ mockEnvsWithAllValidParameters();
+ when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_INVALID));
+ }
+
+ private void mockEnvsWithInvalidState() {
+ mockEnvsWithAllValidParameters();
+ when(envsForCsr.getState()).thenReturn(Optional.empty());
}
}
diff --git a/certServiceClient/src/test/resources/cert1.pem b/certServiceClient/src/test/resources/cert1.pem
new file mode 100644
index 00000000..cd5f3841
--- /dev/null
+++ b/certServiceClient/src/test/resources/cert1.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDjDCCAnSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw
+FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQD
+DBVpbnRlcm1lZGlhdGUub25hcC5vcmcwHhcNMjAwMjEyMDk1MTI2WhcNMjIxMTA4
+MDk1MTI2WjB7MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
+A1UEBwwNU2FuLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjEN
+MAsGA1UECwwET05BUDEVMBMGA1UEAwwMdmlkLm9uYXAub3JnMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+GIRzJzUOh0gtc+wzFJEdTnn+q5F10L0Yhr
+G1xKdjPieHIFGsoiXwcuCU8arNSqlz7ocx62KQRkcA8y6edlOAsYtdOEJvqEI9vc
+eyTB/HYsbzw3URPGch4AmibrQkKU9QvGwouHtHn4R2Ft2Y0tfEqv9hxj9v4njq4A
+EiDLAFLl5FmVyCZu/MtKngSgu1smcaFKTYySPMxytgJZexoa/ALZyyE0gRhsvwHm
+NLGCPt1bmE/PEGZybsCqliyTO0S56ncD55The7+D/UDS4kE1Wg0svlWon/YsE6QW
+B3oeJDX7Kr8ebDTIAErevIAD7Sm4ee5se2zxYrsYlj0MzHZtvwIDAQABoxAwDjAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvQ1pTvjON6vSlcJRKSY4r
+8q7L4/9ZaVXWJAjzEYJtPIqsgGiPWz0vGfgklowU6tZxp9zRZFXfMil+mPQSe+yo
+ULrZSQ/z48YHPueE/BNO/nT4aaVBEhPLR5aVwC7uQVX8H+m1V1UGT8lk9vdI9rej
+CI9l524sLCpdE4dFXiWK2XHEZ0Vfylk221u3IYEogVVA+UMX7BFPSsOnI2vtYK/i
+lwZtlri8LtTusNe4oiTkYyq+RSyDhtAswg8ANgvfHolhCHoLFj6w1IkG88UCmbwN
+d7BoGMy06y5MJxyXEZG0vR7eNeLey0TIh+rAszAFPsIQvrOHW+HuA+WLQAj1mhnm
+-----END CERTIFICATE-----
diff --git a/certServiceClient/src/test/resources/cert2.pem b/certServiceClient/src/test/resources/cert2.pem
new file mode 100644
index 00000000..92ebc821
--- /dev/null
+++ b/certServiceClient/src/test/resources/cert2.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw
+FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMREwDwYDVQQD
+DAhvbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVyQG9uYXAub3JnMB4XDTIw
+MDIxMjA5NDAxMloXDTIyMTEwODA5NDAxMlowgYQxCzAJBgNVBAYTAlVTMRMwEQYD
+VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkwFwYDVQQK
+DBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQDDBVpbnRl
+cm1lZGlhdGUub25hcC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQC1oOYMZ6G+2DGDAizYnzdCNiogivlht1s4oqgem7fM1XFPxD2p31ATIibOdqr/
+gv1qemO9Q4r1xn6w1Ufq7T1K7PjnMzdSeTqZefurE2JM/HHx2QvW4TjMlz2ILgaD
+L1LN60kmMQSOi5VxKJpsrCQxbOsxhvefd212gny5AZMcjJe23kUd9OxUrtvpdLEv
+wI3vFEvT7oRUnEUg/XNz7qeg33vf1C39yMR+6O4s6oevgsEebVKjb+yOoS6zzGtz
+72wZjm07C54ZlO+4Uy+QAlMjRiU3mgWkKbkOy+4CvwehjhpTikdBs2DX39ZLGHhn
+L/0a2NYtGulp9XEqmTvRoI+PAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBADcitdJ6YswiV8jAD9GK0gf3+zqcGegt4kt+79JXlXYbb1sY
+q3o6prcB7nSUoClgF2xUPCslFGpM0Er9FCSFElQM/ru0l/KVmJS6kSpwEHvsYIH3
+q5anta+Pyk8JSQWAAw+qrind0uBQMnhR8Tn13tgV+Kjvg/xlH/nZIEdN5YtLB1cA
+beVsZRyRfVL9DeZU8s/MZ5wC3kgcEp5A4m5lg7HyBxBdqhzFcDr6xiy6OGqW8Yep
+xrwfc8Fw8a/lOv4U+tBeGNKPQDYaL9hh+oM+qMkNXsHXDqdJsuEGJtU4i3Wcwzoc
+XGN5NWV//4bP+NFmwgcn7AYCdRvz04A8GU/0Cwg=
+-----END CERTIFICATE-----
diff --git a/certServiceClient/src/test/resources/expectedKeystore.jks b/certServiceClient/src/test/resources/expectedKeystore.jks
new file mode 100644
index 00000000..95359b0e
--- /dev/null
+++ b/certServiceClient/src/test/resources/expectedKeystore.jks
Binary files differ
diff --git a/certServiceClient/src/test/resources/expectedTruststore.jks b/certServiceClient/src/test/resources/expectedTruststore.jks
new file mode 100644
index 00000000..ab7d93d9
--- /dev/null
+++ b/certServiceClient/src/test/resources/expectedTruststore.jks
Binary files differ
diff --git a/certServiceClient/src/test/resources/privateKey b/certServiceClient/src/test/resources/privateKey
new file mode 100644
index 00000000..463a27d3
--- /dev/null
+++ b/certServiceClient/src/test/resources/privateKey
Binary files differ
diff --git a/certServiceClient/src/test/resources/rsaPrivateKeyPem b/certServiceClient/src/test/resources/rsaPrivateKeyPem
new file mode 100644
index 00000000..a99cc3c8
--- /dev/null
+++ b/certServiceClient/src/test/resources/rsaPrivateKeyPem
@@ -0,0 +1,28 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCwooLW/yfXHIGs
+djOW6zCM6mzGq4ZkFr0LMVBE+Y9dckGsYJzCrfC4pQtFjcvTlwalu6/YOgieR/zY
+bgVF7Ic0IYV+BssO+t6Zx2xYli4NIGc5kJgDrKtR6lWvH8AMnQEr+QiDElLBWobU
++QGn5v8A528Ow5yD1fmxKTqqvWS4v1rOShGCIdse5ViraGjnMFxOV6u6pGqa17v7
+dTh0XIUyF/o3aSbmBHXkmvQ4pu/K1ncsF2zHIqUWAc7j8y1u5uE5o8b+dUzkcS4t
+QKfjFKP81I7XQNmpGZ8REzWyaYVk3RrMCju6iVgdKrs198Wif0b7wGswFv4BFhOp
+2jceFUwfAgMBAAECggEABjDb9x8gTVjRbrMB4eNCY14ADAKNBksJuy+ySYiZrsPH
+a3xDYktoaYBXYcuzfioH8J0gb6qxDKMnSIqqoqXEo14daKpiSZcfYDJuKLiyyoD9
+PTZFLbPKmWdmM2ogeBC0rs7eroFg5yf+G87ScQkWnPh/mvveK3y/cKcqSDu1IQh8
+3b8KQshC5g4iBqCfOMW3ASF03M4zmM3brKMWsdsAWEbFHQ34H10FXTHrAINpWIZK
+s2NL3z9tK6hXrwlZdKH6R/JWczSO7O5MBjLfeXZK7q3Tw4qtFWWjcNwfPlUZKMAS
+3fZFamFwY//qW+0yuCO59o70d9Pjm6p0DWsfOs9t8QKBgQD1iRdGV4xZXZT9Q4Wh
+LQMnChjuNHcmhdBYbmC03j3AffQwkQ1dKt++9uWYdy9dO9v1w7aygAMQI36jkDvR
+UJ1Rnmt9gQpeOL/wHP3R0uHbTtxLeGnX3Oo1Yx7Wfl98rq4mmBxjO5Lgft/6kTgz
+XgeiNDWi53KwDEOoFaZhWihZ6QKBgQC4Ka5Hc9wXD/5utpvNs5ut+9zjY0kx6kr8
+SyDZExbVR1ohtvSQ2sd2JvZPyFS0VbvYfFPhyCYcWW9LDEX168CZT5aHgcNop1Iu
+Szq8nYrljFa5Ibdlpf0qxC6JgObC2XytUR0O7BaXHBWpl0/wLpLTcfU2wTDLRoH8
+JLu7P3MoxwKBgQCI9DWqQ60CL8Op3J7NvviyLtynCVaogx0qJi8E062oD9lDubS1
+kfOJZde8ykX+ACR5mffu6p5KwzGg9BOZdhi57N5R+8cXtRnCSbl97t2R4RPZeMm4
+4P02WBpcU9LZDeoPlurGovUTCVHPRm8Nn9YsMGj2e5ip/71BJQpP5OT6+QKBgQCP
+NYJb+AG3QW22hHQmArxWEFxVyrh5g1sqU/XIOCryUVkKjK4kEq02+NdjdUJBNcYs
+c4n7MlxIgVelQXcJ5HlR/uzslQDy2eJzM3cKg2wmUvqBXnGyLuDvJ72UmdNYxC1K
+zZ/OIdLzURibV5oHCQCOQrjQCm06NasQ+zOtSYrwswKBgQCUHhgxynFNyidxPFzX
+V0X5xCbJ3jvJNjZFRsItQ97vEAkfJqxCnOZKMti0JWSlLBEViaKnqaA+ZE/SeJ/k
+Jut5h9gu4QIdeF4mf9v3tjuEQP7RaMCD6xnFZnebkQf6wlZz5VaXME4ICpi1Cnk7
+DySS9CMoRnwdwY7hAbfPtupKDA==
+-----END RSA PRIVATE KEY-----
diff --git a/pom.xml b/pom.xml
index 2d1632d8..3eef61b1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,6 +53,7 @@
<springdoc-openapi-maven-plugin.version>0.2</springdoc-openapi-maven-plugin.version>
<gson.version>2.8.6</gson.version>
<httpcomponents.version>4.5.6</httpcomponents.version>
+ <commons-lang3.version>3.9</commons-lang3.version>
<commons-io.version>2.6</commons-io.version>
<docker-maven-plugin.version>0.33.0</docker-maven-plugin.version>
<junit.version>5.5.2</junit.version>
@@ -235,6 +236,11 @@
<version>${httpcomponents.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${commons-lang3.version}</version>
+ </dependency>
+ <dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
@@ -257,13 +263,7 @@
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-engine</artifactId>
- <version>${junit.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
+ <artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>