summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--certService/Dockerfile2
-rw-r--r--certService/README.md16
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java (renamed from certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java)7
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java58
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java41
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java20
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoadingException.java32
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java3
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java8
-rw-r--r--certService/src/main/resources/application.properties2
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java (renamed from certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java)38
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java89
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java49
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java167
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java124
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidatorTest.java2
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolationTest.java2
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolationTest.java2
-rw-r--r--certService/src/test/resources/application.properties2
-rw-r--r--certService/src/test/resources/invalidCmpServers.json19
-rw-r--r--certServiceClient/pom.xml18
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java31
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java7
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitableException.java1
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java154
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/EncryptionAlgorithmConstants.java15
-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/CsrGenerationException.java35
-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.java28
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvProvider.java11
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java6
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForClient.java32
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForCsr.java48
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java13
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/CsrConfigurationFactory.java14
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/CsrConfiguration.java8
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/CloseableHttpClientProvider.java40
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/HttpClient.java117
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/CertServiceApiResponseException.java42
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/HttpClientException.java37
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/CertServiceResponse.java44
-rw-r--r--certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/ErrorCertServiceResponse.java40
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/CerServiceRequestTestData.java89
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java58
-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/ClientConfigurationFactoryTest.java44
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java151
-rw-r--r--certServiceClient/src/test/java/org/onap/aaf/certservice/client/httpclient/HttpClientTest.java157
-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/correctResponse10
-rw-r--r--certServiceClient/src/test/resources/expectedFirstElementOfCertificateChain21
-rw-r--r--certServiceClient/src/test/resources/expectedFirstElementOfTrustedCertificates22
-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/missingPkResponse7
-rw-r--r--certServiceClient/src/test/resources/privateKeybin0 -> 1217 bytes
-rw-r--r--certServiceClient/src/test/resources/rsaPrivateKeyPem28
-rw-r--r--certServiceClient/src/test/resources/testCsr1
-rw-r--r--certServiceClient/src/test/resources/testPk1
-rw-r--r--pom.xml14
75 files changed, 2862 insertions, 279 deletions
diff --git a/certService/Dockerfile b/certService/Dockerfile
index 5060c6bf..770dab97 100644
--- a/certService/Dockerfile
+++ b/certService/Dockerfile
@@ -4,7 +4,7 @@ ARG VERSION=${version}
RUN groupadd certService && useradd -g certService certService
-RUN apt-get update && apt-get install -y vim
+RUN apt-get update && apt-get install -y vim curl
RUN chown -R certService:certService /var/log
diff --git a/certService/README.md b/certService/README.md
index 23cb2cf6..4780a904 100644
--- a/certService/README.md
+++ b/certService/README.md
@@ -84,15 +84,23 @@ curl localhost:8080/actuator/health
```
Should return {"status":"UP"}
-### Running CSITs
-Pull csit repository
+### AAF CertService CSITs
+#### CSIT repository
```
https://gerrit.onap.org/r/admin/repos/integration/csit
```
-Go to created directory and run
+
+####How to run tests locally
+1. Checkout CSIT repository
+2. Configure CSIT local environment
+3. Inside CSIT directory execute
```
-sudo ./run-csit.sh plans/aaf/cert-service
+sudo ./run-csit.sh plans/aaf/certservice
```
+
+####Jenkins build
+https://jenkins.onap.org/view/CSIT/job/aaf-master-csit-certservice/
+
### Logs locally
path:
diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java
index 945fc6d1..e663909c 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationService.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java
@@ -39,15 +39,15 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
-public class CertificationService {
+public class CertificationController {
- private static final Logger LOGGER = LoggerFactory.getLogger(CertificationService.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(CertificationController.class);
private final CsrModelFactory csrModelFactory;
private final CertificationModelFactory certificationModelFactory;
@Autowired
- CertificationService(CsrModelFactory csrModelFactory, CertificationModelFactory certificationModelFactory) {
+ CertificationController(CsrModelFactory csrModelFactory, CertificationModelFactory certificationModelFactory) {
this.csrModelFactory = csrModelFactory;
this.certificationModelFactory = certificationModelFactory;
}
@@ -81,5 +81,4 @@ public class CertificationService {
}
-
}
diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java b/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java
new file mode 100644
index 00000000..5390a00c
--- /dev/null
+++ b/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java
@@ -0,0 +1,58 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PROJECT
+ * ================================================================================
+ * 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.api;
+
+import org.onap.aaf.certservice.certification.configuration.CmpServersConfig;
+import org.onap.aaf.certservice.certification.configuration.CmpServersConfigLoadingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class ReloadConfigController {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ReloadConfigController.class);
+
+ private final CmpServersConfig cmpServersConfig;
+
+ @Autowired
+ public ReloadConfigController(CmpServersConfig cmpServersConfig) {
+ this.cmpServersConfig = cmpServersConfig;
+ }
+
+ @GetMapping("/reload")
+ public ResponseEntity<String> reloadConfiguration() throws CmpServersConfigLoadingException {
+ cmpServersConfig.reloadConfiguration();
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ @ExceptionHandler(value = CmpServersConfigLoadingException.class)
+ public ResponseEntity<String> handle(CmpServersConfigLoadingException exception) {
+ LOGGER.error(exception.getMessage(), exception.getCause());
+ return new ResponseEntity<>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+}
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java
index 25e69251..a304b5a6 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java
@@ -20,34 +20,31 @@
package org.onap.aaf.certservice.certification.configuration;
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.PostConstruct;
import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.cloud.context.config.annotation.RefreshScope;
-import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.context.annotation.Configuration;
-import javax.annotation.PostConstruct;
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import org.springframework.context.event.EventListener;
-
@Configuration
public class CmpServersConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(CmpServersConfig.class);
+ private static final String LOADING_SUCCESS_MESSAGE = "CMP Servers configuration successfully loaded from file {}";
private static final String CMP_SERVERS_CONFIG_FILENAME = "cmpServers.json";
+ private static final String INIT_CONFIGURATION = "Loading initial configuration";
private static final String REFRESHING_CONFIGURATION = "Refreshing configuration";
- private String configPath;
- private List<Cmpv2Server> cmpServers;
+ private final String configPath;
private final CmpServersConfigLoader cmpServersConfigLoader;
+ private List<Cmpv2Server> cmpServers;
+
@Autowired
public CmpServersConfig(@Value("${app.config.path}") String configPath,
CmpServersConfigLoader cmpServersConfigLoader) {
@@ -56,18 +53,28 @@ public class CmpServersConfig {
}
@PostConstruct
- void loadConfiguration() {
- String configFilePath = configPath + File.separator + CMP_SERVERS_CONFIG_FILENAME;
- this.cmpServers = Collections.unmodifiableList(cmpServersConfigLoader.load(configFilePath));
+ void init() {
+ LOGGER.info(INIT_CONFIGURATION);
+ try {
+ loadConfiguration();
+ } catch (CmpServersConfigLoadingException e) {
+ LOGGER.error(e.getMessage(), e.getCause());
+ }
}
- @EventListener
- public void onRefreshScope(final RefreshScopeRefreshedEvent event) {
+ public void reloadConfiguration() throws CmpServersConfigLoadingException {
LOGGER.info(REFRESHING_CONFIGURATION);
loadConfiguration();
}
+ void loadConfiguration() throws CmpServersConfigLoadingException {
+ String configFilePath = configPath + File.separator + CMP_SERVERS_CONFIG_FILENAME;
+ this.cmpServers = Collections.unmodifiableList(cmpServersConfigLoader.load(configFilePath));
+ LOGGER.info(LOADING_SUCCESS_MESSAGE, configFilePath);
+ }
+
public List<Cmpv2Server> getCmpServers() {
return cmpServers;
}
+
}
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java
index a6dd5fcf..1072d630 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java
@@ -24,20 +24,18 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.security.InvalidParameterException;
-import java.util.ArrayList;
import java.util.List;
import org.onap.aaf.certservice.certification.configuration.model.CmpServers;
import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
import org.onap.aaf.certservice.certification.configuration.validation.Cmpv2ServerConfigurationValidator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
class CmpServersConfigLoader {
- private static final Logger LOGGER = LoggerFactory.getLogger(CmpServersConfigLoader.class);
+ private static final String LOADING_EXCEPTION_MESSAGE = "Exception occurred during CMP Servers configuration loading";
+ private static final String VALIDATION_EXCEPTION_MESSAGE = "Validation of CMPv2 servers configuration failed";
private final Cmpv2ServerConfigurationValidator validator;
@@ -46,20 +44,16 @@ class CmpServersConfigLoader {
this.validator = validator;
}
- List<Cmpv2Server> load(String path) {
- List<Cmpv2Server> servers = new ArrayList<>();
+ List<Cmpv2Server> load(String path) throws CmpServersConfigLoadingException {
try {
- servers = loadConfigFromFile(path).getCmpv2Servers();
+ List<Cmpv2Server> servers = loadConfigFromFile(path).getCmpv2Servers();
servers.forEach(validator::validate);
- LOGGER.info(String.format("CMP Servers configuration successfully loaded from file '%s'", path));
+ return servers;
} catch (IOException e) {
- LOGGER.error("Exception occurred during CMP Servers configuration loading: ", e);
+ throw new CmpServersConfigLoadingException(LOADING_EXCEPTION_MESSAGE, e);
} catch (InvalidParameterException e) {
- LOGGER.error("Validation of CMPv2 servers configuration failed:", e);
- throw e;
+ throw new CmpServersConfigLoadingException(VALIDATION_EXCEPTION_MESSAGE, e);
}
-
- return servers;
}
private CmpServers loadConfigFromFile(String path) throws IOException {
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoadingException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoadingException.java
new file mode 100644
index 00000000..b7c3638d
--- /dev/null
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoadingException.java
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PROJECT
+ * ================================================================================
+ * 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.certification.configuration;
+
+public class CmpServersConfigLoadingException extends Exception {
+
+ public CmpServersConfigLoadingException(String message) {
+ super(message);
+ }
+
+ public CmpServersConfigLoadingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java
index af254d61..3785cf8e 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Authentication.java
@@ -20,12 +20,15 @@
package org.onap.aaf.certservice.certification.configuration.model;
+import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
public class Authentication {
+ @NotNull
@Length(min = 1, max = 256)
private String iak;
+ @NotNull
@Length(min = 1, max = 256)
private String rv;
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java
index 9f8f9796..20b83b82 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/model/Cmpv2Server.java
@@ -20,19 +20,23 @@
package org.onap.aaf.certservice.certification.configuration.model;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
import org.bouncycastle.asn1.x500.X500Name;
import org.hibernate.validator.constraints.Length;
import org.onap.aaf.certservice.certification.configuration.validation.constraints.Cmpv2URL;
-import javax.validation.Valid;
-
public class Cmpv2Server {
+ @NotNull
@Valid
private Authentication authentication;
+ @NotNull
private CaMode caMode;
+ @NotNull
@Length(min = 1, max = 128)
private String caName;
+ @NotNull
private X500Name issuerDN;
@Cmpv2URL
private String url;
diff --git a/certService/src/main/resources/application.properties b/certService/src/main/resources/application.properties
index ac81c3a0..aac9b96f 100644
--- a/certService/src/main/resources/application.properties
+++ b/certService/src/main/resources/application.properties
@@ -3,7 +3,7 @@ springdoc.show-actuator=true
management.endpoints.enabled-by-default=true
management.endpoint.configprops.enabled=true
-management.endpoints.web.exposure.include=refresh,health
+management.endpoints.web.exposure.include=health
# Swagger configuration
diff --git a/certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java
index ee1ce1ef..2fc6d665 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/api/CertificationServiceTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java
@@ -20,11 +20,21 @@
package org.onap.aaf.certservice.api;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import com.google.gson.Gson;
+import java.io.IOException;
+import java.util.Arrays;
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.MockitoAnnotations;
+import org.mockito.junit.jupiter.MockitoExtension;
import org.onap.aaf.certservice.certification.CertificationModelFactory;
import org.onap.aaf.certservice.certification.CsrModelFactory;
import org.onap.aaf.certservice.certification.CsrModelFactory.StringBase64;
@@ -36,20 +46,11 @@ import org.onap.aaf.certservice.certification.model.CsrModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
-import java.io.IOException;
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class CertificationServiceTest {
+@ExtendWith(MockitoExtension.class)
+class CertificationControllerTest {
- private CertificationService certificationService;
+ private CertificationController certificationController;
@Mock
private CsrModelFactory csrModelFactory;
@@ -58,9 +59,8 @@ class CertificationServiceTest {
private CertificationModelFactory certificationModelFactory;
@BeforeEach
- void serUp() {
- MockitoAnnotations.initMocks(this);
- certificationService = new CertificationService(csrModelFactory, certificationModelFactory);
+ void setUp() {
+ certificationController = new CertificationController(csrModelFactory, certificationModelFactory);
}
@Test
@@ -81,7 +81,7 @@ class CertificationServiceTest {
// when
ResponseEntity<String> testResponse =
- certificationService.signCertificate(testCaName, "encryptedCSR", "encryptedPK");
+ certificationController.signCertificate(testCaName, "encryptedCSR", "encryptedPK");
CertificationModel responseCertificationModel = new Gson().fromJson(testResponse.getBody(), CertificationModel.class);
@@ -101,7 +101,7 @@ class CertificationServiceTest {
// when
Exception exception = assertThrows(
- CsrDecryptionException.class, () -> certificationService.
+ CsrDecryptionException.class, () -> certificationController.
signCertificate("TestCa", "encryptedCSR", "encryptedPK")
);
@@ -120,7 +120,7 @@ class CertificationServiceTest {
// when
Exception exception = assertThrows(
- KeyDecryptionException.class, () -> certificationService.
+ KeyDecryptionException.class, () -> certificationController.
signCertificate("TestCa", "encryptedCSR", "encryptedPK")
);
diff --git a/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java
new file mode 100644
index 00000000..17db24b8
--- /dev/null
+++ b/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java
@@ -0,0 +1,89 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PROJECT
+ * ================================================================================
+ * 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.api;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.doThrow;
+
+import org.assertj.core.api.Assertions;
+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.onap.aaf.certservice.certification.configuration.CmpServersConfig;
+import org.onap.aaf.certservice.certification.configuration.CmpServersConfigLoadingException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+@ExtendWith(MockitoExtension.class)
+public class ReloadConfigControllerTest {
+
+ private static final String ERROR_MESSAGE = "Exception occurred during CMP Servers configuration loading";
+
+ private ReloadConfigController reloadConfigController;
+
+ @Mock
+ public CmpServersConfig cmpServersConfig;
+
+ @BeforeEach
+ public void setUp() {
+ this.reloadConfigController = new ReloadConfigController(cmpServersConfig);
+ }
+
+ @Test
+ public void shouldReturnStatusOkWhenSuccessfullyReloaded() throws CmpServersConfigLoadingException {
+ // When
+ ResponseEntity<String> response = reloadConfigController.reloadConfiguration();
+
+ // Then
+ assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
+ }
+
+ @Test
+ public void shouldRethrowSameErrorWhenFailedToReload() throws CmpServersConfigLoadingException {
+ // Given
+ doThrow(new CmpServersConfigLoadingException(ERROR_MESSAGE)).when(cmpServersConfig).reloadConfiguration();
+
+ // When
+ Exception exception = assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> reloadConfigController.reloadConfiguration());
+
+ // Then
+ Assertions.assertThat(exception.getMessage()).isEqualTo(ERROR_MESSAGE);
+ }
+
+ @Test
+ void shouldReturnErrorStatusAndMessageWhenExceptionOccurred() {
+ // Given
+ CmpServersConfigLoadingException exception = new CmpServersConfigLoadingException(ERROR_MESSAGE);
+
+ // When
+ ResponseEntity<String> response = reloadConfigController.handle(exception);
+
+ // Then
+ assertEquals(ERROR_MESSAGE, response.getBody());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+ }
+}
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java
index cf8c07a1..c78f6ceb 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java
@@ -20,26 +20,26 @@
package org.onap.aaf.certservice.certification.configuration;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.List;
+import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.onap.aaf.certservice.CertServiceApplication;
import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = CertServiceApplication.class)
class CmpServersConfigLoaderTest {
private static final String EXISTING_CONFIG_FILENAME = "cmpServers.json";
- private static final String NONEXISTING_CONFIG_FILENAME = "nonexisting_cmpServers.json";
+ private static final String INVALID_CONFIG_FILENAME = "invalidCmpServers.json";
+ private static final String NONEXISTENT_CONFIG_FILENAME = "nonExisting_cmpServers.json";
+
private static final Map<String, String> EXPECTED_FIRST_CMP_SERVER = Map.of(
"CA_NAME", "TEST",
"URL", "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
@@ -61,9 +61,9 @@ class CmpServersConfigLoaderTest {
private CmpServersConfigLoader configLoader;
@Test
- public void shouldLoadCmpServersConfigWhenFileAvailable() {
+ void shouldLoadCmpServersConfigWhenFileAvailable() throws CmpServersConfigLoadingException {
// Given
- String path = getClass().getClassLoader().getResource(EXISTING_CONFIG_FILENAME).getFile();
+ String path = getResourcePath(EXISTING_CONFIG_FILENAME);
// When
List<Cmpv2Server> cmpServers = configLoader.load(path);
@@ -75,14 +75,33 @@ class CmpServersConfigLoaderTest {
verifyThatCmpServerEquals(cmpServers.get(1), EXPECTED_SECOND_CMP_SERVER);
}
- @Test()
- public void shouldReturnEmptyListWhenFileMissing() {
+ @Test
+ void shouldThrowExceptionWhenFileMissing() {
+ // When
+ Exception exception = assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> configLoader.load(NONEXISTENT_CONFIG_FILENAME));
+
+ // Then
+ assertThat(exception.getMessage()).contains("Exception occurred during CMP Servers configuration loading");
+ }
+
+ @Test
+ void shouldThrowExceptionWhenConfigurationIsInvalid() {
+ // Given
+ String path = getResourcePath(INVALID_CONFIG_FILENAME);
+
// When
- List<Cmpv2Server> cmpServers = configLoader.load(NONEXISTING_CONFIG_FILENAME);
+ Exception exception = assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> configLoader.load(path));
// Then
- assertThat(cmpServers).isNotNull();
- assertThat(cmpServers).isEmpty();
+ assertThat(exception.getMessage()).contains("Validation of CMPv2 servers configuration failed");
+ }
+
+ private String getResourcePath(String invalidConfigFilename) {
+ return getClass().getClassLoader().getResource(invalidConfigFilename).getFile();
}
private void verifyThatCmpServerEquals(Cmpv2Server cmpv2Server, Map<String, String> expected) {
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java
index 43094f09..5d850fe9 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java
@@ -20,54 +20,167 @@
package org.onap.aaf.certservice.certification.configuration;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.startsWith;
+
+import java.util.List;
+import org.bouncycastle.asn1.x500.X500Name;
+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.Mockito;
-import org.onap.aaf.certservice.CertServiceApplication;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.aaf.certservice.certification.configuration.model.Authentication;
+import org.onap.aaf.certservice.certification.configuration.model.CaMode;
import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.startsWith;
-@ExtendWith(SpringExtension.class)
-@ContextConfiguration(classes = CertServiceApplication.class)
-@TestPropertySource(properties = {"app.config.path=/fake/path/to/config"})
+@ExtendWith(MockitoExtension.class)
class CmpServersConfigTest {
- private static final List<Cmpv2Server> SAMPLE_CMP_SERVERS = List.of(
- new Cmpv2Server(),
- new Cmpv2Server()
- );
+ private static final String ERROR_MESSAGE = "Exception occurred during CMP Servers configuration loading";
+ private static final String APP_CONFIG_PATH = "/fake/path/to/config";
+ private static final List<Cmpv2Server> SAMPLE_CMP_SERVERS = generateTestConfiguration();
- @MockBean
+ @Mock
private CmpServersConfigLoader cmpServersConfigLoader;
- @Autowired
private CmpServersConfig cmpServersConfig;
+ @BeforeEach
+ void setUp() {
+ cmpServersConfig = new CmpServersConfig(APP_CONFIG_PATH, cmpServersConfigLoader);
+ }
+
@Test
- public void shouldCallLoaderWithPathFromPropertiesWhenCreated() {
- Mockito.verify(cmpServersConfigLoader).load(startsWith("/fake/path/to/config"));
+ void shouldCallLoaderWithPathFromPropertiesWhenCreated() throws CmpServersConfigLoadingException {
+ // When
+ this.cmpServersConfig.init(); // Manual PostConstruct call
+
+ // Then
+ Mockito.verify(cmpServersConfigLoader).load(startsWith(APP_CONFIG_PATH));
}
@Test
- public void shouldReturnLoadedServersWhenGetCalled() {
+ void shouldReturnLoadedServersWhenGetCalled() throws CmpServersConfigLoadingException {
// Given
Mockito.when(cmpServersConfigLoader.load(any())).thenReturn(SAMPLE_CMP_SERVERS);
- this.cmpServersConfig.loadConfiguration(); // Manual PostConstruct call
+ this.cmpServersConfig.init(); // Manual PostConstruct call
// When
List<Cmpv2Server> receivedCmpServers = this.cmpServersConfig.getCmpServers();
// Then
- assertThat(receivedCmpServers).hasSize(SAMPLE_CMP_SERVERS.size());
+ assertThat(receivedCmpServers).containsAll(SAMPLE_CMP_SERVERS);
}
-} \ No newline at end of file
+
+ @Test
+ void shouldReturnLoadedServersAfterReloadWhenGetCalled() throws CmpServersConfigLoadingException {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenReturn(SAMPLE_CMP_SERVERS);
+ List<Cmpv2Server> receivedCmpServers = this.cmpServersConfig.getCmpServers();
+ assertThat(receivedCmpServers).isNull();
+
+ // When
+ this.cmpServersConfig.reloadConfiguration();
+ receivedCmpServers = this.cmpServersConfig.getCmpServers();
+
+ // Then
+ assertThat(receivedCmpServers).containsAll(SAMPLE_CMP_SERVERS);
+ }
+
+ @Test
+ void shouldRethrowExceptionWhenReloaded() throws CmpServersConfigLoadingException {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenThrow(new CmpServersConfigLoadingException(
+ ERROR_MESSAGE));
+
+ // Then
+ assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> cmpServersConfig.reloadConfiguration());
+ }
+
+ @Test
+ void shouldPassMessageToRethrownErrorWhenReloadingFails() throws CmpServersConfigLoadingException {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenThrow(new CmpServersConfigLoadingException(ERROR_MESSAGE));
+
+ // When
+ Exception exception = assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> cmpServersConfig.reloadConfiguration());
+
+ // Then
+ assertThat(exception.getMessage()).isEqualTo(ERROR_MESSAGE);
+ }
+
+ @Test
+ void shouldNotReturnIakAndRvWhenToStringMethodIsUsed() throws CmpServersConfigLoadingException {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenReturn(SAMPLE_CMP_SERVERS);
+ this.cmpServersConfig.init(); // Manual PostConstruct call
+
+ // When
+ List<Cmpv2Server> receivedCmpServers = this.cmpServersConfig.getCmpServers();
+
+ // Then
+ receivedCmpServers.forEach((server) -> assertThat(server.toString())
+ .doesNotContain(
+ server.getAuthentication().getIak(),
+ server.getAuthentication().getRv()
+ ));
+ }
+
+ @Test
+ void shouldRethrowErrorWhenLoadingFails() throws CmpServersConfigLoadingException {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenThrow(new CmpServersConfigLoadingException(ERROR_MESSAGE));
+
+ // Then
+ assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> cmpServersConfig.loadConfiguration());
+ }
+
+ @Test
+ void shouldPassMessageToRethrownErrorWhenLoadingFails() throws CmpServersConfigLoadingException {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenThrow(new CmpServersConfigLoadingException(ERROR_MESSAGE));
+
+ // When
+ Exception exception = assertThrows(
+ CmpServersConfigLoadingException.class,
+ () -> cmpServersConfig.loadConfiguration());
+
+ // Then
+ assertThat(exception.getMessage()).isEqualTo(ERROR_MESSAGE);
+ }
+
+ private static List<Cmpv2Server> generateTestConfiguration() {
+ Cmpv2Server testServer1 = new Cmpv2Server();
+ testServer1.setCaName("TEST_CA1");
+ testServer1.setIssuerDN(new X500Name("CN=testIssuer"));
+ testServer1.setUrl("http://test.ca.server");
+ Authentication testAuthentication1 = new Authentication();
+ testAuthentication1.setIak("testIak");
+ testAuthentication1.setRv("testRv");
+ testServer1.setAuthentication(testAuthentication1);
+ testServer1.setCaMode(CaMode.RA);
+
+ Cmpv2Server testServer2 = new Cmpv2Server();
+ testServer2.setCaName("TEST_CA2");
+ testServer2.setIssuerDN(new X500Name("CN=testIssuer2"));
+ testServer2.setUrl("http://test.ca.server");
+ Authentication testAuthentication2 = new Authentication();
+ testAuthentication2.setIak("test2Iak");
+ testAuthentication2.setRv("test2Rv");
+ testServer2.setAuthentication(testAuthentication2);
+ testServer2.setCaMode(CaMode.CLIENT);
+
+ return List.of(testServer1, testServer2);
+ }
+
+}
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java
index 18097608..10a7ba46 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java
@@ -20,6 +20,9 @@
package org.onap.aaf.certservice.certification.configuration.validation;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
import org.bouncycastle.asn1.x500.X500Name;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -32,13 +35,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = CertServiceApplication.class)
class Cmpv2ServerConfigurationValidatorTest {
+ private static final String EMPTY_STRING = "";
+
@Autowired
private Cmpv2ServerConfigurationValidator validator;
@@ -52,53 +54,121 @@ class Cmpv2ServerConfigurationValidatorTest {
}
@Test
- public void givenValidServerDetailsWhenValidatingShouldNotThrowAnyException() {
- //then
+ public void shouldNotThrowExceptionWhenServerConfigurationIsValid() {
+ // Then
assertDoesNotThrow(() -> validator.validate(server));
}
@Test
- public void givenWrongProtocolInURLServerDetailsWhenValidatingShouldThrowException() {
- //given
+ public void shouldThrowExceptionWhenWrongProtocolInURL() {
+ // Given
server.setUrl("https://test.test.test:60000/");
- //then
- assertThrows(IllegalArgumentException.class, () -> {validator.validate(server);});
+ // Then
+ assertExceptionIsThrown();
}
@Test
- public void givenWrongPortInURLServerDetailsWhenValidatingShouldThrowException() {
- //given
+ public void shouldThrowExceptionWhenWrongPortInURL() {
+ // Given
server.setUrl("http://test.test.test:70000/");
- //then
- assertThrows(IllegalArgumentException.class, () -> validator.validate(server));
+ // Then
+ assertExceptionIsThrown();
}
@Test
- public void givenWrongCANameLengthInURLServerDetailsWhenValidatingShouldThrowException() {
- //given
- server.setCaName("");
+ public void shouldThrowExceptionWhenWrongCANameLength() {
+ // Given
+ server.setCaName(EMPTY_STRING);
- //then
- assertThrows(IllegalArgumentException.class, () -> validator.validate(server));
+ // Then
+ assertExceptionIsThrown();
}
@Test
- public void givenWrongRVLengthInURLServerDetailsWhenValidatingShouldThrowException() {
- //given
- authentication.setRv("");
+ public void shouldThrowExceptionWhenWrongRVLength() {
+ // Given
+ authentication.setRv(EMPTY_STRING);
- //then
- assertThrows(IllegalArgumentException.class, () -> validator.validate(server));
+ // Then
+ assertExceptionIsThrown();
}
+
@Test
- public void givenWrongIAKLengthInURLServerDetailsWhenValidatingShouldThrowException() {
- //given
- authentication.setIak("");
+ public void shouldThrowExceptionWhenWrongIAKLength() {
+ // Given
+ authentication.setIak(EMPTY_STRING);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenCaNameIsNull() {
+ // Given
+ server.setCaName(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenIssuerDnIsNull() {
+ // Given
+ server.setIssuerDN(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenCaModeIsNull() {
+ // Given
+ server.setCaMode(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenUrlIsNull() {
+ // Given
+ server.setUrl(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenAuthenticationIsNull() {
+ // Given
+ server.setAuthentication(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenIakIsNull() {
+ // Given
+ authentication.setIak(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenRvIsNull() {
+ // Given
+ authentication.setRv(null);
+
+ // Then
+ assertExceptionIsThrown();
+ }
- //then
+ private void assertExceptionIsThrown() {
assertThrows(IllegalArgumentException.class, () -> validator.validate(server));
}
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidatorTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidatorTest.java
index a2a03860..78368d8a 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidatorTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/Cmpv2URLValidatorTest.java
@@ -27,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.*;
class Cmpv2URLValidatorTest {
- private Cmpv2URLValidator validator = new Cmpv2URLValidator();
+ private final Cmpv2URLValidator validator = new Cmpv2URLValidator();
@Test
public void givenCorrectURLWhenValidatingShouldReturnTrue() {
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolationTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolationTest.java
index 8ae4cd88..d1850473 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolationTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/PortNumberViolationTest.java
@@ -27,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.*;
class PortNumberViolationTest {
- private PortNumberViolation violation = new PortNumberViolation();
+ private final PortNumberViolation violation = new PortNumberViolation();
@Test
public void givenValidPortShouldReturnTrue() {
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolationTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolationTest.java
index 9e220560..cba2f340 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolationTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/constraints/violations/RequestTypeViolationTest.java
@@ -26,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.*;
class RequestTypeViolationTest {
- private RequestTypeViolation violation = new RequestTypeViolation();
+ private final RequestTypeViolation violation = new RequestTypeViolation();
@Test
public void givenValidRequestTypeShouldReturnTrue() {
diff --git a/certService/src/test/resources/application.properties b/certService/src/test/resources/application.properties
new file mode 100644
index 00000000..39001571
--- /dev/null
+++ b/certService/src/test/resources/application.properties
@@ -0,0 +1,2 @@
+# AAF CertService app specific configuration
+app.config.path=./src/test/resources
diff --git a/certService/src/test/resources/invalidCmpServers.json b/certService/src/test/resources/invalidCmpServers.json
new file mode 100644
index 00000000..ac4b34af
--- /dev/null
+++ b/certService/src/test/resources/invalidCmpServers.json
@@ -0,0 +1,19 @@
+{
+ "cmpv2Servers": [
+ {
+ "caName": " ",
+ "url": "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
+ "issuerDN": "CN=ManagementCA",
+ "caMode": "CLIENT"
+ },
+ {
+ "caName": "TEST2",
+ "url": "http://127.0.0.1/ejbca/publicweb/cmp/cmpRA",
+ "caMode": "RA",
+ "authentication": {
+ "iak": "xxx",
+ "rv": "yyy"
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/certServiceClient/pom.xml b/certServiceClient/pom.xml
index 5392163c..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>
@@ -173,6 +173,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
</dependencies>
</project> \ No newline at end of file
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 f8867846..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,22 +19,30 @@
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;
import org.onap.aaf.certservice.client.configuration.factory.CsrConfigurationFactory;
import org.onap.aaf.certservice.client.configuration.model.ClientConfiguration;
import org.onap.aaf.certservice.client.configuration.model.CsrConfiguration;
-
-import java.security.KeyPair;
+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 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;
public class CertServiceClient {
+
private AppExitHandler appExitHandler;
public CertServiceClient(AppExitHandler appExitHandler) {
@@ -43,14 +51,31 @@ 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());
+ HttpClient httpClient = new HttpClient(provider, clientConfiguration.getUrlToCertService());
+
+ CertServiceResponse certServiceData =
+ httpClient.retrieveCertServiceData(
+ clientConfiguration.getCaName(),
+ 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());
}
appExitHandler.exit(SUCCESS_EXIT_CODE.getValue());
}
-
}
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 295738f4..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
@@ -22,7 +22,12 @@ public enum ExitCode {
SUCCESS_EXIT_CODE(0),
CLIENT_CONFIGURATION_EXCEPTION(1),
CSR_CONFIGURATION_EXCEPTION(2),
- KEY_PAIR_GENERATION_EXCEPTION(3);
+ KEY_PAIR_GENERATION_EXCEPTION(3),
+ CSR_GENERATION_EXCEPTION(4),
+ CERT_SERVICE_API_CONNECTION_EXCEPTION(5),
+ 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/api/ExitableException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitableException.java
index 51981a48..f9166c96 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitableException.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitableException.java
@@ -26,6 +26,5 @@ public abstract class ExitableException extends Exception {
public ExitableException(String message) {
super(message);
}
-
public abstract int applicationExitCode();
}
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
new file mode 100644
index 00000000..83fa6d44
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java
@@ -0,0 +1,154 @@
+/*============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.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.ExtensionsGenerator;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.pkcs.PKCS10CertificationRequest;
+import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
+
+import org.onap.aaf.certservice.client.certification.exception.CsrGenerationException;
+import org.onap.aaf.certservice.client.configuration.model.CsrConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+import java.util.Base64;
+import java.util.Optional;
+
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.COMMON_NAME;
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.COUNTRY;
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.LOCATION;
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.ORGANIZATION;
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.ORGANIZATION_UNIT;
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.SIGN_ALGORITHM;
+import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.STATE;
+
+
+public class CsrFactory {
+
+ private final Logger LOGGER = LoggerFactory.getLogger(CsrFactory.class);
+ private static final String SANS_DELIMITER = ":";
+ private final CsrConfiguration configuration;
+
+
+ public CsrFactory(CsrConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+
+ 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 convertPKC10CsrToPem(request);
+ }
+
+
+ private StringBuilder getMandatoryParameters() {
+ return new StringBuilder(String.format("%s=%s, %s=%s, %s=%s, %s=%s",
+ COMMON_NAME, configuration.getCommonName(),
+ COUNTRY, configuration.getCountry(),
+ STATE, configuration.getState(),
+ ORGANIZATION, configuration.getOrganization()));
+ }
+
+ private String getOptionalParameters() {
+ StringBuilder optionalParameters = new StringBuilder();
+ Optional.ofNullable(configuration.getOrganizationUnit())
+ .filter(CsrFactory::isParameterPresent)
+ .map(unit -> optionalParameters.append(String.format(", %s=%s", ORGANIZATION_UNIT, unit)));
+ Optional.ofNullable(configuration.getLocation())
+ .filter(CsrFactory::isParameterPresent)
+ .map(location -> optionalParameters.append(String.format(", %s=%s", LOCATION, location)));
+ return optionalParameters.toString();
+ }
+
+ private PKCS10CertificationRequest createPKCS10Csr(X500Principal subject, KeyPair keyPair) throws CsrGenerationException {
+ JcaPKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
+
+ if (isParameterPresent(configuration.getSans())) {
+ builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, generateSansExtension());
+ }
+
+ return builder.build(getContentSigner(keyPair));
+ }
+
+ private ContentSigner getContentSigner(KeyPair keyPair) throws CsrGenerationException {
+ ContentSigner contentSigner;
+ try {
+ contentSigner = new JcaContentSignerBuilder(SIGN_ALGORITHM).build(keyPair.getPrivate());
+ } catch (OperatorCreationException e) {
+ LOGGER.error("Creation of PKCS10Csr failed, exception message: {}", e.getMessage());
+ throw new CsrGenerationException(e);
+
+ }
+ return contentSigner;
+ }
+
+ private String convertPKC10CsrToPem(PKCS10CertificationRequest request) throws CsrGenerationException {
+ final StringWriter stringWriter = new StringWriter();
+ try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) {
+ pemWriter.writeObject(request);
+ } catch (IOException e) {
+ LOGGER.error("Conversion to PEM failed, exception message: {}", e.getMessage());
+ throw new CsrGenerationException(e);
+ }
+ return stringWriter.toString();
+ }
+
+ private Extensions generateSansExtension() throws CsrGenerationException {
+ ExtensionsGenerator generator = new ExtensionsGenerator();
+ try {
+ generator.addExtension(Extension.subjectAlternativeName, false, createGeneralNames());
+ } catch (IOException e) {
+ LOGGER.error("Generation of SANs parameter failed, exception message: {}", e.getMessage());
+ throw new CsrGenerationException(e);
+ }
+ return generator.generate();
+ }
+
+ private GeneralNames createGeneralNames() {
+ String[] sansTable = this.configuration.getSans().split(SANS_DELIMITER);
+ int length = sansTable.length;
+ GeneralName[] generalNames = new GeneralName[length];
+ for (int i = 0; i < length; i++) {
+ generalNames[i] = new GeneralName(GeneralName.dNSName, sansTable[i]);
+ }
+ return new GeneralNames(generalNames);
+ }
+
+ private static Boolean isParameterPresent(String parameter) {
+ return parameter != null && !"".equals(parameter);
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/EncryptionAlgorithmConstants.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/EncryptionAlgorithmConstants.java
index 2afdbee0..96b3650c 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/EncryptionAlgorithmConstants.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/EncryptionAlgorithmConstants.java
@@ -16,9 +16,22 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+
package org.onap.aaf.certservice.client.certification;
-public class EncryptionAlgorithmConstants {
+public final class EncryptionAlgorithmConstants {
+
+ private EncryptionAlgorithmConstants() {}
+
public static final String RSA_ENCRYPTION_ALGORITHM = "RSA";
+ public static final String SIGN_ALGORITHM = "SHA1withRSA";
public static final int KEY_SIZE = 2048;
+
+ public static final String COMMON_NAME = "CN";
+ public static final String ORGANIZATION = "O";
+ public static final String ORGANIZATION_UNIT = "OU";
+ public static final String LOCATION = "L";
+ public static final String STATE = "ST";
+ public static final String COUNTRY = "C";
+
}
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/CsrGenerationException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/CsrGenerationException.java
new file mode 100644
index 00000000..c1d4afd2
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/CsrGenerationException.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 CsrGenerationException extends ExitableException {
+ private static final ExitCode EXIT_CODE = ExitCode.CSR_GENERATION_EXCEPTION;
+
+ public CsrGenerationException(Throwable e) {
+ super(e);
+ }
+
+ public int applicationExitCode() {
+ return EXIT_CODE.getValue();
+ }
+}
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/Base64Encoder.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java
new file mode 100644
index 00000000..1f90db1b
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java
@@ -0,0 +1,28 @@
+/*============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.common;
+
+import org.bouncycastle.util.encoders.Base64;
+
+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/EnvProvider.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvProvider.java
index beccd383..25a152bf 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvProvider.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvProvider.java
@@ -19,8 +19,15 @@
*/
package org.onap.aaf.certservice.client.configuration;
+import java.util.Optional;
+
public class EnvProvider {
- public String readEnvVariable(String envVariable) {
- return System.getProperty(envVariable);
+ public Optional<String> readEnvVariable(String envVariableName) {
+ return Optional.ofNullable(System.getenv(envVariableName))
+ .filter(EnvProvider::isEnvPresent);
+ }
+
+ private static Boolean isEnvPresent(String envValue) {
+ return !"".equals(envValue);
}
}
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 b87df5be..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,17 +27,13 @@ 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) {
return caName.matches("^[a-zA-Z0-9]*$");
}
- public static Boolean isEnvExists(String envValue) {
- return envValue != null && !"".equals(envValue);
- }
-
public static Boolean isCountryValid(String country) {
return country.matches("^([A-Z][A-Z])$");
}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForClient.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForClient.java
index aad64f5b..1ce76370 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForClient.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForClient.java
@@ -19,33 +19,31 @@
*/
package org.onap.aaf.certservice.client.configuration;
+import java.util.Optional;
+
public class EnvsForClient {
- private static final EnvProvider envProvider = new EnvProvider();
- private final String urlToCertService;
- private final String requestTimeOut;
- private final String outputPath;
- private final String caName;
+ private final EnvProvider envProvider = new EnvProvider();
public EnvsForClient() {
- this.urlToCertService = envProvider.readEnvVariable(ClientConfigurationEnvs.REQUEST_URL.toString());
- this.requestTimeOut = envProvider.readEnvVariable(ClientConfigurationEnvs.REQUEST_TIMEOUT.toString());
- this.outputPath = envProvider.readEnvVariable(ClientConfigurationEnvs.OUTPUT_PATH.toString());
- this.caName = envProvider.readEnvVariable(ClientConfigurationEnvs.CA_NAME.toString());
}
- public String getUrlToCertService() {
- return urlToCertService;
+ public Optional<String> getUrlToCertService() {
+ return readEnv(ClientConfigurationEnvs.REQUEST_URL);
+ }
+
+ public Optional<String> getRequestTimeOut() {
+ return readEnv(ClientConfigurationEnvs.REQUEST_TIMEOUT);
}
- public String getRequestTimeOut() {
- return requestTimeOut;
+ public Optional<String> getOutputPath() {
+ return readEnv(ClientConfigurationEnvs.OUTPUT_PATH);
}
- public String getOutputPath() {
- return outputPath;
+ public Optional<String> getCaName() {
+ return readEnv(ClientConfigurationEnvs.CA_NAME);
}
- public String getCaName() {
- return caName;
+ private Optional<String> readEnv(ClientConfigurationEnvs envName) {
+ return envProvider.readEnvVariable(envName.toString());
}
}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForCsr.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForCsr.java
index 0c948d3f..77efc198 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForCsr.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvsForCsr.java
@@ -19,52 +19,42 @@
*/
package org.onap.aaf.certservice.client.configuration;
+import java.util.Optional;
public class EnvsForCsr {
private final EnvProvider envProvider = new EnvProvider();
- private String commonName;
- private String organization;
- private String organizationUnit;
- private String location;
- private String state;
- private String country;
- private String subjectAlternativesName;
- public EnvsForCsr() {
- this.commonName = envProvider.readEnvVariable(CsrConfigurationEnvs.COMMON_NAME.toString());
- this.organization = envProvider.readEnvVariable(CsrConfigurationEnvs.ORGANIZATION.toString());
- this.organizationUnit = envProvider.readEnvVariable(CsrConfigurationEnvs.ORGANIZATION_UNIT.toString());
- this.location = envProvider.readEnvVariable(CsrConfigurationEnvs.LOCATION.toString());
- this.state = envProvider.readEnvVariable(CsrConfigurationEnvs.STATE.toString());
- this.country = envProvider.readEnvVariable(CsrConfigurationEnvs.COUNTRY.toString());
- this.subjectAlternativesName = envProvider.readEnvVariable(CsrConfigurationEnvs.SANS.toString());
+ public EnvsForCsr() {}
+
+ public Optional<String> getCommonName() {
+ return readEnv(CsrConfigurationEnvs.COMMON_NAME);
}
- public String getCommonName() {
- return commonName;
+ public Optional<String> getOrganization() {
+ return readEnv(CsrConfigurationEnvs.ORGANIZATION);
}
- public String getOrganization() {
- return organization;
+ public Optional<String> getOrganizationUnit() {
+ return readEnv(CsrConfigurationEnvs.ORGANIZATION_UNIT);
}
- public String getOrganizationUnit() {
- return organizationUnit;
+ public Optional<String> getLocation() {
+ return readEnv(CsrConfigurationEnvs.LOCATION);
}
- public String getLocation() {
- return location;
+ public Optional<String> getState() {
+ return readEnv(CsrConfigurationEnvs.STATE);
}
- public String getState() {
- return state;
+ public Optional<String> getCountry() {
+ return readEnv(CsrConfigurationEnvs.COUNTRY);
}
- public String getCountry() {
- return country;
+ public Optional<String> getSubjectAlternativesName() {
+ return readEnv(CsrConfigurationEnvs.SANS);
}
- public String getSubjectAlternativesName() {
- return subjectAlternativesName;
+ private Optional<String> readEnv(CsrConfigurationEnvs envName) {
+ return envProvider.readEnvVariable(envName.toString());
}
}
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 96b1fb8b..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;
@@ -42,18 +43,18 @@ public class ClientConfigurationFactory implements AbstractConfigurationFactory<
ClientConfiguration configuration = new ClientConfiguration();
- Optional.ofNullable(envsForClient.getUrlToCertService()).filter(EnvValidationUtils::isEnvExists)
+ envsForClient.getUrlToCertService()
.map(configuration::setUrlToCertService);
- Optional.ofNullable(envsForClient.getRequestTimeOut()).filter(EnvValidationUtils::isEnvExists)
+ envsForClient.getRequestTimeOut()
.map(timeout -> configuration.setRequestTimeout(Integer.valueOf(timeout)));
- Optional.ofNullable(envsForClient.getOutputPath()).filter(EnvValidationUtils::isEnvExists)
+ envsForClient.getOutputPath()
.filter(EnvValidationUtils::isPathValid)
.map(configuration::setCertsOutputPath)
.orElseThrow(() -> new ClientConfigurationException(ClientConfigurationEnvs.OUTPUT_PATH + " is invalid."));
- Optional.ofNullable(envsForClient.getCaName()).filter(EnvValidationUtils::isEnvExists)
+ envsForClient.getCaName()
.filter(EnvValidationUtils::isAlphaNumeric)
.map(configuration::setCaName)
.orElseThrow(() -> new ClientConfigurationException(ClientConfigurationEnvs.CA_NAME + " is invalid."));
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/CsrConfigurationFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/CsrConfigurationFactory.java
index 61e1b3c3..1e5d5c53 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/CsrConfigurationFactory.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/CsrConfigurationFactory.java
@@ -43,32 +43,32 @@ public class CsrConfigurationFactory implements AbstractConfigurationFactory<Csr
CsrConfiguration configuration = new CsrConfiguration();
- Optional.ofNullable(envsForCsr.getCommonName()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getCommonName()
.filter(EnvValidationUtils::isCommonNameValid)
.map(configuration::setCommonName)
.orElseThrow(() -> new CsrConfigurationException(CsrConfigurationEnvs.COMMON_NAME + " is invalid."));
- Optional.ofNullable(envsForCsr.getOrganization()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getOrganization()
.filter(org -> !EnvValidationUtils.isSpecialCharsPresent(org))
.map(configuration::setOrganization)
.orElseThrow(() -> new CsrConfigurationException(CsrConfigurationEnvs.ORGANIZATION + " is invalid."));
- Optional.ofNullable(envsForCsr.getState()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getState()
.map(configuration::setState)
.orElseThrow(() -> new CsrConfigurationException(CsrConfigurationEnvs.STATE + " is invalid."));
- Optional.ofNullable(envsForCsr.getCountry()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getCountry()
.filter(EnvValidationUtils::isCountryValid)
.map(configuration::setCountry)
.orElseThrow(() -> new CsrConfigurationException(CsrConfigurationEnvs.COUNTRY + " is invalid."));
- Optional.ofNullable(envsForCsr.getOrganizationUnit()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getOrganizationUnit()
.map(configuration::setOrganizationUnit);
- Optional.ofNullable(envsForCsr.getLocation()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getLocation()
.map(configuration::setLocation);
- Optional.ofNullable(envsForCsr.getSubjectAlternativesName()).filter(EnvValidationUtils::isEnvExists)
+ envsForCsr.getSubjectAlternativesName()
.map(configuration::setSubjectAlternativeNames);
return configuration;
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/CsrConfiguration.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/CsrConfiguration.java
index 30caf42a..aaaf10fa 100644
--- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/CsrConfiguration.java
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/model/CsrConfiguration.java
@@ -29,7 +29,7 @@ public class CsrConfiguration implements ConfigurationModel {
private String country;
private String organizationUnit;
private String location;
- private String subjectAlternativeNames;
+ private String sans;
public String getCommonName() {
@@ -86,12 +86,12 @@ public class CsrConfiguration implements ConfigurationModel {
return this;
}
- public String getSubjectAlternativeNames() {
- return subjectAlternativeNames;
+ public String getSans() {
+ return sans;
}
public CsrConfiguration setSubjectAlternativeNames(String subjectAlternativeNames) {
- this.subjectAlternativeNames = subjectAlternativeNames;
+ this.sans = subjectAlternativeNames;
return this;
}
}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/CloseableHttpClientProvider.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/CloseableHttpClientProvider.java
new file mode 100644
index 00000000..ff29a14d
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/CloseableHttpClientProvider.java
@@ -0,0 +1,40 @@
+/*
+ * ============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.httpclient;
+
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+
+public class CloseableHttpClientProvider {
+
+ private final int timeout;
+
+ public CloseableHttpClientProvider(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public CloseableHttpClient getClient() {
+ RequestConfig config =
+ RequestConfig.custom().setConnectionRequestTimeout(timeout).build();
+ return HttpClientBuilder.create().setDefaultRequestConfig(config).build();
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/HttpClient.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/HttpClient.java
new file mode 100644
index 00000000..30f881bb
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/HttpClient.java
@@ -0,0 +1,117 @@
+/*
+ * ============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.httpclient;
+
+import com.google.gson.Gson;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.onap.aaf.certservice.client.httpclient.exception.CertServiceApiResponseException;
+import org.onap.aaf.certservice.client.httpclient.exception.HttpClientException;
+import org.onap.aaf.certservice.client.httpclient.model.CertServiceResponse;
+import org.onap.aaf.certservice.client.httpclient.model.ErrorCertServiceResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+public class HttpClient {
+
+ private static final String CSR_HEADER_NAME = "CSR";
+ private static final String PK_HEADER_NAME = "PK";
+ private static final String CHARSET_UTF_8 = "UTF-8";
+
+ private final Logger LOGGER = LoggerFactory.getLogger(HttpClient.class);
+
+ private final Gson gson = new Gson();
+ private final CloseableHttpClientProvider httpClientProvider;
+ private final String certServiceAddress;
+
+ public HttpClient(CloseableHttpClientProvider httpClientProvider, String certServiceAddress) {
+ this.httpClientProvider = httpClientProvider;
+ this.certServiceAddress = certServiceAddress;
+ }
+
+ public CertServiceResponse retrieveCertServiceData(String caName, String csr, String encodedPk)
+ throws CertServiceApiResponseException, HttpClientException {
+
+ try (CloseableHttpClient httpClient = httpClientProvider.getClient()) {
+ LOGGER.info("Sending request to API. Url: {}{} ", certServiceAddress, caName);
+ HttpResponse httpResponse = httpClient.execute(createHttpRequest(caName, csr, encodedPk));
+ LOGGER.info("Received response from API");
+ return extractCertServiceResponse(httpResponse);
+
+ } catch (IOException e) {
+ LOGGER.error("Failed execute request to API for URL: {}{} . Exception message: {}",
+ certServiceAddress, caName, e.getMessage());
+ throw new HttpClientException(e);
+ }
+ }
+
+ private int getStatusCode(HttpResponse httpResponse) {
+ return httpResponse.getStatusLine().getStatusCode();
+ }
+
+ private CertServiceResponse extractCertServiceResponse(HttpResponse httpResponse)
+ throws CertServiceApiResponseException, HttpClientException {
+ int httpResponseCode = getStatusCode(httpResponse);
+ if (HttpStatus.SC_OK != httpResponseCode) {
+ LOGGER.error("Error on API response. Response Code: {}", httpResponseCode);
+ throw generateApiResponseException(httpResponse);
+ }
+ String jsonResponse = getStringResponse(httpResponse.getEntity());
+ return gson.fromJson(jsonResponse, CertServiceResponse.class);
+ }
+
+ private String getStringResponse(HttpEntity httpEntity) throws HttpClientException {
+ try {
+ return EntityUtils.toString(httpEntity, CHARSET_UTF_8);
+ } catch (IOException e) {
+ LOGGER.error("Cannot parse response to string", e);
+ throw new HttpClientException(e);
+ }
+ }
+
+ private HttpGet createHttpRequest(String caName, String csr, String pk) {
+ String url = certServiceAddress + caName;
+ HttpGet httpGet = new HttpGet(url);
+ httpGet.addHeader(CSR_HEADER_NAME, csr);
+ httpGet.addHeader(PK_HEADER_NAME, pk);
+ return httpGet;
+ }
+
+
+ private CertServiceApiResponseException generateApiResponseException(HttpResponse httpResponse)
+ throws HttpClientException {
+ String stringResponse = getStringResponse(httpResponse.getEntity());
+ ErrorCertServiceResponse errorCertServiceResponse =
+ gson.fromJson(stringResponse, ErrorCertServiceResponse.class);
+
+ String messageFromApi = errorCertServiceResponse.getMessage();
+ String path = errorCertServiceResponse.getPath();
+ int httpResponseCode = getStatusCode(httpResponse);
+
+ return new CertServiceApiResponseException(certServiceAddress + path, httpResponseCode, messageFromApi);
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/CertServiceApiResponseException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/CertServiceApiResponseException.java
new file mode 100644
index 00000000..40470af3
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/CertServiceApiResponseException.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.httpclient.exception;
+
+import org.onap.aaf.certservice.client.api.ExitCode;
+import org.onap.aaf.certservice.client.api.ExitableException;
+
+public class CertServiceApiResponseException extends ExitableException {
+ private final ExitCode EXIT_CODE = ExitCode.CERT_SERVICE_API_CONNECTION_EXCEPTION;
+
+ public CertServiceApiResponseException(String url, int responseCode, String messageFromAPI) {
+
+ super(String.format("Request failed for URL '%s'. Response code: %d . Message from API: %s",
+ url,
+ responseCode,
+ messageFromAPI));
+ }
+
+ @Override
+ public int applicationExitCode() {
+ return EXIT_CODE.getValue();
+ }
+
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/HttpClientException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/HttpClientException.java
new file mode 100644
index 00000000..d6fb1461
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/exception/HttpClientException.java
@@ -0,0 +1,37 @@
+/*
+ * ============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.httpclient.exception;
+
+import org.onap.aaf.certservice.client.api.ExitCode;
+import org.onap.aaf.certservice.client.api.ExitableException;
+
+public class HttpClientException extends ExitableException {
+ private final ExitCode EXIT_CODE = ExitCode.HTTP_CLIENT_EXCEPTION;
+
+ public HttpClientException(Throwable e) {
+ super(e);
+ }
+
+ @Override
+ public int applicationExitCode() {
+ return EXIT_CODE.getValue();
+ }
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/CertServiceResponse.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/CertServiceResponse.java
new file mode 100644
index 00000000..4ca17999
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/CertServiceResponse.java
@@ -0,0 +1,44 @@
+/*
+ * ============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.httpclient.model;
+
+import java.util.Collections;
+import java.util.List;
+
+public class CertServiceResponse {
+
+ private final List<String> certificateChain;
+ private final List<String> trustedCertificates;
+
+ public CertServiceResponse(List<String> certificateChain, List<String> trustedCertificates) {
+ this.certificateChain = certificateChain;
+ this.trustedCertificates = trustedCertificates;
+ }
+
+ public List<String> getCertificateChain() {
+ return Collections.unmodifiableList(certificateChain);
+ }
+
+ public List<String> getTrustedCertificates() {
+ return Collections.unmodifiableList(trustedCertificates);
+ }
+
+}
diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/ErrorCertServiceResponse.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/ErrorCertServiceResponse.java
new file mode 100644
index 00000000..6fe99ce5
--- /dev/null
+++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/httpclient/model/ErrorCertServiceResponse.java
@@ -0,0 +1,40 @@
+/*
+ * ============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.httpclient.model;
+
+public class ErrorCertServiceResponse {
+
+ private final String message;
+ private final String path;
+
+ public ErrorCertServiceResponse(String message, String path) {
+ this.message = message;
+ this.path = path;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getPath() {
+ return path;
+ }
+}
diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/CerServiceRequestTestData.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/CerServiceRequestTestData.java
new file mode 100644
index 00000000..8f252c31
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/CerServiceRequestTestData.java
@@ -0,0 +1,89 @@
+/*
+ * ============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;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public final class CerServiceRequestTestData {
+
+ private static final String RESOURCE_PATH = "src/test/resources/";
+
+ // Request parameters
+ public static final String CA_NAME = "TestCA";
+ public static final String CSR = getCsrValue();
+ public static final String PK = getPkValue();
+
+ // Correct response data
+ public static final String CORRECT_RESPONSE = getCorrectResponse();
+ public static final String EXPECTED_FIRST_ELEMENT_OF_CERTIFICATE_CHAIN =
+ getExpectedFirstElementOfCertificateChain();
+ public static final String EXPECTED_FIRST_ELEMENT_OF_TRUSTED_CERTIFICATES =
+ getExpectedFirstElementOfTrustedCertificates();
+
+ // Error response data
+ public static final String MISSING_PK_RESPONSE = getMissingPkResponse();
+
+ private CerServiceRequestTestData() {
+ }
+
+ private static String getMissingPkResponse() {
+ String fileName = "missingPkResponse";
+ return readFromFile(RESOURCE_PATH + fileName);
+ }
+
+ private static String getExpectedFirstElementOfTrustedCertificates() {
+
+ String fileName = "expectedFirstElementOfTrustedCertificates";
+ return readFromFile(RESOURCE_PATH + fileName);
+ }
+
+ private static String getExpectedFirstElementOfCertificateChain() {
+ String fileName = "expectedFirstElementOfCertificateChain";
+ return readFromFile(RESOURCE_PATH + fileName);
+ }
+
+ private static String getCorrectResponse() {
+ String fileName = "correctResponse";
+ return readFromFile(RESOURCE_PATH + fileName);
+ }
+
+ private static String getPkValue() {
+ String fileName = "testPk";
+ return readFromFile(RESOURCE_PATH + fileName);
+ }
+
+ private static String getCsrValue() {
+ String fileName = "testCsr";
+ return readFromFile(RESOURCE_PATH + fileName);
+ }
+
+ private static String readFromFile(String path) {
+ try {
+ return Files.readString(Paths.get(path), StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return "File not found";
+ }
+ }
+}
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
new file mode 100644
index 00000000..809a91f2
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java
@@ -0,0 +1,58 @@
+/*============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.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.client.certification.exception.CsrGenerationException;
+import org.onap.aaf.certservice.client.certification.exception.KeyPairGenerationException;
+import org.onap.aaf.certservice.client.configuration.model.CsrConfiguration;
+
+import java.security.KeyPair;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+
+public class CsrFactoryTest {
+
+ CsrConfiguration config = mock(CsrConfiguration.class);
+
+
+
+ @Test
+ void createEncodedCsr_shouldSucceedWhenAllFieldsAreSetCorrectly() throws KeyPairGenerationException, CsrGenerationException {
+
+ KeyPair keyPair =
+ new KeyPairFactory(EncryptionAlgorithmConstants.RSA_ENCRYPTION_ALGORITHM, EncryptionAlgorithmConstants.KEY_SIZE).create();
+
+ when(config.getCommonName()).thenReturn("onap.org");
+ when(config.getSans()).thenReturn("onapexample.com:onapexample.com.pl:onapexample.pl");
+ when(config.getCountry()).thenReturn("US");
+ when(config.getLocation()).thenReturn("San-Francisco");
+ when(config.getOrganization()).thenReturn("Linux-Foundation");
+ when(config.getOrganizationUnit()).thenReturn("ONAP");
+ when(config.getState()).thenReturn("California");
+
+ 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/ClientConfigurationFactoryTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java
index f355de1a..2c875c24 100644
--- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/ClientConfigurationFactoryTest.java
@@ -26,6 +26,8 @@ import org.onap.aaf.certservice.client.configuration.EnvsForClient;
import org.onap.aaf.certservice.client.configuration.exception.ClientConfigurationException;
import org.onap.aaf.certservice.client.configuration.factory.ClientConfigurationFactory;
+import java.util.Optional;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
@@ -33,22 +35,22 @@ import static org.mockito.Mockito.when;
public class ClientConfigurationFactoryTest {
- final String CA_NAME_VALID = "caaaftest2";
- final String TIME_OUT_VALID = "30000";
- final String OUTPUT_PATH_VALID = "/opt/app/osaaf";
- final String URL_TO_CERT_SERVICE_VALID = "http://cert-service:8080/v1/certificate/";
- final String CA_NAME_INVALID = "caaaftest2#$";
- final String OUTPUT_PATH_INVALID = "/opt//app/osaaf";
+ private final String CA_NAME_VALID = "caaaftest2";
+ private final String TIME_OUT_VALID = "30000";
+ private final String OUTPUT_PATH_VALID = "/opt/app/osaaf";
+ private final String URL_TO_CERT_SERVICE_VALID = "http://cert-service:8080/v1/certificate/";
+ private final String CA_NAME_INVALID = "caaaftest2#$";
+ private final String OUTPUT_PATH_INVALID = "/opt//app/osaaf";
private EnvsForClient envsForClient = mock(EnvsForClient.class);
@Test
void create_shouldReturnSuccessWhenAllVariablesAreSetAndValid() throws ClientConfigurationException {
// given
- when(envsForClient.getCaName()).thenReturn(CA_NAME_VALID);
- when(envsForClient.getOutputPath()).thenReturn(OUTPUT_PATH_VALID);
- when(envsForClient.getRequestTimeOut()).thenReturn(TIME_OUT_VALID);
- when(envsForClient.getUrlToCertService()).thenReturn(URL_TO_CERT_SERVICE_VALID);
+ when(envsForClient.getCaName()).thenReturn(Optional.of(CA_NAME_VALID));
+ when(envsForClient.getOutputPath()).thenReturn(Optional.of(OUTPUT_PATH_VALID));
+ when(envsForClient.getRequestTimeOut()).thenReturn(Optional.of(TIME_OUT_VALID));
+ when(envsForClient.getUrlToCertService()).thenReturn(Optional.of(URL_TO_CERT_SERVICE_VALID));
// when
ClientConfiguration configuration = new ClientConfigurationFactory(envsForClient).create();
@@ -63,8 +65,8 @@ public class ClientConfigurationFactoryTest {
@Test
void create_shouldReturnSuccessWhenDefaultVariablesAreNotSet() throws ClientConfigurationException {
// given
- when(envsForClient.getCaName()).thenReturn(CA_NAME_VALID);
- when(envsForClient.getOutputPath()).thenReturn(OUTPUT_PATH_VALID);
+ when(envsForClient.getCaName()).thenReturn(Optional.of(CA_NAME_VALID));
+ when(envsForClient.getOutputPath()).thenReturn(Optional.of(OUTPUT_PATH_VALID));
// when
ClientConfiguration configuration = new ClientConfigurationFactory(envsForClient).create();
@@ -79,7 +81,7 @@ public class ClientConfigurationFactoryTest {
@Test
void create_shouldReturnClientExceptionWhenRequiredVariableIsNotSet() {
// given
- when(envsForClient.getOutputPath()).thenReturn(OUTPUT_PATH_VALID);
+ when(envsForClient.getOutputPath()).thenReturn(Optional.of(OUTPUT_PATH_VALID));
// when
ClientConfigurationFactory configurationFactory = new ClientConfigurationFactory(envsForClient);
@@ -93,10 +95,10 @@ public class ClientConfigurationFactoryTest {
@Test
void create_shouldReturnClientExceptionWhenCANameContainsSpecialCharacters() {
// given
- when(envsForClient.getCaName()).thenReturn(CA_NAME_INVALID);
- when(envsForClient.getOutputPath()).thenReturn(OUTPUT_PATH_VALID);
- when(envsForClient.getRequestTimeOut()).thenReturn(TIME_OUT_VALID);
- when(envsForClient.getUrlToCertService()).thenReturn(URL_TO_CERT_SERVICE_VALID);
+ when(envsForClient.getCaName()).thenReturn(Optional.of(CA_NAME_INVALID));
+ when(envsForClient.getOutputPath()).thenReturn(Optional.of(OUTPUT_PATH_VALID));
+ when(envsForClient.getRequestTimeOut()).thenReturn(Optional.of(TIME_OUT_VALID));
+ when(envsForClient.getUrlToCertService()).thenReturn(Optional.of(URL_TO_CERT_SERVICE_VALID));
// when
ClientConfigurationFactory configurationFactory = new ClientConfigurationFactory(envsForClient);
@@ -110,10 +112,10 @@ public class ClientConfigurationFactoryTest {
@Test
void create_shouldReturnClientExceptionWhenOutputPathContainsSpecialCharacters() {
// given
- when(envsForClient.getCaName()).thenReturn(CA_NAME_VALID);
- when(envsForClient.getOutputPath()).thenReturn(OUTPUT_PATH_INVALID);
- when(envsForClient.getRequestTimeOut()).thenReturn(TIME_OUT_VALID);
- when(envsForClient.getUrlToCertService()).thenReturn(URL_TO_CERT_SERVICE_VALID);
+ when(envsForClient.getCaName()).thenReturn(Optional.of(CA_NAME_VALID));
+ when(envsForClient.getOutputPath()).thenReturn(Optional.of(OUTPUT_PATH_INVALID));
+ when(envsForClient.getRequestTimeOut()).thenReturn(Optional.of(TIME_OUT_VALID));
+ when(envsForClient.getUrlToCertService()).thenReturn(Optional.of(URL_TO_CERT_SERVICE_VALID));
// when
ClientConfigurationFactory configurationFactory = new ClientConfigurationFactory(envsForClient);
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 d6bf431b..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,12 +20,18 @@
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;
import static org.mockito.Mockito.mock;
@@ -33,35 +39,42 @@ import static org.mockito.Mockito.when;
public class CsrConfigurationFactoryTest {
- final String COMMON_NAME_VALID = "onap.org";
- final String SANS_VALID = "test-name";
- final String COUNTRY_VALID = "US";
- final String LOCATION_VALID = "San-Francisco";
- final String ORGANIZATION_VALID = "Linux-Foundation";
- final String ORGANIZATION_UNIT_VALID = "ONAP";
- final String STATE_VALID = "California";
- final String COMMON_NAME_INVALID = "onap.org*&";
+ private final String COMMON_NAME_VALID = "onap.org";
+ private final String SANS_VALID = "test-name";
+ private final String COUNTRY_VALID = "US";
+ private final String LOCATION_VALID = "San-Francisco";
+ private final String ORGANIZATION_VALID = "Linux-Foundation";
+ 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(COMMON_NAME_VALID);
- when(envsForCsr.getSubjectAlternativesName()).thenReturn(SANS_VALID);
- when(envsForCsr.getCountry()).thenReturn(COUNTRY_VALID);
- when(envsForCsr.getLocation()).thenReturn(LOCATION_VALID);
- when(envsForCsr.getOrganization()).thenReturn(ORGANIZATION_VALID);
- when(envsForCsr.getOrganizationUnit()).thenReturn(ORGANIZATION_UNIT_VALID);
- when(envsForCsr.getState()).thenReturn(STATE_VALID);
+ mockEnvsWithAllValidParameters();
// when
- CsrConfiguration configuration = new CsrConfigurationFactory(envsForCsr).create();
+ CsrConfiguration configuration = testedFactory.create();
// then
assertThat(configuration.getCommonName()).isEqualTo(COMMON_NAME_VALID);
- assertThat(configuration.getSubjectAlternativeNames()).isEqualTo(SANS_VALID);
+ assertThat(configuration.getSans()).isEqualTo(SANS_VALID);
assertThat(configuration.getCountry()).isEqualTo(COUNTRY_VALID);
assertThat(configuration.getLocation()).isEqualTo(LOCATION_VALID);
assertThat(configuration.getOrganization()).isEqualTo(ORGANIZATION_VALID);
@@ -70,15 +83,12 @@ public class CsrConfigurationFactoryTest {
}
@Test
- void create_shouldReturnSuccessWhenNotRequiredVariablesAreNotSet() throws CsrConfigurationException {
+ void shouldReturnCorrectConfiguration_WhenNotRequiredVariablesAreNotSet() throws CsrConfigurationException {
// given
- when(envsForCsr.getCommonName()).thenReturn(COMMON_NAME_VALID);
- when(envsForCsr.getState()).thenReturn(STATE_VALID);
- when(envsForCsr.getCountry()).thenReturn(COUNTRY_VALID);
- when(envsForCsr.getOrganization()).thenReturn(ORGANIZATION_VALID);
+ mockEnvsWithValidRequiredParameters();
// when
- CsrConfiguration configuration = new CsrConfigurationFactory(envsForCsr).create();
+ CsrConfiguration configuration = testedFactory.create();
// then
assertThat(configuration.getCommonName()).isEqualTo(COMMON_NAME_VALID);
@@ -89,22 +99,89 @@ public class CsrConfigurationFactoryTest {
@Test
- void create_shouldReturnCsrConfigurationExceptionWhenCommonNameContainsSpecialCharacters() {
+ void shouldThrowCsrConfigurationException_WhenCommonNameInvalid() {
// given
- when(envsForCsr.getCommonName()).thenReturn(COMMON_NAME_INVALID);
- when(envsForCsr.getSubjectAlternativesName()).thenReturn(SANS_VALID);
- when(envsForCsr.getCountry()).thenReturn(COUNTRY_VALID);
- when(envsForCsr.getLocation()).thenReturn(LOCATION_VALID);
- when(envsForCsr.getOrganization()).thenReturn(ORGANIZATION_VALID);
- when(envsForCsr.getOrganizationUnit()).thenReturn(ORGANIZATION_UNIT_VALID);
- when(envsForCsr.getState()).thenReturn(SANS_VALID);
+ mockEnvsWithInvalidCommonName();
- // when
- CsrConfigurationFactory configurationFactory = new CsrConfigurationFactory(envsForCsr);
+ // 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(configurationFactory::create)
- .withMessageContaining(CsrConfigurationEnvs.COMMON_NAME + " is invalid.");
+ .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.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID));
+ when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID));
+ }
+
+ private void mockEnvsWithInvalidCommonName() {
+ mockEnvsWithAllValidParameters();
+ when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_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/java/org/onap/aaf/certservice/client/httpclient/HttpClientTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/httpclient/HttpClientTest.java
new file mode 100644
index 00000000..461b7a34
--- /dev/null
+++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/httpclient/HttpClientTest.java
@@ -0,0 +1,157 @@
+/*
+ * ============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.httpclient;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.StatusLine;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+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.httpclient.exception.CertServiceApiResponseException;
+import org.onap.aaf.certservice.client.httpclient.exception.HttpClientException;
+import org.onap.aaf.certservice.client.httpclient.model.CertServiceResponse;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.CA_NAME;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.CORRECT_RESPONSE;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.CSR;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.EXPECTED_FIRST_ELEMENT_OF_CERTIFICATE_CHAIN;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.EXPECTED_FIRST_ELEMENT_OF_TRUSTED_CERTIFICATES;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.MISSING_PK_RESPONSE;
+import static org.onap.aaf.certservice.client.CerServiceRequestTestData.PK;
+
+class HttpClientTest {
+
+ private HttpClient httpClient;
+ private CloseableHttpClient closeableHttpClient;
+ private HttpEntity httpEntity;
+ private StatusLine statusLine;
+ private CloseableHttpResponse httpResponse;
+
+ @BeforeEach
+ void setUp() {
+
+ closeableHttpClient = mock(CloseableHttpClient.class);
+ httpEntity = mock(HttpEntity.class);
+ statusLine = mock(StatusLine.class);
+ httpResponse = mock(CloseableHttpResponse.class);
+
+ CloseableHttpClientProvider httpClientProvider = mock(CloseableHttpClientProvider.class);
+
+ when(httpClientProvider.getClient()).thenReturn(closeableHttpClient);
+ String testCertServiceAddress = "";
+ httpClient = new HttpClient(httpClientProvider, testCertServiceAddress);
+ }
+
+ @Test
+ void shouldReturnCorrectListsOfCertificatedChainsAndTrustedCertificates_WhenRequestDataIsCorrect()
+ throws Exception {
+
+ // given
+ mockServerResponse(HTTP_OK, CORRECT_RESPONSE);
+
+ // when
+ CertServiceResponse certServiceResponse =
+ httpClient.retrieveCertServiceData(CA_NAME, CSR, PK);
+ List<String> certificateChain = certServiceResponse.getCertificateChain();
+ List<String> trustedCertificate = certServiceResponse.getTrustedCertificates();
+
+ // then
+ assertNotNull(certServiceResponse);
+
+ final int expectedTwoElements = 2;
+ assertEquals(expectedTwoElements, certificateChain.size());
+ assertEquals(expectedTwoElements, trustedCertificate.size());
+
+ assertEquals(EXPECTED_FIRST_ELEMENT_OF_CERTIFICATE_CHAIN, certificateChain.get(0));
+ assertEquals(EXPECTED_FIRST_ELEMENT_OF_TRUSTED_CERTIFICATES, trustedCertificate.get(0));
+ }
+
+ @Test
+ void shouldThrowCertServiceApiResponseException_WhenPkHeaderIsMissing() throws Exception {
+
+ // given
+ mockServerResponse(HTTP_BAD_REQUEST, MISSING_PK_RESPONSE);
+
+ // when
+ CertServiceApiResponseException exception =
+ assertThrows(CertServiceApiResponseException.class,
+ () -> httpClient.retrieveCertServiceData(CA_NAME, CSR, ""));
+
+ // then
+ assertEquals(ExitCode.CERT_SERVICE_API_CONNECTION_EXCEPTION.getValue(), exception.applicationExitCode());
+ }
+
+ @Test
+ void shouldThrowHttpClientException_WhenCannotExecuteRequestToAPI() throws Exception{
+
+ //given
+ when(closeableHttpClient.execute(any(HttpGet.class))).thenThrow(IOException.class);
+
+ //when
+ HttpClientException exception =
+ assertThrows(HttpClientException.class,
+ () -> httpClient.retrieveCertServiceData(CA_NAME, CSR, ""));
+
+ //then
+ assertEquals(ExitCode.HTTP_CLIENT_EXCEPTION.getValue(), exception.applicationExitCode());
+ }
+
+ @Test
+ void shouldThrowHttpClientException_WhenCannotParseResponseToString() throws Exception{
+
+ //given
+ mockServerResponse(HTTP_OK, CORRECT_RESPONSE);
+ when(httpEntity.getContent()).thenThrow(IOException.class);
+
+ //when
+ HttpClientException exception =
+ assertThrows(HttpClientException.class,
+ () -> httpClient.retrieveCertServiceData(CA_NAME, CSR, ""));
+
+ //then
+ assertEquals(ExitCode.HTTP_CLIENT_EXCEPTION.getValue(), exception.applicationExitCode());
+ }
+
+ private void mockServerResponse(int serverCodeResponse, String stringResponse)
+ throws IOException {
+ when(statusLine.getStatusCode()).thenReturn(serverCodeResponse);
+ when(httpResponse.getStatusLine()).thenReturn(statusLine);
+ when(httpResponse.getEntity()).thenReturn(httpEntity);
+ when(closeableHttpClient.execute(any(HttpGet.class))).thenReturn(httpResponse);
+
+ when(httpEntity.getContent()).thenReturn(new ByteArrayInputStream(stringResponse.getBytes()));
+ }
+}
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/correctResponse b/certServiceClient/src/test/resources/correctResponse
new file mode 100644
index 00000000..c7bf349e
--- /dev/null
+++ b/certServiceClient/src/test/resources/correctResponse
@@ -0,0 +1,10 @@
+{
+ "certificateChain": [
+ "-----BEGIN CERTIFICATE-----\nMIIDjDCCAnSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\nFwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQD\nDBVpbnRlcm1lZGlhdGUub25hcC5vcmcwHhcNMjAwMjEyMDk1MTI2WhcNMjIxMTA4\nMDk1MTI2WjB7MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\nA1UEBwwNU2FuLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjEN\nMAsGA1UECwwET05BUDEVMBMGA1UEAwwMdmlkLm9uYXAub3JnMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+GIRzJzUOh0gtc+wzFJEdTnn+q5F10L0Yhr\nG1xKdjPieHIFGsoiXwcuCU8arNSqlz7ocx62KQRkcA8y6edlOAsYtdOEJvqEI9vc\neyTB/HYsbzw3URPGch4AmibrQkKU9QvGwouHtHn4R2Ft2Y0tfEqv9hxj9v4njq4A\nEiDLAFLl5FmVyCZu/MtKngSgu1smcaFKTYySPMxytgJZexoa/ALZyyE0gRhsvwHm\nNLGCPt1bmE/PEGZybsCqliyTO0S56ncD55The7+D/UDS4kE1Wg0svlWon/YsE6QW\nB3oeJDX7Kr8ebDTIAErevIAD7Sm4ee5se2zxYrsYlj0MzHZtvwIDAQABoxAwDjAM\nBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvQ1pTvjON6vSlcJRKSY4r\n8q7L4/9ZaVXWJAjzEYJtPIqsgGiPWz0vGfgklowU6tZxp9zRZFXfMil+mPQSe+yo\nULrZSQ/z48YHPueE/BNO/nT4aaVBEhPLR5aVwC7uQVX8H+m1V1UGT8lk9vdI9rej\nCI9l524sLCpdE4dFXiWK2XHEZ0Vfylk221u3IYEogVVA+UMX7BFPSsOnI2vtYK/i\nlwZtlri8LtTusNe4oiTkYyq+RSyDhtAswg8ANgvfHolhCHoLFj6w1IkG88UCmbwN\nd7BoGMy06y5MJxyXEZG0vR7eNeLey0TIh+rAszAFPsIQvrOHW+HuA+WLQAj1mhnm\n-----END CERTIFICATE-----",
+ "-----BEGIN CERTIFICATE-----\nMIIDqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\nFwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMREwDwYDVQQD\nDAhvbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVyQG9uYXAub3JnMB4XDTIw\nMDIxMjA5NDAxMloXDTIyMTEwODA5NDAxMlowgYQxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkwFwYDVQQK\nDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQDDBVpbnRl\ncm1lZGlhdGUub25hcC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQC1oOYMZ6G+2DGDAizYnzdCNiogivlht1s4oqgem7fM1XFPxD2p31ATIibOdqr/\ngv1qemO9Q4r1xn6w1Ufq7T1K7PjnMzdSeTqZefurE2JM/HHx2QvW4TjMlz2ILgaD\nL1LN60kmMQSOi5VxKJpsrCQxbOsxhvefd212gny5AZMcjJe23kUd9OxUrtvpdLEv\nwI3vFEvT7oRUnEUg/XNz7qeg33vf1C39yMR+6O4s6oevgsEebVKjb+yOoS6zzGtz\n72wZjm07C54ZlO+4Uy+QAlMjRiU3mgWkKbkOy+4CvwehjhpTikdBs2DX39ZLGHhn\nL/0a2NYtGulp9XEqmTvRoI+PAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI\nhvcNAQELBQADggEBADcitdJ6YswiV8jAD9GK0gf3+zqcGegt4kt+79JXlXYbb1sY\nq3o6prcB7nSUoClgF2xUPCslFGpM0Er9FCSFElQM/ru0l/KVmJS6kSpwEHvsYIH3\nq5anta+Pyk8JSQWAAw+qrind0uBQMnhR8Tn13tgV+Kjvg/xlH/nZIEdN5YtLB1cA\nbeVsZRyRfVL9DeZU8s/MZ5wC3kgcEp5A4m5lg7HyBxBdqhzFcDr6xiy6OGqW8Yep\nxrwfc8Fw8a/lOv4U+tBeGNKPQDYaL9hh+oM+qMkNXsHXDqdJsuEGJtU4i3Wcwzoc\nXGN5NWV//4bP+NFmwgcn7AYCdRvz04A8GU/0Cwg=\n-----END CERTIFICATE-----"
+ ],
+ "trustedCertificates": [
+ "-----BEGIN CERTIFICATE-----\nMIIDtzCCAp8CFAwqQddh4/iyGfP8UZ3dpXlxfAN8MA0GCSqGSIb3DQEBCwUAMIGX\nMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\nLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\nT05BUDERMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBv\nbmFwLm9yZzAeFw0yMDAyMTIwOTM0MjdaFw0yMTAyMTEwOTM0MjdaMIGXMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5j\naXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwET05BUDER\nMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBvbmFwLm9y\nZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCFrnO7/eT6V+7XkPPd\neiL/6xXreuegvit/1/jTVjG+3AOVcmTn2WXwXXRcQLvkWQfJVPoltsY8E3FqFRti\n797XjY6cdQJFVDyzNU0+Fb4vJL9FK5wSvnS6EFjBEn3JvXRlENorDCs/mfjkjJoa\nDl74gXQEJYcg4nsTeNIj7cm3Q7VK3mZt1t7LSJJ+czxv69UJDuNJpmQ/2WOKyLZA\ngTtBJ+Hyol45/OLsrqwq1dAn9ZRWIFPvRt/XQYH9bI/6MtqSreRVUrdYCiTe/XpP\nB/OM6NEi2+p5QLi3Yi70CEbqP3HqUVbkzF+r7bwIb6M5/HxfqzLmGwLvD+6rYnUn\nBm8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAhXoO65DXth2X/zFRNsCNpLwmDy7r\nPxT9ZAIZAzSxx3/aCYiuTrKP1JnqjkO+F2IbikrI4n6sKO49SKnRf9SWTFhd+5dX\nvxq5y7MaqxHAY9J7+Qzq33+COVFQnaF7ddel2NbyUVb2b9ZINNsaZkkPXui6DtQ7\n/Fb/1tmAGWd3hMp75G2thBSzs816JMKKa9WD+4VGATEs6OSll4sv2fOZEn+0mAD3\n9q9c+WtLGIudOwcHwzPb2njtNntQSCK/tVOqbY+vzhMY3JW+p9oSrLDSdGC+pAKK\nm/wB+2VPIYcsPMtIhHC4tgoSaiCqjXYptaOh4b8ye8CPBUCpX/AYYkN0Ow==\n-----END CERTIFICATE-----",
+ "-----BEGIN CERTIFICATE-----\nMIIDvzCCAqcCFF5DejiyfoNfPiiMmBXulniBewBGMA0GCSqGSIb3DQEBCwUAMIGb\nMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\nLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\nT05BUDEVMBMGA1UEAwwMbmV3Lm9uYXAub3JnMR4wHAYJKoZIhvcNAQkBFg90ZXN0\nZXJAb25hcC5vcmcwHhcNMjAwMjEyMDk1OTM3WhcNMjEwMjExMDk1OTM3WjCBmzEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbi1G\ncmFuY2lzY28xGTAXBgNVBAoMEExpbnV4LUZvdW5kYXRpb24xDTALBgNVBAsMBE9O\nQVAxFTATBgNVBAMMDG5ldy5vbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVy\nQG9uYXAub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtF4FXeDV\nng/inC/bTACmZnLC9IiC7PyG/vVbMxxN1bvQLRAwC/Hbl3i9zD68Vs/jPPr/SDr9\n2rgItdDdUY1V30Y3PT06F11XdEaRb+t++1NX0rDf1AqPaBZgnBmB86s1wbqHdJTr\nwEImDZ5xMPfP3fiWy/9Yw/U7iRMIi1/oI0lWuHJV0bn908shuJ6dvInpRCoDnoTX\nYP/FiDSZCFVewQcq4TigB7kRqZrDcPZWbSlqHklDMXRwbCxAiFSziuX6TBwru9Rn\nHhIeXVSgMU1ZSSopVbJGtQ4zSsU1nvTK5Bhc2UHGcAOZy1xTN5D9EEbTqh7l+Wtx\ny8ojkEXvFG8lVwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAE+bUphwHit78LK8sb\nOMjt4DiEu32KeSJOpYgPLeBeAIynaNsa7sQrpuxerGNTmQWIcw6olXI0J+OOwkik\nII7elrYtd5G1uALxXWdamNsaY0Du34moVL1YjexJ7qQ4oBUxg2tuY8NAQGDK+23I\nnCA+ZwzdTJo73TYS6sx64d/YLWkX4nHGUoMlF+xUH34csDyhpuTSzQhC2quB5N8z\ntSFdpe4z2jqx07qo2EBFxi03EQ8Q0ex6l421QM2gbs7cZQ66K0DkpPcF2+iHZnyx\nxq1lnlsWHklElF2bhyXTn3fPp5wtan00P8IolKx7CAWb92QjkW6M0RvTW/xuwIzh\n0rTO\n-----END CERTIFICATE-----"
+ ]
+} \ No newline at end of file
diff --git a/certServiceClient/src/test/resources/expectedFirstElementOfCertificateChain b/certServiceClient/src/test/resources/expectedFirstElementOfCertificateChain
new file mode 100644
index 00000000..1cbbc8d3
--- /dev/null
+++ b/certServiceClient/src/test/resources/expectedFirstElementOfCertificateChain
@@ -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----- \ No newline at end of file
diff --git a/certServiceClient/src/test/resources/expectedFirstElementOfTrustedCertificates b/certServiceClient/src/test/resources/expectedFirstElementOfTrustedCertificates
new file mode 100644
index 00000000..2d36a220
--- /dev/null
+++ b/certServiceClient/src/test/resources/expectedFirstElementOfTrustedCertificates
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp8CFAwqQddh4/iyGfP8UZ3dpXlxfAN8MA0GCSqGSIb3DQEBCwUAMIGX
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu
+LUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE
+T05BUDERMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBv
+bmFwLm9yZzAeFw0yMDAyMTIwOTM0MjdaFw0yMTAyMTEwOTM0MjdaMIGXMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5j
+aXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwET05BUDER
+MA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBvbmFwLm9y
+ZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCFrnO7/eT6V+7XkPPd
+eiL/6xXreuegvit/1/jTVjG+3AOVcmTn2WXwXXRcQLvkWQfJVPoltsY8E3FqFRti
+797XjY6cdQJFVDyzNU0+Fb4vJL9FK5wSvnS6EFjBEn3JvXRlENorDCs/mfjkjJoa
+Dl74gXQEJYcg4nsTeNIj7cm3Q7VK3mZt1t7LSJJ+czxv69UJDuNJpmQ/2WOKyLZA
+gTtBJ+Hyol45/OLsrqwq1dAn9ZRWIFPvRt/XQYH9bI/6MtqSreRVUrdYCiTe/XpP
+B/OM6NEi2+p5QLi3Yi70CEbqP3HqUVbkzF+r7bwIb6M5/HxfqzLmGwLvD+6rYnUn
+Bm8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAhXoO65DXth2X/zFRNsCNpLwmDy7r
+PxT9ZAIZAzSxx3/aCYiuTrKP1JnqjkO+F2IbikrI4n6sKO49SKnRf9SWTFhd+5dX
+vxq5y7MaqxHAY9J7+Qzq33+COVFQnaF7ddel2NbyUVb2b9ZINNsaZkkPXui6DtQ7
+/Fb/1tmAGWd3hMp75G2thBSzs816JMKKa9WD+4VGATEs6OSll4sv2fOZEn+0mAD3
+9q9c+WtLGIudOwcHwzPb2njtNntQSCK/tVOqbY+vzhMY3JW+p9oSrLDSdGC+pAKK
+m/wB+2VPIYcsPMtIhHC4tgoSaiCqjXYptaOh4b8ye8CPBUCpX/AYYkN0Ow==
+-----END CERTIFICATE----- \ No newline at end of file
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/missingPkResponse b/certServiceClient/src/test/resources/missingPkResponse
new file mode 100644
index 00000000..c53358e0
--- /dev/null
+++ b/certServiceClient/src/test/resources/missingPkResponse
@@ -0,0 +1,7 @@
+{
+ "timestamp": "2020-02-25T06:36:23.651+0000",
+ "status": 400,
+ "error": "Bad Request",
+ "message": "Missing request header 'PK' for method parameter of type String",
+ "path": "//v1/certificate/TestCA"
+} \ No newline at end of file
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/certServiceClient/src/test/resources/testCsr b/certServiceClient/src/test/resources/testCsr
new file mode 100644
index 00000000..aa9387bf
--- /dev/null
+++ b/certServiceClient/src/test/resources/testCsr
@@ -0,0 +1 @@
+LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJRExEQ0NBaFFDQVFBd2daQXhDekFKQmdOVkJBWVRBbEJNTVJZd0ZBWURWUVFJREExTWIzZGxjaTFUYVd4bGMybGhNUkF3RGdZRFZRUUhEQWRYY205amJHRjNNUTR3REFZRFZRUUtEQVZPYjJ0cFlURU5NQXNHQTFVRUN3d0VUMDVCVURFWE1CVUdBMVVFQXd3T2RHVnpkQzV1YjJ0cFlTNWpiMjB4SHpBZEJna3Foa2lHOXcwQkNRRVdFSFJsYzNSbGNrQnViMnRwWVM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFERzMwWUZKMDk3bS83dDJQV1pFbExBNmJ5bFc5Z1k0cDNod3NidC9paENqKzFqRG9YRFdpQk0wMXVGd1BqWmNiaXhwR3BQdXdVU3ZWREUzOUtwUDFHS3NCYVcrMHdLZG02Sit4YmN6ZTBEc0N6QUhCTnNYVXJEK3VzZC9jVUxOVm5UeXRZYzZubkF1VSswQzg0U1l6OGVkVHJ4UWVkSmF4MDBaS3YrdHluVnZvWUtyVVFsMlFrTDI4bFhhaWsxdWIzd1FGeFNQdndEM2xuMU81N2k0Wk9hOHlNcWx2NlpsTkxZYng2UFhsc1RqanBWTldPUllPKzdzeWdieEZ0bHYvbEgyN1BISHZJT3BUUmtGd0lVLzRHWXU2blQ0bDBqYkl0VEE0b2dhUFR6b3hodG5jaStLT1VVeVZ4OWk4eWd3cVBUb3d5UFkyNGpSb2xTd3RBQWpDYkJBZ01CQUFHZ1ZqQlVCZ2txaGtpRzl3MEJDUTR4UnpCRk1FTUdBMVVkRVFROE1EcUNEM1JsYzNReUxtNXZhMmxoTG1OdmJZSVBkR1Z6ZEM1dWIyc3VhWFF1WTI5dGdoWjBaWE4wTG1sdWRDNXVaWFF1Ym05cmFXRXVZMjl0TUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBUmRlNnpiT2R2TXdKSkFETGV0TmlXT0p3TU9Ec0RJeFduUDBjbXkwTVovb21KK21JZFJSb1NZV0t2VDl5OXd3a3A1Sllzb2htMUN4c0RvS1pBZHFWWTloeENMSUJWRktEL2FveUlRUzRhM3prZFBVa0lnWW00UzJxMkI3bTFjT2YxTHpYNzVSQ3BKN3N2SDZ3RFlqV2dEOTBsVW5uamphNUF2VnJTWnRCVUhEQWZsUG5DTmhXU3hMREhTSkZhWHhERkpGbjhpT1FhdDkvUmNERHc2M0lrbWVaLzBWWDhVRjRsaWp2VWcxSGc4WUFrdXVOQnNwTmRDY2FFVFZFUHJwS3BjaFQxdDg1YnA2RnppSHczc3ZCVTM2cmhzUGNQVU5IM1NYT2tVcmZlOXp0RmJzUFB4dmJtZWx1MWEwS2FudmhDbEU0Z1dMT2tWb1k2Q0hlUktYeU0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0t \ No newline at end of file
diff --git a/certServiceClient/src/test/resources/testPk b/certServiceClient/src/test/resources/testPk
new file mode 100644
index 00000000..36bc9834
--- /dev/null
+++ b/certServiceClient/src/test/resources/testPk
@@ -0,0 +1 @@
+LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRREczMFlGSjA5N20vN3QyUFdaRWxMQTZieWxXOWdZNHAzaHdzYnQvaWhDaisxakRvWERXaUJNMDF1RndQalpjYml4cEdwUHV3VVN2VkRFMzlLcFAxR0tzQmFXKzB3S2RtNkoreGJjemUwRHNDekFIQk5zWFVyRCt1c2QvY1VMTlZuVHl0WWM2bm5BdVUrMEM4NFNZejhlZFRyeFFlZEpheDAwWkt2K3R5blZ2b1lLclVRbDJRa0wyOGxYYWlrMXViM3dRRnhTUHZ3RDNsbjFPNTdpNFpPYTh5TXFsdjZabE5MWWJ4NlBYbHNUampwVk5XT1JZTys3c3lnYnhGdGx2L2xIMjdQSEh2SU9wVFJrRndJVS80R1l1Nm5UNGwwamJJdFRBNG9nYVBUem94aHRuY2krS09VVXlWeDlpOHlnd3FQVG93eVBZMjRqUm9sU3d0QUFqQ2JCQWdNQkFBRUNnZ0VBTHdIcHFDQXhubk15SUFCdmxSNEtwNFRZVFhIWE01S2xaUTdJUE1zZHN4WVlNNWprTDFmbldLR0ErYTJ5Wkp1SDM1MlFiNFl5WGNxWUErRXdCMGRyTzlBQmx2Q1JlY3VpdDBTOWs3V3ROM2oyS3ZhMzlKNWNwTlJ6ck9RbUprOFhDNFBmZG5oS0RTOEFVdnVUV3k5UVpSK3FyZ280NUZiSVVYRVdZcC9pNkoyMGR3WW44Sm9HamV5WkFBdVhKQktOYzRJNDRndmNQUHJ4ZHBzMUh6dG5WU2RXbE1wL2lDZnc2YnNlRG94aCtkcXYrTXBrbUhROEV6WVZyVUNmbnhsTWNoMmtwenJpOXdTS3ZrZmMzckFieUpTWnhPQ3hYd2ZvTit3M05JQlpOQzh3WStIZC9nVzJPdFNkY2JOaHJ5UWdjMUVWVGtBdVdzTG1jNXZiTjRZQUVRS0JnUUR1WUdCUmVGZ3FUT1BhNHJJVEZhY1BSZm1qdGNmRnpqSEJLNDA5emhSL0VEWERDNGdxVmpxYWZGSkNIWFp4USt2Q1N3UXBvYVpQcTgraWFmc0pVTUdlcjhLNGdQR0xJTmVueFF2ZEF2c2M4NnA2MzZlakYxbFVLdzA4Rmhzam5zL3pyeGxhZnB3eWpGb0RIcFBoWGg2R25sNGx1NmEycGF2bm8wK3dzWGNRZFFLQmdRRFZremhzY1h1SG0wMnZTTE9KN1RZOHEzQSthbUZrb2hBOVY0YmpJYVpBZ2ZoVHZjMS9aSWM4THNRQmZBL2RKZ0R1eldOYjVqckJ5S0NQMWZDU1FZZ2VybmpSYXFRRlB6ZC82bmswSWZzNjUreUJ6bHlBVDVQNjB0Qjk2NEhsSjBYODRnc1owZlMweFlBRTNxWW83UG1QRUNDRXJPQ05FZTlLRXZabjBVanpuUUtCZ1FEYVAyMFFTbkhXVU0yeFl5c05KQjd2Y2U3TlA2cW5aVkRTZnJCemJOSUJQL01wSDg3TWpHUmRld1BKT3JadG4zVWtUNUNCR1ZwdXlXeHlWRHdlWEV6Wm9DeFV4dUhmc3ZNZnpONCt2UEx5bi9sdlJJUjBZdlZMaFpzNWJ6ZnIxZ1NwSktDKzVQclhvUDdzcWp0VTlOcFlBSGxNYk5HSG1vbVlyRUpURVRoazNRS0JnR1FCRm5kNHY4M2tnNENpK3lhSFExRXZPVlNRZldBZ25wZ0todWVObHdvM2tXNnN2aTk3Zy9ORE5wWTNZRG8rRkV1OU1sd1N0c3FNUmRwejQ3eW9JTE8xSUc5MmpxekNTQnVHVUJDQUpPSVZQT0lmSGFNYklBQmZmQzZwK3QyeEFRMkRUbzFkaVVhbi8rVEgyR2ZyWm9OOW1xeGxRcFBycE84N1o5Tis1TGpsQW9HQVhFQXI5Vmo5WmF3bE5yV0VZYjgyN1J6NVNFZkFjSmFFeTVhVzFUVWNzZVc0bWgwYmNuTzVCSHQvYTFmN3VoQmJoY2xQVFlPOTBSNGpLcUtGK2lVa2VDRHV0TmcrM09ncTdKaS9PWk5vajRSaUM1WWV4TWs5d1kxc3NVV0pqbDVoUURpd1BRQU5Zc09TSWxOT3Z2SWpydG81RnhNWVN5UndHamYrYnRSTzIyYz0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQ \ No newline at end of file
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>