From c4047c754b96f63e5c7675969937967aa739bd2f Mon Sep 17 00:00:00 2001 From: Michal Banka Date: Mon, 23 Mar 2020 15:03:10 +0100 Subject: Add validation for uniqueness of CA names Signed-off-by: Michal Banka Change-Id: Icfa9ee0f78d360a4f640904bb9077a10f15497ed Issue-ID: AAF-1107 --- .../certification/X509CertificateBuilder.java | 2 +- .../configuration/CmpServersConfigLoader.java | 9 +- .../Cmpv2ServerConfigurationValidator.java | 48 ----- .../Cmpv2ServersConfigurationValidator.java | 68 +++++++ .../configuration/CmpServersConfigLoaderTest.java | 7 +- .../Cmpv2ServerConfigurationValidatorTest.java | 189 ------------------ .../Cmpv2ServersConfigurationValidatorTest.java | 213 +++++++++++++++++++++ 7 files changed, 291 insertions(+), 245 deletions(-) delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidator.java create mode 100644 certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidator.java delete mode 100644 certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java create mode 100644 certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidatorTest.java diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/X509CertificateBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/X509CertificateBuilder.java index 70591759..5b24c653 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/X509CertificateBuilder.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/X509CertificateBuilder.java @@ -38,7 +38,7 @@ public class X509CertificateBuilder { private static final int SECURE_NEXT_BYTES = 16; private static final int VALID_PERIOD_IN_DAYS = 365; - public X509v3CertificateBuilder build(PKCS10CertificationRequest csr) throws IOException { + X509v3CertificateBuilder build(PKCS10CertificationRequest csr) throws IOException { return new X509v3CertificateBuilder(csr.getSubject(), createSerial(), Date.from(LocalDateTime.now().toInstant(ZoneOffset.UTC)), Date.from(LocalDateTime.now().plusDays(VALID_PERIOD_IN_DAYS).toInstant(ZoneOffset.UTC)), 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 696ae564..101712e2 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 @@ -25,9 +25,10 @@ import java.io.File; import java.io.IOException; import java.security.InvalidParameterException; 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.onap.aaf.certservice.certification.configuration.validation.Cmpv2ServersConfigurationValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -37,17 +38,17 @@ class CmpServersConfigLoader { 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; + private final Cmpv2ServersConfigurationValidator validator; @Autowired - CmpServersConfigLoader(Cmpv2ServerConfigurationValidator validator) { + CmpServersConfigLoader(Cmpv2ServersConfigurationValidator validator) { this.validator = validator; } List load(String path) throws CmpServersConfigLoadingException { try { List servers = loadConfigFromFile(path).getCmpv2Servers(); - servers.forEach(validator::validate); + validator.validate(servers); return servers; } catch (IOException e) { throw new CmpServersConfigLoadingException(LOADING_EXCEPTION_MESSAGE, e); diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidator.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidator.java deleted file mode 100644 index 736a65d1..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidator.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ============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.validation; - -import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import javax.validation.ConstraintViolation; -import javax.validation.Validator; -import java.security.InvalidParameterException; -import java.util.Set; - -@Service -public class Cmpv2ServerConfigurationValidator { - - private final Validator validator; - - @Autowired - public Cmpv2ServerConfigurationValidator(Validator validator) { - this.validator = validator; - } - - public void validate(Cmpv2Server serverDetails) { - Set> violations = validator.validate(serverDetails); - if (!violations.isEmpty()) { - throw new InvalidParameterException(violations.toString()); - } - } -} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidator.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidator.java new file mode 100644 index 00000000..3cf7fdf7 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidator.java @@ -0,0 +1,68 @@ +/* + * ============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.validation; + +import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import java.security.InvalidParameterException; +import java.util.List; +import java.util.Set; + +@Service +public class Cmpv2ServersConfigurationValidator { + + private final Validator validator; + + @Autowired + public Cmpv2ServersConfigurationValidator(Validator validator) { + this.validator = validator; + } + + public void validate(List servers) { + servers.forEach(this::validateServer); + validateUniqueCaNames(servers); + } + + private void validateServer(Cmpv2Server serverDetails) { + Set> violations = validator.validate(serverDetails); + if (!violations.isEmpty()) { + throw new InvalidParameterException(violations.toString()); + } + } + + private void validateUniqueCaNames(List servers) { + long distinctCAs = getNumberOfUniqueCaNames(servers); + if (servers.size() != distinctCAs) { + throw new InvalidParameterException("CA names are not unique within given CMPv2 servers"); + } + } + + private long getNumberOfUniqueCaNames(List servers) { + return servers.stream().map(Cmpv2Server::getCaName) + .distinct() + .count(); + } + +} 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 61970050..87964295 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 @@ -39,7 +39,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; class CmpServersConfigLoaderTest { private static final String EXISTING_CONFIG_FILENAME = "cmpServers.json"; private static final String INVALID_CONFIG_FILENAME = "invalidCmpServers.json"; - private static final String NONEXISTENT_CONFIG_FILENAME = "nonExisting_cmpServers.json"; + private static final String NONEXISTENT_CONFIG_FILENAME = "nonExistingCmpServers.json"; private static final Map EXPECTED_FIRST_CMP_SERVER = Map.of( "CA_NAME", "TEST", @@ -99,10 +99,11 @@ class CmpServersConfigLoaderTest { // Then assertThat(exception.getMessage()).contains("Validation of CMPv2 servers configuration failed"); + assertThat(exception.getCause().getMessage()).contains("authentication"); } - private String getResourcePath(String invalidConfigFilename) { - return getClass().getClassLoader().getResource(invalidConfigFilename).getFile(); + private String getResourcePath(String configFilename) { + return getClass().getClassLoader().getResource(configFilename).getFile(); } private void verifyThatCmpServerEquals(Cmpv2Server cmpv2Server, Map expected) { 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 deleted file mode 100644 index 1c021b43..00000000 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServerConfigurationValidatorTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * ============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.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; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.aaf.certservice.CertServiceApplication; -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.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = CertServiceApplication.class) -class Cmpv2ServerConfigurationValidatorTest { - - private static final String EMPTY_STRING = ""; - - @Autowired - private Cmpv2ServerConfigurationValidator validator; - - private Authentication authentication; - private Cmpv2Server server; - - @BeforeEach - private void init() { - setAuthentication(); - setServerConfiguration(); - } - - @Test - void shouldNotThrowExceptionWhenServerConfigurationIsValid() { - // Then - assertDoesNotThrow(() -> validator.validate(server)); - } - - @Test - void shouldThrowExceptionWhenWrongProtocolInUrl() { - // Given - server.setUrl("https://test.test.test:60000/"); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenWrongPortInUrl() { - // Given - server.setUrl("http://test.test.test:70000/"); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenWrongCaNameLength() { - // Given - server.setCaName(EMPTY_STRING); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenWrongRvLength() { - // Given - authentication.setRv(EMPTY_STRING); - - // Then - assertExceptionIsThrown(); - } - - - @Test - void shouldThrowExceptionWhenWrongIakLength() { - // Given - authentication.setIak(EMPTY_STRING); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenCaNameIsNull() { - // Given - server.setCaName(null); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenIssuerDnIsNull() { - // Given - server.setIssuerDN(null); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenCaModeIsNull() { - // Given - server.setCaMode(null); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenUrlIsNull() { - // Given - server.setUrl(null); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenAuthenticationIsNull() { - // Given - server.setAuthentication(null); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenIakIsNull() { - // Given - authentication.setIak(null); - - // Then - assertExceptionIsThrown(); - } - - @Test - void shouldThrowExceptionWhenRvIsNull() { - // Given - authentication.setRv(null); - - // Then - assertExceptionIsThrown(); - } - - private void assertExceptionIsThrown() { - assertThrows(IllegalArgumentException.class, () -> validator.validate(server)); - } - - private void setServerConfiguration() { - server = new Cmpv2Server(); - server.setCaMode(CaMode.CLIENT); - server.setCaName("TEST"); - server.setIssuerDN(new X500Name("CN=ManagementCA")); - server.setUrl("http://127.0.0.1/ejbca/publicweb/cmp/cmp"); - server.setAuthentication(authentication); - } - - private void setAuthentication() { - authentication = new Authentication(); - authentication.setRv("testRV"); - authentication.setIak("testIAK"); - } -} diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidatorTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidatorTest.java new file mode 100644 index 00000000..6db77753 --- /dev/null +++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/validation/Cmpv2ServersConfigurationValidatorTest.java @@ -0,0 +1,213 @@ +/* + * ============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.validation; + + +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.onap.aaf.certservice.CertServiceApplication; +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.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = CertServiceApplication.class) +class Cmpv2ServersConfigurationValidatorTest { + + private static final String EMPTY_STRING = ""; + + @Autowired + private Cmpv2ServersConfigurationValidator validator; + + private Authentication authentication; + private Cmpv2Server server; + private List servers; + + @BeforeEach + private void init() { + setAuthentication(); + setServerConfiguration(); + servers = new ArrayList<>(); + servers.add(server); + } + + @Test + void shouldThrowExceptionWhenCaNamesAreNotUnique() { + // Given + servers.add(server); + + // When + Exception exception = assertThrows( + InvalidParameterException.class, + () -> validator.validate(servers)); + + // Then + assertThat(exception.getMessage()).contains("CA names are not unique within given CMPv2 servers"); + } + + @Test + void shouldThrowExceptionWhenWrongProtocolInUrl() { + // Given + server.setUrl("https://test.test.test:60000/"); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenWrongPortInUrl() { + // Given + server.setUrl("http://test.test.test:70000/"); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenWrongCaNameLength() { + // Given + server.setCaName(EMPTY_STRING); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenWrongRvLength() { + // Given + authentication.setRv(EMPTY_STRING); + + // Then + assertExceptionIsThrown(); + } + + + @Test + void shouldThrowExceptionWhenWrongIakLength() { + // Given + authentication.setIak(EMPTY_STRING); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenCaNameIsNull() { + // Given + server.setCaName(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenIssuerDnIsNull() { + // Given + server.setIssuerDN(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenCaModeIsNull() { + // Given + server.setCaMode(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenUrlIsNull() { + // Given + server.setUrl(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenAuthenticationIsNull() { + // Given + server.setAuthentication(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenIakIsNull() { + // Given + authentication.setIak(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldThrowExceptionWhenRvIsNull() { + // Given + authentication.setRv(null); + + // Then + assertExceptionIsThrown(); + } + + @Test + void shouldNotThrowExceptionWhenServerConfigurationIsValid() { + // Then + assertDoesNotThrow(() -> validator.validate(servers)); + } + + private void assertExceptionIsThrown() { + assertThrows(IllegalArgumentException.class, () -> validator.validate(servers)); + } + + private void setServerConfiguration() { + server = new Cmpv2Server(); + server.setCaMode(CaMode.CLIENT); + server.setCaName("TEST"); + server.setIssuerDN(new X500Name("CN=ManagementCA")); + server.setUrl("http://127.0.0.1/ejbca/publicweb/cmp/cmp"); + server.setAuthentication(authentication); + } + + private void setAuthentication() { + authentication = new Authentication(); + authentication.setRv("testRV"); + authentication.setIak("testIAK"); + } + +} \ No newline at end of file -- cgit 1.2.3-korg