diff --git a/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/domain/ConfigurationSource.java b/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/domain/ConfigurationSource.java index ae600a1e0f..4881df74f1 100644 --- a/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/domain/ConfigurationSource.java +++ b/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/domain/ConfigurationSource.java @@ -48,4 +48,3 @@ public class ConfigurationSource { private Set configurationSigningKeys = new HashSet<>(0); } - diff --git a/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/facade/GlobalConfFacade.java b/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/facade/GlobalConfFacade.java index 99eb5424da..4d0a47d59d 100644 --- a/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/facade/GlobalConfFacade.java +++ b/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/facade/GlobalConfFacade.java @@ -32,7 +32,7 @@ import ee.ria.xroad.common.conf.globalconf.GlobalConf; import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo; import ee.ria.xroad.common.conf.globalconf.MemberInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -137,9 +137,9 @@ ClientId getSubjectName(SignCertificateProfileInfoParameters signCertificateProf String getSecurityServerAddress(SecurityServerId securityServerId); /** - * {@link GlobalConf#getApprovedTspTypes(String)} + * {@link GlobalConf#getApprovedTsps(String)} */ - List getApprovedTspTypes(String instanceIdentifier); + List getApprovedTsps(String instanceIdentifier); /** * {@link GlobalConf#isSecurityServerClient(ClientId, SecurityServerId)}} diff --git a/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/service/ConfigurationService.java b/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/service/ConfigurationService.java index d36e07c9d7..8720a4b540 100644 --- a/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/service/ConfigurationService.java +++ b/src/central-server/admin-service/core-api/src/main/java/org/niis/xroad/cs/admin/api/service/ConfigurationService.java @@ -26,16 +26,21 @@ */ package org.niis.xroad.cs.admin.api.service; +import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKey; import org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType; import org.niis.xroad.cs.admin.api.domain.DistributedFile; import org.niis.xroad.cs.admin.api.dto.ConfigurationParts; import org.niis.xroad.cs.admin.api.dto.File; import org.niis.xroad.cs.admin.api.dto.GlobalConfDownloadUrl; +import java.util.List; +import java.util.Map; import java.util.Set; public interface ConfigurationService { + Map> getNodeAddressesWithConfigurationSigningKeys(); + boolean hasSigningKeys(ConfigurationSourceType sourceType); Set getConfigurationParts(ConfigurationSourceType sourceType); diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/entity/mapper/TrustedAnchorMapper.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/entity/mapper/TrustedAnchorMapper.java index 4a68fc2d76..37c1cbc396 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/entity/mapper/TrustedAnchorMapper.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/entity/mapper/TrustedAnchorMapper.java @@ -27,7 +27,7 @@ package org.niis.xroad.cs.admin.core.entity.mapper; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import org.mapstruct.Mapper; import org.niis.xroad.cs.admin.api.converter.GenericUniDirectionalMapper; @@ -47,7 +47,7 @@ @Mapper(componentModel = SPRING, unmappedTargetPolicy = ERROR) public interface TrustedAnchorMapper extends GenericUniDirectionalMapper { - default TrustedAnchor map(ConfigurationAnchorV2 anchorV2, byte[] anchorBytes) { + default TrustedAnchor map(ConfigurationAnchor anchorV2, byte[] anchorBytes) { final TrustedAnchor trustedAnchor = new TrustedAnchor(); trustedAnchor.setInstanceIdentifier(anchorV2.getInstanceIdentifier()); trustedAnchor.setGeneratedAt(anchorV2.getGeneratedAt().toInstant()); diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/facade/GlobalConfFacadeImpl.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/facade/GlobalConfFacadeImpl.java index befa180606..c525126770 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/facade/GlobalConfFacadeImpl.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/facade/GlobalConfFacadeImpl.java @@ -32,7 +32,7 @@ import ee.ria.xroad.common.conf.globalconf.GlobalConf; import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo; import ee.ria.xroad.common.conf.globalconf.MemberInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -177,10 +177,10 @@ public String getSecurityServerAddress(SecurityServerId securityServerId) { } /** - * {@link GlobalConf#getApprovedTspTypes(String)} + * {@link GlobalConf#getApprovedTsps(String)} */ - public List getApprovedTspTypes(String instanceIdentifier) { - return GlobalConf.getApprovedTspTypes(instanceIdentifier); + public List getApprovedTsps(String instanceIdentifier) { + return GlobalConf.getApprovedTsps(instanceIdentifier); } /** diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/repository/ConfigurationSigningKeyRepository.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/repository/ConfigurationSigningKeyRepository.java index 2ac8a56c2c..93d0864203 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/repository/ConfigurationSigningKeyRepository.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/repository/ConfigurationSigningKeyRepository.java @@ -38,6 +38,8 @@ public interface ConfigurationSigningKeyRepository extends GenericRepository findByKeyIdentifierIn(Collection keyIds); + List findForSourceIn(List sourceTypes); + void deleteByKeyIdentifier(String identifier); Optional findActiveForSource(String sourceType, String haNodeName); diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImpl.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImpl.java index f31cba4b9f..5550462455 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImpl.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImpl.java @@ -138,7 +138,7 @@ public ConfigurationAnchor recreateAnchor(ConfigurationSourceType configurationT final var sources = configurationSourceRepository.findAllBySourceType(configurationType.name().toLowerCase()); final var now = TimeUtils.zonedDateTimeNow(ZoneId.of("UTC")); - final var anchorXml = buildAnchorXml(configurationType, instanceIdentifier, now, sources); + final var anchorXml = buildAnchorXml(instanceIdentifier, now, sources); final var anchorXmlBytes = anchorXml.getBytes(StandardCharsets.UTF_8); final var anchorXmlHash = CryptoUtils.calculateAnchorHashDelimited(anchorXmlBytes); if (addAuditLog) { @@ -156,8 +156,7 @@ public ConfigurationAnchor recreateAnchor(ConfigurationSourceType configurationT return new ConfigurationAnchor(anchorXmlHash, now.toInstant()); } - private String buildAnchorXml(final ConfigurationSourceType configurationType, - final String instanceIdentifier, + private String buildAnchorXml(final String instanceIdentifier, final ZonedDateTime now, final List sources) { try { @@ -171,10 +170,10 @@ private String buildAnchorXml(final ConfigurationSourceType configurationType, configurationAnchor.setInstanceIdentifier(instanceIdentifier); sources.stream() - .map(src -> toXmlSource(src, configurationType, factory, false)) + .map(src -> toXmlSource(src, factory, false)) .forEach(configurationAnchor.getSource()::add); sources.stream() - .map(src -> toXmlSource(src, configurationType, factory, true)) + .map(src -> toXmlSource(src, factory, true)) .forEach(configurationAnchor.getSource()::add); JAXBElement root = factory.createConfigurationAnchor(configurationAnchor); @@ -187,9 +186,9 @@ private String buildAnchorXml(final ConfigurationSourceType configurationType, } } - private String buildGlobalDownloadUrl(final ConfigurationSourceType sourceType, final String haNodeName, final boolean isHttps) { + private String buildGlobalDownloadUrl(final String sourceType, final String haNodeName, final boolean isHttps) { final var csAddress = systemParameterService.getCentralServerAddress(haNodeName); - final String sourceDirectory = sourceType.equals(INTERNAL) + final String sourceDirectory = INTERNAL.name().equalsIgnoreCase(sourceType) ? SystemProperties.getCenterInternalDirectory() : SystemProperties.getCenterExternalDirectory(); final String protocol = isHttps ? "https" : "http"; @@ -199,12 +198,11 @@ private String buildGlobalDownloadUrl(final ConfigurationSourceType sourceType, private ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ConfigurationSourceType toXmlSource( final ConfigurationSourceEntity source, - final ConfigurationSourceType configurationType, final ObjectFactory factory, final boolean isHttps) { final var xmlSource = factory.createConfigurationSourceType(); - xmlSource.setDownloadURL(buildGlobalDownloadUrl(configurationType, source.getHaNodeName(), isHttps)); + xmlSource.setDownloadURL(buildGlobalDownloadUrl(source.getSourceType(), source.getHaNodeName(), isHttps)); source.getConfigurationSigningKeys().stream() .map(ConfigurationSigningKeyEntity::getCert) .forEach(xmlSource.getVerificationCert()::add); diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImpl.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImpl.java index 03d00e1c41..7604aee6b4 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImpl.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImpl.java @@ -37,6 +37,7 @@ import lombok.SneakyThrows; import org.niis.xroad.common.exception.NotFoundException; import org.niis.xroad.common.exception.ServiceException; +import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKey; import org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType; import org.niis.xroad.cs.admin.api.domain.DistributedFile; import org.niis.xroad.cs.admin.api.dto.ConfigurationParts; @@ -47,6 +48,7 @@ import org.niis.xroad.cs.admin.api.service.SystemParameterService; import org.niis.xroad.cs.admin.core.entity.ConfigurationSourceEntity; import org.niis.xroad.cs.admin.core.entity.DistributedFileEntity; +import org.niis.xroad.cs.admin.core.entity.mapper.ConfigurationSigningKeyMapper; import org.niis.xroad.cs.admin.core.entity.mapper.DistributedFileMapper; import org.niis.xroad.cs.admin.core.repository.ConfigurationSigningKeyRepository; import org.niis.xroad.cs.admin.core.repository.ConfigurationSourceRepository; @@ -59,6 +61,7 @@ import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -67,6 +70,8 @@ import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS; import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS; import static ee.ria.xroad.common.util.CryptoUtils.DEFAULT_UPLOAD_FILE_HASH_ALGORITHM; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; import static org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType.EXTERNAL; import static org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType.INTERNAL; @@ -96,6 +101,21 @@ public class ConfigurationServiceImpl implements ConfigurationService { private final DistributedFileMapper distributedFileMapper; private final AuditDataHelper auditDataHelper; private final ConfigurationPartValidator configurationPartValidator; + private final ConfigurationSigningKeyMapper configurationSigningKeyMapper; + + @Override + public Map> getNodeAddressesWithConfigurationSigningKeys() { + return configurationSourceRepository.findAll().stream().collect(toMap( + src -> systemParameterService.getCentralServerAddress(src.getHaNodeName()), + src -> src.getConfigurationSigningKeys().stream() + .map(configurationSigningKeyMapper::toTarget) + .collect(toList()), + (signingKeys1, signingKeys2) -> { + signingKeys1.addAll(signingKeys2); + return signingKeys1; + } + )); + } @Override public boolean hasSigningKeys(final ConfigurationSourceType sourceType) { diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationSigningKeysServiceImpl.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationSigningKeysServiceImpl.java index 786fc4e9d1..488c45521c 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationSigningKeysServiceImpl.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/ConfigurationSigningKeysServiceImpl.java @@ -206,6 +206,7 @@ public void activateKey(final String keyIdentifier) { } } + @Override public Optional findActiveForSource(String sourceType) { return configurationSigningKeyRepository.findActiveForSource(sourceType, haConfigStatus.getCurrentHaNodeName()) .map(configurationSigningKeyMapper::toTarget); diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImpl.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImpl.java index 12af1e7474..602857c11e 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImpl.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImpl.java @@ -26,7 +26,7 @@ */ package org.niis.xroad.cs.admin.core.service; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import ee.ria.xroad.common.conf.globalconf.ConfigurationLocation; import lombok.RequiredArgsConstructor; @@ -91,7 +91,7 @@ public List findAll() { @Override public TrustedAnchor preview(byte[] trustedAnchorFile) { try { - final ConfigurationAnchorV2 anchorV2 = new ConfigurationAnchorV2(trustedAnchorFile); + final ConfigurationAnchor anchorV2 = new ConfigurationAnchor(trustedAnchorFile); return trustedAnchorMapper.map(anchorV2, trustedAnchorFile); } catch (Exception e) { throw new ValidationFailureException(MALFORMED_ANCHOR); @@ -102,7 +102,7 @@ public TrustedAnchor preview(byte[] trustedAnchorFile) { public TrustedAnchor upload(byte[] trustedAnchor) { auditDataHelper.calculateAndPutAnchorHash(trustedAnchor); - final ConfigurationAnchorV2 anchorV2 = new ConfigurationAnchorV2(trustedAnchor); + final ConfigurationAnchor anchorV2 = new ConfigurationAnchor(trustedAnchor); auditDataHelper.put(INSTANCE_IDENTIFIER, anchorV2.getInstanceIdentifier()); auditDataHelper.putDate(GENERATED_AT, anchorV2.getGeneratedAt()); @@ -116,7 +116,7 @@ public TrustedAnchor upload(byte[] trustedAnchor) { return trustedAnchorMapper.toTarget(entity); } - private TrustedAnchorEntity saveTrustedAnchor(ConfigurationAnchorV2 anchorV2, byte[] anchorFile) { + private TrustedAnchorEntity saveTrustedAnchor(ConfigurationAnchor anchorV2, byte[] anchorFile) { final TrustedAnchorEntity entity = trustedAnchorRepository.findFirstByInstanceIdentifier(anchorV2.getInstanceIdentifier()) .map(existing -> { anchorUrlRepository.deleteByTrustedAnchorId(existing.getId()); diff --git a/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImplTest.java b/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImplTest.java index d920835475..c9fdf0af06 100644 --- a/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImplTest.java +++ b/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationAnchorServiceImplTest.java @@ -206,9 +206,11 @@ void shouldSuccessfullyRecreateInternal() { when(configurationSource.getConfigurationSigningKeys()) .thenReturn(new LinkedHashSet<>(List.of(signingKeyEntity1, signingKeyEntity2))); when(configurationSource.getConfigurationSigningKey()).thenReturn(signingKeyEntity1); + when(configurationSource.getSourceType()).thenReturn(INTERNAL_CONFIGURATION); when(configurationSource2.getHaNodeName()).thenReturn(HA_NODE_NAME2); when(configurationSource2.getConfigurationSigningKeys()).thenReturn(Set.of(signingKeyEntity3)); when(configurationSource2.getConfigurationSigningKey()).thenReturn(null); + when(configurationSource2.getSourceType()).thenReturn(INTERNAL_CONFIGURATION); when(signingKeyEntity1.getCert()).thenReturn(CERT1.getBytes(UTF_8)); when(signingKeyEntity2.getCert()).thenReturn(CERT2.getBytes(UTF_8)); when(signingKeyEntity3.getCert()).thenReturn(CERT3.getBytes(UTF_8)); diff --git a/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImplTest.java b/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImplTest.java index bf139672e1..60566f0576 100644 --- a/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImplTest.java +++ b/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/ConfigurationServiceImplTest.java @@ -49,8 +49,11 @@ import org.niis.xroad.cs.admin.api.dto.HAConfigStatus; import org.niis.xroad.cs.admin.api.service.ConfigurationService; import org.niis.xroad.cs.admin.api.service.SystemParameterService; +import org.niis.xroad.cs.admin.core.entity.ConfigurationSigningKeyEntity; import org.niis.xroad.cs.admin.core.entity.ConfigurationSourceEntity; import org.niis.xroad.cs.admin.core.entity.DistributedFileEntity; +import org.niis.xroad.cs.admin.core.entity.mapper.ConfigurationSigningKeyMapper; +import org.niis.xroad.cs.admin.core.entity.mapper.ConfigurationSigningKeyMapperImpl; import org.niis.xroad.cs.admin.core.entity.mapper.DistributedFileMapper; import org.niis.xroad.cs.admin.core.entity.mapper.DistributedFileMapperImpl; import org.niis.xroad.cs.admin.core.repository.ConfigurationSigningKeyRepository; @@ -61,6 +64,7 @@ import org.niis.xroad.restapi.config.audit.RestApiAuditProperty; import java.time.Instant; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -116,6 +120,8 @@ class ConfigurationServiceImplTest { private DistributedFileMapper distributedFileMapper = new DistributedFileMapperImpl(); @Mock private ConfigurationSigningKeyRepository configurationSigningKeyRepository; + @Spy + private final ConfigurationSigningKeyMapper configurationSigningKeyMapper = new ConfigurationSigningKeyMapperImpl(); private ConfigurationServiceImpl configurationServiceHa; @BeforeEach @@ -205,6 +211,17 @@ void shouldReturnEmptyListWhenSourceNotFound() { assertThat(configurationService.getConfigurationParts(INTERNAL)).isEmpty(); verifyNoInteractions(distributedFileRepository); } + + @Test + void getNodeAddressesWithConfigurationSigningKeys() { + when(configurationSourceRepository.findAll()).thenReturn(List.of(configurationSource, configurationSource)); + when(configurationSource.getConfigurationSigningKeys()).thenReturn(Set.of(new ConfigurationSigningKeyEntity())); + when(configurationSource.getHaNodeName()).thenReturn(HA_NODE_NAME); + when(systemParameterService.getCentralServerAddress(HA_NODE_NAME)).thenReturn(CENTRAL_SERVICE); + + assertThat(configurationServiceHa.getNodeAddressesWithConfigurationSigningKeys().get(CENTRAL_SERVICE)) + .hasSize(2); + } } @Nested @@ -239,7 +256,8 @@ private ConfigurationServiceImpl createConfigurationService(HAConfigStatus haCon distributedFileRepository, distributedFileMapper, auditDataHelper, - configurationPartValidator); + configurationPartValidator, + configurationSigningKeyMapper); } @Nested diff --git a/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImplTest.java b/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImplTest.java index af4fdce363..1fbfdaac94 100644 --- a/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImplTest.java +++ b/src/central-server/admin-service/core/src/test/java/org/niis/xroad/cs/admin/core/service/TrustedAnchorServiceImplTest.java @@ -137,7 +137,7 @@ void uploadNew() throws Exception { verify(auditDataHelper).calculateAndPutAnchorHash(bytes); verify(auditDataHelper).put(INSTANCE_IDENTIFIER, "CS0"); verify(auditDataHelper).putDate(GENERATED_AT, anchorDate); - verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf?version=2")); + verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf")); verify(configurationVerifier).verifyConfiguration(any(), any()); @@ -164,7 +164,7 @@ void uploadNewVerificationShouldFail() throws Exception { verify(auditDataHelper).calculateAndPutAnchorHash(bytes); verify(auditDataHelper).put(INSTANCE_IDENTIFIER, "CS0"); verify(auditDataHelper).putDate(GENERATED_AT, anchorDate); - verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf?version=2")); + verify(auditDataHelper).put(ANCHOR_URLS, Set.of("http://cs0/internalconf")); verifyNoMoreInteractions(trustedAnchorRepository); } diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationDistributor.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationDistributor.java index ec1f922c65..dd36b6fab8 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationDistributor.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationDistributor.java @@ -103,6 +103,10 @@ private void writeFile(Path fileSubPath, byte @NonNull [] data) { } } + public int getVersion() { + return version; + } + public Path getVersionSubPath() { return Path.of("V" + version); } diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationPartsGenerator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationPartsGenerator.java new file mode 100644 index 0000000000..731a265ebb --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/ConfigurationPartsGenerator.java @@ -0,0 +1,36 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import java.util.List; + +public interface ConfigurationPartsGenerator { + + int getConfigurationVersion(); + + List generateConfigurationParts(); +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilder.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilder.java index faf1087a80..9408099be7 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilder.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilder.java @@ -40,6 +40,7 @@ import java.util.Collection; import java.util.List; +import static java.lang.String.valueOf; import static org.niis.xroad.cs.admin.globalconf.generator.MultipartMessage.header; import static org.niis.xroad.cs.admin.globalconf.generator.MultipartMessage.partBuilder; @@ -51,6 +52,7 @@ public class DirectoryContentBuilder { private final String pathPrefix; private final String instanceIdentifier; private final HashCalculator hashCalculator; + private final int configurationVersion; private final List configurationParts = new ArrayList<>(); @SneakyThrows @@ -58,10 +60,12 @@ public DirectoryContentBuilder( @NonNull String hashAlgorithmId, @NonNull Instant expireDate, @NonNull String pathPrefix, - @NonNull String instanceIdentifier) { + @NonNull String instanceIdentifier, + int configurationVersion) { this.expireDate = expireDate; this.pathPrefix = pathPrefix; this.instanceIdentifier = instanceIdentifier; + this.configurationVersion = configurationVersion; hashCalculator = new HashCalculator(CryptoUtils.getDigestAlgorithmURI(hashAlgorithmId)); } @@ -81,7 +85,7 @@ DirectoryContentHolder build() { var builder = MultipartMessage.builder(); builder.part(partBuilder() .header(header("Expire-date", EXPIRE_DATE_FORMATTER.format(expireDate))) - .header(header("Version", "2")) + .header(header("Version", valueOf(configurationVersion))) .build()); configurationParts.forEach(confPart -> builder.part(buildPart(confPart))); var multipartMessage = builder.build(); diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/GlobalConfGenerationServiceImpl.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/GlobalConfGenerationServiceImpl.java index d26d5cc43a..abd10610b7 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/GlobalConfGenerationServiceImpl.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/GlobalConfGenerationServiceImpl.java @@ -27,7 +27,6 @@ package org.niis.xroad.cs.admin.globalconf.generator; import ee.ria.xroad.common.SystemProperties; -import ee.ria.xroad.common.conf.globalconf.ConfigurationConstants; import ee.ria.xroad.common.util.CryptoUtils; import ee.ria.xroad.common.util.TimeUtils; import ee.ria.xroad.commonui.OptionalConfPart; @@ -71,7 +70,6 @@ @Slf4j @RequiredArgsConstructor public class GlobalConfGenerationServiceImpl implements GlobalConfGenerationService { - private static final int CONFIGURATION_VERSION = 2; private static final int OLD_CONF_PRESERVING_SECONDS = 600; private static final Set EXTERNAL_SOURCE_CONTENT_IDENTIFIERS = Set.of( @@ -84,49 +82,58 @@ public class GlobalConfGenerationServiceImpl implements GlobalConfGenerationServ private final SystemParameterService systemParameterService; private final ConfigurationService configurationService; private final ConfigurationSigningKeysService configurationSigningKeysService; - private final PrivateParametersGenerator privateParametersGenerator; - private final SharedParametersGenerator sharedParametersGenerator; private final ApplicationEventPublisher eventPublisher; + private final List configurationPartsGenerators; + @SneakyThrows @Override @Transactional @Scheduled(fixedRateString = "${xroad.admin-service.global-configuration-generation-rate-in-seconds}", timeUnit = SECONDS) public void generate() { - var success = false; - try { - log.debug("Starting global conf generation"); + configurationPartsGenerators.forEach(configurationPartsGenerator -> { + int confVersion = configurationPartsGenerator.getConfigurationVersion(); + if (confVersion < SystemProperties.getMinimumCentralServerGlobalConfigurationVersion()) { + return; + } - generateAndSaveConfiguration(); - var configGenerationTime = TimeUtils.now(); + var success = false; + try { + log.debug("Starting global conf V{} generation", confVersion); - var allConfigurationParts = toConfigurationParts(configurationService.getAllConfigurationFiles(CONFIGURATION_VERSION)); - var internalConfigurationParts = internalConfigurationParts(allConfigurationParts); - var externalConfigurationParts = externalConfigurationParts(allConfigurationParts); + var configurationParts = configurationPartsGenerator.generateConfigurationParts(); + configurationParts.forEach(gp -> configurationService + .saveConfigurationPart(gp.getContentIdentifier(), gp.getFilename(), gp.getData(), confVersion)); + var configGenerationTime = TimeUtils.now(); - var generatedConfDir = Path.of(SystemProperties.getCenterGeneratedConfDir()); - var configDistributor = new ConfigurationDistributor(generatedConfDir, CONFIGURATION_VERSION, configGenerationTime); - configDistributor.initConfLocation(); - configDistributor.writeConfigurationFiles(allConfigurationParts); + var allConfigurationParts = toConfigurationParts(configurationService.getAllConfigurationFiles(confVersion)); + var internalConfigurationParts = internalConfigurationParts(allConfigurationParts); + var externalConfigurationParts = externalConfigurationParts(allConfigurationParts); - var internalSigningKey = configurationSigningKeysService.findActiveForSource(SOURCE_TYPE_INTERNAL).orElseThrow(); - var externalSigningKey = configurationSigningKeysService.findActiveForSource(SOURCE_TYPE_EXTERNAL).orElseThrow(); + var generatedConfDir = Path.of(SystemProperties.getCenterGeneratedConfDir()); + var configDistributor = new ConfigurationDistributor(generatedConfDir, confVersion, configGenerationTime); + configDistributor.initConfLocation(); + configDistributor.writeConfigurationFiles(allConfigurationParts); - writeDirectoryContentFile(configDistributor, internalConfigurationParts, internalSigningKey, getTmpInternalDirectory()); - writeDirectoryContentFile(configDistributor, externalConfigurationParts, externalSigningKey, getTmpExternalDirectory()); + var internalSigningKey = configurationSigningKeysService.findActiveForSource(SOURCE_TYPE_INTERNAL).orElseThrow(); + var externalSigningKey = configurationSigningKeysService.findActiveForSource(SOURCE_TYPE_EXTERNAL).orElseThrow(); - configDistributor.moveDirectoryContentFile(getTmpInternalDirectory(), getCenterInternalDirectory()); - configDistributor.moveDirectoryContentFile(getTmpExternalDirectory(), getCenterExternalDirectory()); + writeDirectoryContentFile(configDistributor, internalConfigurationParts, internalSigningKey, getTmpInternalDirectory()); + writeDirectoryContentFile(configDistributor, externalConfigurationParts, externalSigningKey, getTmpExternalDirectory()); - cleanUpOldConfigurations(generatedConfDir.resolve(configDistributor.getVersionSubPath())); + configDistributor.moveDirectoryContentFile(getTmpInternalDirectory(), getCenterInternalDirectory()); + configDistributor.moveDirectoryContentFile(getTmpExternalDirectory(), getCenterExternalDirectory()); - writeLocalCopy(allConfigurationParts); + cleanUpOldConfigurations(generatedConfDir.resolve(configDistributor.getVersionSubPath())); - log.debug("Global conf generated"); - success = true; - } finally { - eventPublisher.publishEvent(success ? SUCCESS : FAILURE); - } + writeLocalCopy(allConfigurationParts); + + log.debug("Global conf generated"); + success = true; + } finally { + eventPublisher.publishEvent(success ? SUCCESS : FAILURE); + } + }); } @SneakyThrows @@ -177,18 +184,18 @@ private void writeDirectoryContentFile(ConfigurationDistributor configDistributo Set configurationParts, ConfigurationSigningKey signingKey, String fileName) { - String signedDirectory = createSignedDirectory(configurationParts, - "/" + configDistributor.getSubPath().toString(), - signingKey); + String signedDirectory = createSignedDirectory(configDistributor, configurationParts, signingKey); configDistributor.writeDirectoryContentFile(fileName, signedDirectory.getBytes(UTF_8)); } - private String createSignedDirectory(Set configurationParts, String pathPrefix, ConfigurationSigningKey signingKey) { + private String createSignedDirectory(ConfigurationDistributor configDistributor, Set configurationParts, + ConfigurationSigningKey signingKey) { var directoryContentBuilder = new DirectoryContentBuilder( getConfHashAlgoId(), TimeUtils.now().plusSeconds(systemParameterService.getConfExpireIntervalSeconds()), - pathPrefix, - systemParameterService.getInstanceIdentifier()) + "/" + configDistributor.getSubPath().toString(), + systemParameterService.getInstanceIdentifier(), + configDistributor.getVersion()) .contentParts(configurationParts); var directoryContent = directoryContentBuilder.build(); @@ -201,12 +208,6 @@ private String createSignedDirectory(Set configurationParts, return directoryContentSigner.createSignedDirectory(directoryContent, signingKey.getKeyIdentifier(), signingKey.getCert()); } - private void generateAndSaveConfiguration() { - var configurationParts = generateConfiguration(); - configurationParts.forEach(gp -> configurationService - .saveConfigurationPart(gp.getContentIdentifier(), gp.getFilename(), gp.getData(), CONFIGURATION_VERSION)); - } - private Set toConfigurationParts(Set configurationFiles) { return configurationFiles .stream().map(this::toConfigurationPart) @@ -237,20 +238,6 @@ private void writeLocalCopy(Set allConfigurationParts) { .write(allConfigurationParts); } - private List generateConfiguration() { - return List.of( - ConfigurationPart.builder() - .contentIdentifier(ConfigurationConstants.CONTENT_ID_PRIVATE_PARAMETERS) - .filename(ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS) - .data(privateParametersGenerator.generate().getBytes(UTF_8)) - .build(), - ConfigurationPart.builder() - .contentIdentifier(CONTENT_ID_SHARED_PARAMETERS) - .filename(ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS) - .data(sharedParametersGenerator.generate().getBytes(UTF_8)) - .build()); - } - private static Set getInternalSourceContentIdentifiers() { return concat(INTERNAL_SOURCE_REQUIRED_CONTENT_IDENTIFIERS.stream(), getOptionalPartsConf().getAllParts().stream() diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersConverter.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Converter.java similarity index 94% rename from src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersConverter.java rename to src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Converter.java index cfdbffe87f..76dec0e242 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersConverter.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Converter.java @@ -39,8 +39,8 @@ @Mapper(uses = {ObjectFactory.class, MappingUtils.class}, unmappedTargetPolicy = ReportingPolicy.ERROR) -interface PrivateParametersConverter { - PrivateParametersConverter INSTANCE = Mappers.getMapper(PrivateParametersConverter.class); +interface PrivateParametersV2Converter { + PrivateParametersV2Converter INSTANCE = Mappers.getMapper(PrivateParametersV2Converter.class); @Mapping(source = "configurationAnchors", target = "configurationAnchor") PrivateParametersType convert(PrivateParameters parameters); diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersGenerator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Generator.java similarity index 94% rename from src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersGenerator.java rename to src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Generator.java index d549514017..0d8eac5024 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersGenerator.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Generator.java @@ -33,8 +33,8 @@ @Component @RequiredArgsConstructor @Slf4j -public class PrivateParametersGenerator { - private final PrivateParametersMarshaller marshaller; +public class PrivateParametersV2Generator { + private final PrivateParametersV2Marshaller marshaller; private final PrivateParametersLoader loader; String generate() { diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersMarshaller.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Marshaller.java similarity index 96% rename from src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersMarshaller.java rename to src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Marshaller.java index 3dff7acea2..b16b688422 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersMarshaller.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2Marshaller.java @@ -39,7 +39,7 @@ import java.io.StringWriter; @Component -class PrivateParametersMarshaller { +class PrivateParametersV2Marshaller { private final JAXBContext jaxbContext = createJaxbContext(); @SneakyThrows @@ -48,7 +48,7 @@ String marshall(PrivateParameters parameters) { var marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setSchema(PrivateParametersSchemaValidatorV2.getSchema()); - marshaller.marshal(new ObjectFactory().createConf(PrivateParametersConverter.INSTANCE.convert(parameters)), writer); + marshaller.marshal(new ObjectFactory().createConf(PrivateParametersV2Converter.INSTANCE.convert(parameters)), writer); return writer.toString(); } diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Converter.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Converter.java new file mode 100644 index 0000000000..bc7a2374ed --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Converter.java @@ -0,0 +1,53 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ConfigurationAnchorType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ConfigurationSourceType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ObjectFactory; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.PrivateParametersType; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(uses = {ObjectFactory.class, MappingUtils.class}, + unmappedTargetPolicy = ReportingPolicy.ERROR) +interface PrivateParametersV3Converter { + + PrivateParametersV3Converter INSTANCE = Mappers.getMapper(PrivateParametersV3Converter.class); + + @Mapping(source = "configurationAnchors", target = "configurationAnchor") + PrivateParametersType convert(PrivateParameters parameters); + + @Mapping(source = "sources", target = "source") + ConfigurationAnchorType convertAnchor(PrivateParameters.ConfigurationAnchor configurationAnchor); + + @Mapping(source = "verificationCerts", target = "verificationCert") + ConfigurationSourceType convertSource(PrivateParameters.ConfigurationSource configurationSource); +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Generator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Generator.java new file mode 100644 index 0000000000..8b2e6072e7 --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Generator.java @@ -0,0 +1,45 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class PrivateParametersV3Generator { + private final PrivateParametersV3Marshaller marshaller; + private final PrivateParametersLoader loader; + + String generate() { + log.debug("Generating private parameters"); + var parameters = loader.load(); + return marshaller.marshall(parameters); + } +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Marshaller.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Marshaller.java new file mode 100644 index 0000000000..41cd33d06d --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3Marshaller.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.PrivateParametersSchemaValidatorV3; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ObjectFactory; + +import lombok.SneakyThrows; +import org.springframework.stereotype.Component; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + +import java.io.StringWriter; + +@Component +public class PrivateParametersV3Marshaller { + + private final JAXBContext jaxbContext = createJaxbContext(); + + @SneakyThrows + String marshall(PrivateParameters parameters) { + var writer = new StringWriter(); + var marshaller = jaxbContext.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + marshaller.setSchema(PrivateParametersSchemaValidatorV3.getSchema()); + marshaller.marshal(new ObjectFactory().createConf(PrivateParametersV3Converter.INSTANCE.convert(parameters)), + writer); + return writer.toString(); + } + + @SneakyThrows + private JAXBContext createJaxbContext() { + return JAXBContext.newInstance(ObjectFactory.class); + } + +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParameters.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParameters.java index 4913c18c95..2290ca7d2f 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParameters.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParameters.java @@ -36,6 +36,7 @@ @Data class SharedParameters { private String instanceIdentifier; + private List sources; private List approvedCAs; private List approvedTSAs; private List members; @@ -43,6 +44,12 @@ class SharedParameters { private List globalGroups; private GlobalSettings globalSettings; + @Data + public static class ConfigurationSource { + private String address; + private List verificationCerts; + } + @Data public static class ApprovedCA { private String name; diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoader.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoader.java index 4f90a65104..e0cb6157de 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoader.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoader.java @@ -33,6 +33,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.niis.xroad.cs.admin.api.domain.AuthCert; +import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKey; import org.niis.xroad.cs.admin.api.domain.FlattenedSecurityServerClientView; import org.niis.xroad.cs.admin.api.domain.GlobalGroup; import org.niis.xroad.cs.admin.api.domain.GlobalGroupMember; @@ -42,6 +43,7 @@ import org.niis.xroad.cs.admin.api.dto.OcspResponder; import org.niis.xroad.cs.admin.api.service.CertificationServicesService; import org.niis.xroad.cs.admin.api.service.ClientService; +import org.niis.xroad.cs.admin.api.service.ConfigurationService; import org.niis.xroad.cs.admin.api.service.GlobalGroupMemberService; import org.niis.xroad.cs.admin.api.service.GlobalGroupService; import org.niis.xroad.cs.admin.api.service.MemberClassService; @@ -69,10 +71,12 @@ class SharedParametersLoader { private final GlobalGroupService globalGroupService; private final GlobalGroupMemberService globalGroupMemberService; private final MemberClassService memberClassService; + private final ConfigurationService configurationService; SharedParameters load() { var parameters = new SharedParameters(); + parameters.setSources(getSources()); parameters.setInstanceIdentifier(systemParameterService.getInstanceIdentifier()); parameters.setApprovedCAs(getApprovedCAs()); parameters.setApprovedTSAs(getApprovedTSAs()); @@ -83,6 +87,25 @@ SharedParameters load() { return parameters; } + private List getSources() { + return configurationService.getNodeAddressesWithConfigurationSigningKeys().entrySet().stream() + .map(this::toSource) + .collect(toList()); + } + + private SharedParameters.ConfigurationSource toSource( + Map.Entry> addressWithConfigurationSigningKeys + ) { + var source = new SharedParameters.ConfigurationSource(); + source.setAddress(addressWithConfigurationSigningKeys.getKey()); + source.setVerificationCerts( + addressWithConfigurationSigningKeys.getValue().stream() + .map(ConfigurationSigningKey::getCert) + .collect(toList()) + ); + return source; + } + private List getApprovedCAs() { var approvedCas = certificationServicesService.findAll(); return approvedCas.stream() diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersConverter.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Converter.java similarity index 93% rename from src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersConverter.java rename to src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Converter.java index b7c8682998..3cda227e9e 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersConverter.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Converter.java @@ -52,15 +52,12 @@ import static java.util.stream.Collectors.toList; @Mapper(uses = {ObjectFactory.class, MappingUtils.class}, unmappedTargetPolicy = ReportingPolicy.ERROR) -abstract class SharedParametersConverter { - public static final SharedParametersConverter INSTANCE = Mappers.getMapper(SharedParametersConverter.class); - private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory(); +abstract class SharedParametersV2Converter { + public static final SharedParametersV2Converter INSTANCE = Mappers.getMapper(SharedParametersV2Converter.class); + protected static final ObjectFactory OBJECT_FACTORY = new ObjectFactory(); SharedParametersTypeV2 convert(SharedParameters sharedParameters) { - if (sharedParameters == null) { - return null; - } - return convert(sharedParameters, createClientIdMap(sharedParameters)); + return sharedParameters != null ? convert(sharedParameters, createClientIdMap(sharedParameters)) : null; } @Mapping(source = "approvedCAs", target = "approvedCA") diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersGenerator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Generator.java similarity index 95% rename from src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersGenerator.java rename to src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Generator.java index c595092ec0..48d8d4a2dc 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersGenerator.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Generator.java @@ -33,11 +33,10 @@ @Component @RequiredArgsConstructor @Slf4j -public class SharedParametersGenerator { - private final SharedParametersMarshaller marshaller; +public class SharedParametersV2Generator { + private final SharedParametersV2Marshaller marshaller; private final SharedParametersLoader loader; - String generate() { log.debug("Generating shared parameters"); var parameters = loader.load(); diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersMarshaller.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Marshaller.java similarity index 96% rename from src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersMarshaller.java rename to src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Marshaller.java index d1e5d3c654..49ec9837c3 100644 --- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersMarshaller.java +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2Marshaller.java @@ -38,7 +38,7 @@ import java.io.StringWriter; @Component -class SharedParametersMarshaller { +class SharedParametersV2Marshaller { private final JAXBContext jaxbContext = createJaxbContext(); @SneakyThrows @@ -47,7 +47,7 @@ String marshall(SharedParameters parameters) { var marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setSchema(SharedParametersSchemaValidatorV2.getSchema()); - marshaller.marshal(new ObjectFactory().createConf(SharedParametersConverter.INSTANCE.convert(parameters)), writer); + marshaller.marshal(new ObjectFactory().createConf(SharedParametersV2Converter.INSTANCE.convert(parameters)), writer); return writer.toString(); } diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Converter.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Converter.java new file mode 100644 index 0000000000..5a07b96afe --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Converter.java @@ -0,0 +1,145 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + + +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ApprovedCATypeV2; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ConfigurationSourceType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.GlobalGroupType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.GlobalSettingsType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.MemberType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ObjectFactory; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SecurityServerType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SharedParametersTypeV3; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SubsystemType; +import ee.ria.xroad.common.identifier.ClientId; + +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +import javax.xml.bind.JAXBElement; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static java.util.stream.Collectors.toList; + +@Mapper(uses = {ObjectFactory.class, MappingUtils.class}, unmappedTargetPolicy = ReportingPolicy.ERROR) + +abstract class SharedParametersV3Converter { + public static final SharedParametersV3Converter INSTANCE = Mappers.getMapper(SharedParametersV3Converter.class); + protected static final ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + + SharedParametersTypeV3 convert(SharedParameters sharedParameters) { + return sharedParameters != null ? convert(sharedParameters, createClientIdMap(sharedParameters)) : null; + } + + @Mapping(source = "sources", target = "source") + @Mapping(source = "approvedCAs", target = "approvedCA") + @Mapping(source = "approvedTSAs", target = "approvedTSA") + @Mapping(source = "members", target = "member") + @Mapping(source = "securityServers", target = "securityServer") + @Mapping(source = "globalGroups", target = "globalGroup") + @Mapping(target = "centralService", ignore = true) + abstract SharedParametersTypeV3 convert(SharedParameters sharedParameters, + @Context Map clientMap); + + @Mapping(source = "memberClasses", target = "memberClass") + abstract GlobalSettingsType convert(SharedParameters.GlobalSettings globalSettings); + + @Mapping(source = "verificationCerts", target = "verificationCert") + abstract ConfigurationSourceType convert(SharedParameters.ConfigurationSource configurationSource); + + @Mapping(source = "intermediateCAs", target = "intermediateCA") + abstract ApprovedCATypeV2 convert(SharedParameters.ApprovedCA approvedCa); + + @Mapping(source = "authCertHashes", target = "authCertHash") + @Mapping(source = "clients", target = "client", qualifiedByName = "clientsById") + @Mapping(target = "owner", qualifiedByName = "clientById") + abstract SecurityServerType convert(SharedParameters.SecurityServer securityServer, @Context Map clientMap); + + @Mapping(source = "groupMembers", target = "groupMember") + abstract GlobalGroupType convert(SharedParameters.GlobalGroup globalGroup); + + @Mapping(target = "subsystem", ignore = true) + @Mapping(source = "id", target = "id") + abstract MemberType convertMember(SharedParameters.Member member, String id); + + @Mapping(source = "id", target = "id") + abstract SubsystemType convertSubsystem(SharedParameters.Subsystem subsystem, String id); + + MemberType convertMember(SharedParameters.Member member, @Context Map clientMap) { + return (MemberType) clientMap.get(member.getId()); + } + + @Named("clientById") + Object xmlClientId(ClientId value, @Context Map clientMap) { + return clientMap.get(value); + } + + @Named("clientsById") + List> xmlClientIds(List clientIds, @Context Map clientMap) { + if (clientIds == null) { + return List.of(); + } + return clientIds.stream() + .map(clientId -> OBJECT_FACTORY.createSecurityServerTypeClient(xmlClientId(clientId, clientMap))) + .collect(toList()); + } + + private Map createClientIdMap(SharedParameters sharedParameters) { + if (sharedParameters.getMembers() == null) { + return Map.of(); + } + Map clientMap = new HashMap<>(); + var sequence = new IdSequence(); + + for (SharedParameters.Member member : sharedParameters.getMembers()) { + var memberType = convertMember(member, sequence.nextValue()); + clientMap.put(member.getId(), memberType); + for (SharedParameters.Subsystem subsystem : member.getSubsystems()) { + var subsystemType = convertSubsystem(subsystem, sequence.nextValue()); + clientMap.put(subsystem.getId(), subsystemType); + memberType.getSubsystem().add(subsystemType); + } + } + return clientMap; + } + + private static class IdSequence { + int nextId = 0; + + String nextValue() { + return String.format("id%d", nextId++); + } + } +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Generator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Generator.java new file mode 100644 index 0000000000..642d32b2db --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Generator.java @@ -0,0 +1,46 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class SharedParametersV3Generator { + private final SharedParametersV3Marshaller marshaller; + private final SharedParametersLoader loader; + + String generate() { + log.debug("Generating shared parameters"); + var parameters = loader.load(); + log.trace("Shared parameters loaded: {}", parameters); + return marshaller.marshall(parameters); + } +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Marshaller.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Marshaller.java new file mode 100644 index 0000000000..60166cd9b9 --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3Marshaller.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.SharedParametersSchemaValidatorV3; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ObjectFactory; + +import lombok.SneakyThrows; +import org.springframework.stereotype.Component; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + +import java.io.StringWriter; + +@Component +public class SharedParametersV3Marshaller { + + private final JAXBContext jaxbContext = createJaxbContext(); + + @SneakyThrows + String marshall(SharedParameters parameters) { + var writer = new StringWriter(); + var marshaller = jaxbContext.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + marshaller.setSchema(SharedParametersSchemaValidatorV3.getSchema()); + marshaller.marshal(new ObjectFactory().createConf(SharedParametersV3Converter.INSTANCE.convert(parameters)), + writer); + return writer.toString(); + } + + @SneakyThrows + private JAXBContext createJaxbContext() { + return JAXBContext.newInstance(ObjectFactory.class); + } + +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/V2ConfigurationPartsGenerator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/V2ConfigurationPartsGenerator.java new file mode 100644 index 0000000000..8acd8fdd9a --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/V2ConfigurationPartsGenerator.java @@ -0,0 +1,66 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.ConfigurationConstants; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.CONTENT_ID_SHARED_PARAMETERS; +import static java.nio.charset.StandardCharsets.UTF_8; + +@Component +@RequiredArgsConstructor +public class V2ConfigurationPartsGenerator implements ConfigurationPartsGenerator { + + private static final int CONFIGURATION_VERSION = 2; + + private final PrivateParametersV2Generator privateParametersV2Generator; + private final SharedParametersV2Generator sharedParametersV2Generator; + + public int getConfigurationVersion() { + return CONFIGURATION_VERSION; + } + + public List generateConfigurationParts() { + return List.of( + ConfigurationPart.builder() + .contentIdentifier(ConfigurationConstants.CONTENT_ID_PRIVATE_PARAMETERS) + .filename(ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS) + .data(privateParametersV2Generator.generate().getBytes(UTF_8)) + .build(), + ConfigurationPart.builder() + .contentIdentifier(CONTENT_ID_SHARED_PARAMETERS) + .filename(ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS) + .data(sharedParametersV2Generator.generate().getBytes(UTF_8)) + .build()); + } + +} diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/V3ConfigurationsPartsGenerator.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/V3ConfigurationsPartsGenerator.java new file mode 100644 index 0000000000..31a324b406 --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/V3ConfigurationsPartsGenerator.java @@ -0,0 +1,66 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.ConfigurationConstants; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.CONTENT_ID_SHARED_PARAMETERS; +import static java.nio.charset.StandardCharsets.UTF_8; + +@Component +@RequiredArgsConstructor +public class V3ConfigurationsPartsGenerator implements ConfigurationPartsGenerator { + + private static final int CONFIGURATION_VERSION = 3; + + private final PrivateParametersV3Generator privateParametersV3Generator; + private final SharedParametersV3Generator sharedParametersV3Generator; + + public int getConfigurationVersion() { + return CONFIGURATION_VERSION; + } + + public List generateConfigurationParts() { + return List.of( + ConfigurationPart.builder() + .contentIdentifier(ConfigurationConstants.CONTENT_ID_PRIVATE_PARAMETERS) + .filename(ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS) + .data(privateParametersV3Generator.generate().getBytes(UTF_8)) + .build(), + ConfigurationPart.builder() + .contentIdentifier(CONTENT_ID_SHARED_PARAMETERS) + .filename(ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS) + .data(sharedParametersV3Generator.generate().getBytes(UTF_8)) + .build()); + } + +} diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilderTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilderTest.java index 7d4152f3c9..512601c904 100644 --- a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilderTest.java +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentBuilderTest.java @@ -47,7 +47,8 @@ void buildDirectoryContent() { CryptoUtils.SHA1_ID, Instant.parse("2022-12-08T08:05:01.123Z"), "/V2/some/path", - "CS-INSTANCE"); + "CS-INSTANCE", + 2); var dirContent = directoryContentBuilder .contentPart(ConfigurationPart.builder() .filename("config-file.txt") diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersConverterTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2ConverterTest.java similarity index 94% rename from src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersConverterTest.java rename to src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2ConverterTest.java index 6c55d1c045..e016c9b014 100644 --- a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersConverterTest.java +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2ConverterTest.java @@ -42,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -class PrivateParametersConverterTest { +class PrivateParametersV2ConverterTest { private static final String INSTANCE = "INSTANCE"; private static final String DOWNLOAD_URL = "http://example.com"; private static final byte[] VERIFICATION_CERT = "VERIFICATION_CERT".getBytes(UTF_8); @@ -56,7 +56,7 @@ class PrivateParametersConverterTest { void shouldMapAllProperties() { PrivateParameters privateParameters = getPrivateParameters(); - var xmlType = PrivateParametersConverter.INSTANCE.convert(privateParameters); + var xmlType = PrivateParametersV2Converter.INSTANCE.convert(privateParameters); assertPrivateParameters(xmlType); } @@ -77,9 +77,9 @@ private static void assertPrivateParameters(PrivateParametersType privateParamet () -> assertThat(privateParameters).isNotNull(), () -> assertThat(privateParameters.getInstanceIdentifier()).isEqualTo(INSTANCE), () -> assertThat(privateParameters.getConfigurationAnchor()) - .satisfiesExactly(PrivateParametersConverterTest::assertConfigurationAnchor), + .satisfiesExactly(PrivateParametersV2ConverterTest::assertConfigurationAnchor), () -> assertThat(privateParameters.getManagementService()).satisfies( - PrivateParametersConverterTest::assertManagementService), + PrivateParametersV2ConverterTest::assertManagementService), () -> assertThat(privateParameters.getTimeStampingIntervalSeconds()).isEqualTo(BigInteger.valueOf(TIMESTAMPING_INTERVAL)), () -> assertThat(privateParameters).hasNoNullFieldsOrProperties() ); @@ -99,7 +99,7 @@ private static void assertConfigurationAnchor(ConfigurationAnchorType anchor) { () -> assertThat(anchor.getInstanceIdentifier()).isEqualTo(OTHER_INSTANCE), () -> assertThat(anchor.getGeneratedAt().toGregorianCalendar().toInstant()).isEqualTo(Instant.EPOCH), () -> assertThat(anchor.getSource()) - .satisfiesExactly(PrivateParametersConverterTest::assertConfigurationSource), + .satisfiesExactly(PrivateParametersV2ConverterTest::assertConfigurationSource), () -> assertThat(anchor).hasNoNullFieldsOrProperties() ); } diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersMarshallerTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2MarshallerTest.java similarity index 96% rename from src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersMarshallerTest.java rename to src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2MarshallerTest.java index c2f6fd019d..c4839b9b46 100644 --- a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersMarshallerTest.java +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV2MarshallerTest.java @@ -36,11 +36,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -class PrivateParametersMarshallerTest { +class PrivateParametersV2MarshallerTest { private final ClientId clientId = ClientId.Conf.create("CS", "CLASS", "CODE"); - private final PrivateParametersMarshaller marshaller = new PrivateParametersMarshaller(); + private final PrivateParametersV2Marshaller marshaller = new PrivateParametersV2Marshaller(); @Test void marshall() { diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3ConverterTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3ConverterTest.java new file mode 100644 index 0000000000..c79a447c08 --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3ConverterTest.java @@ -0,0 +1,137 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ConfigurationAnchorType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ConfigurationSourceType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ManagementServiceType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.PrivateParametersType; +import ee.ria.xroad.common.identifier.ClientId; + +import org.junit.jupiter.api.Test; + +import java.math.BigInteger; +import java.time.Instant; +import java.util.List; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +class PrivateParametersV3ConverterTest { + + private static final String INSTANCE = "INSTANCE"; + private static final String DOWNLOAD_URL = "http://example.com"; + private static final byte[] VERIFICATION_CERT = "VERIFICATION_CERT".getBytes(UTF_8); + private static final byte[] AUTH_CERT_REG_SERVICE_CERT = "authCertRegServiceCert".getBytes(UTF_8); + private static final String OTHER_INSTANCE = "OTHER_INSTANCE"; + private static final ClientId + SERVICE_PROVIDER_ID = ClientId.Conf.create(INSTANCE, "MEMBER-CLASS", "SERVICE-PROVIDER"); + private static final String AUTH_CERT_REG_SERVICE_ADDRESS = "http://getAuthCertReg.example.com"; + private static final Integer TIMESTAMPING_INTERVAL = 123; + + @Test + void shouldMapAllProperties() { + PrivateParameters privateParameters = getPrivateParameters(); + + var xmlType = PrivateParametersV3Converter.INSTANCE.convert(privateParameters); + + assertPrivateParameters(xmlType); + } + + private static PrivateParameters getPrivateParameters() { + getConfigurationAnchor(); + + PrivateParameters privateParameters = new PrivateParameters(); + privateParameters.setInstanceIdentifier(INSTANCE); + privateParameters.setConfigurationAnchors(List.of(getConfigurationAnchor())); + privateParameters.setManagementService(getManagementService()); + privateParameters.setTimeStampingIntervalSeconds(TIMESTAMPING_INTERVAL); + return privateParameters; + } + + private static void assertPrivateParameters(PrivateParametersType privateParameters) { + assertAll( + () -> assertThat(privateParameters).isNotNull(), + () -> assertThat(privateParameters.getInstanceIdentifier()).isEqualTo(INSTANCE), + () -> assertThat(privateParameters.getConfigurationAnchor()) + .satisfiesExactly(PrivateParametersV3ConverterTest::assertConfigurationAnchor), + () -> assertThat(privateParameters.getManagementService()).satisfies( + PrivateParametersV3ConverterTest::assertManagementService), + () -> assertThat(privateParameters.getTimeStampingIntervalSeconds()).isEqualTo(BigInteger.valueOf(TIMESTAMPING_INTERVAL)), + () -> assertThat(privateParameters).hasNoNullFieldsOrProperties() + ); + } + + private static PrivateParameters.ConfigurationAnchor getConfigurationAnchor() { + PrivateParameters.ConfigurationSource source = getConfigurationSource(); + PrivateParameters.ConfigurationAnchor anchor = new PrivateParameters.ConfigurationAnchor(); + anchor.setGeneratedAt(Instant.EPOCH); + anchor.setInstanceIdentifier(OTHER_INSTANCE); + anchor.setSources(List.of(source)); + return anchor; + } + + private static void assertConfigurationAnchor(ConfigurationAnchorType anchor) { + assertAll( + () -> assertThat(anchor.getInstanceIdentifier()).isEqualTo(OTHER_INSTANCE), + () -> assertThat(anchor.getGeneratedAt().toGregorianCalendar().toInstant()).isEqualTo(Instant.EPOCH), + () -> assertThat(anchor.getSource()) + .satisfiesExactly(PrivateParametersV3ConverterTest::assertConfigurationSource), + () -> assertThat(anchor).hasNoNullFieldsOrProperties() + ); + } + + private static PrivateParameters.ConfigurationSource getConfigurationSource() { + var source = new PrivateParameters.ConfigurationSource(); + source.setDownloadURL(DOWNLOAD_URL); + source.setVerificationCerts(List.of(VERIFICATION_CERT)); + return source; + } + + private static void assertConfigurationSource(ConfigurationSourceType source) { + assertAll( + () -> assertThat(source.getDownloadURL()).isEqualTo(DOWNLOAD_URL), + () -> assertThat(source.getVerificationCert()).containsExactly(VERIFICATION_CERT), + () -> assertThat(source).hasNoNullFieldsOrProperties()); + } + + private static PrivateParameters.ManagementService getManagementService() { + var managementService = new PrivateParameters.ManagementService(); + managementService.setManagementRequestServiceProviderId(SERVICE_PROVIDER_ID); + managementService.setAuthCertRegServiceAddress(AUTH_CERT_REG_SERVICE_ADDRESS); + managementService.setAuthCertRegServiceCert(AUTH_CERT_REG_SERVICE_CERT); + return managementService; + } + + private static void assertManagementService(ManagementServiceType managementService) { + assertAll( + () -> assertThat(managementService.getManagementRequestServiceProviderId()).isEqualTo(SERVICE_PROVIDER_ID), + () -> assertThat(managementService.getAuthCertRegServiceCert()).isEqualTo(AUTH_CERT_REG_SERVICE_CERT), + () -> assertThat(managementService.getAuthCertRegServiceAddress()).isEqualTo(AUTH_CERT_REG_SERVICE_ADDRESS), + () -> assertThat(managementService).hasNoNullFieldsOrProperties()); + } +} diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3MarshallerTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3MarshallerTest.java new file mode 100644 index 0000000000..826362791c --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/PrivateParametersV3MarshallerTest.java @@ -0,0 +1,88 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.identifier.ClientId; + +import org.junit.jupiter.api.Test; + +import javax.xml.bind.MarshalException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class PrivateParametersV3MarshallerTest { + private final ClientId clientId = ClientId.Conf.create("CS", "CLASS", "CODE"); + + private final PrivateParametersV3Marshaller marshaller = new PrivateParametersV3Marshaller(); + + @Test + void marshall() { + final PrivateParameters privateParams = new PrivateParameters(); + privateParams.setInstanceIdentifier("CS"); + privateParams.setManagementService(new PrivateParameters.ManagementService()); + privateParams.getManagementService().setAuthCertRegServiceAddress("https://cs:4001/managementservice/"); + privateParams.getManagementService().setManagementRequestServiceProviderId(clientId); + privateParams.setTimeStampingIntervalSeconds(60); + + final String result = marshaller.marshall(privateParams); + + assertThat(result).isNotBlank(); + } + + @Test + void marshallShouldFailWhenInvalid() { + final PrivateParameters privateParams = new PrivateParameters(); + // missing instance identifier + privateParams.setManagementService(new PrivateParameters.ManagementService()); + privateParams.getManagementService().setAuthCertRegServiceAddress("https://cs:4001/managementservice/"); + privateParams.getManagementService().setManagementRequestServiceProviderId(clientId); + + assertThrows(MarshalException.class, () -> marshaller.marshall(privateParams)); + } + + @Test + void marshallShouldFailWhenInvalid2() { + final PrivateParameters privateParams = new PrivateParameters(); + privateParams.setInstanceIdentifier("CS"); + // missing managementService + + assertThrows(MarshalException.class, () -> marshaller.marshall(privateParams)); + } + + @Test + void marshallShouldFailWhenInvalid3() { + final PrivateParameters privateParams = new PrivateParameters(); + privateParams.setInstanceIdentifier("CS"); + privateParams.setManagementService(new PrivateParameters.ManagementService()); + privateParams.getManagementService().setAuthCertRegServiceAddress("https://cs:4001/managementservice/"); + privateParams.getManagementService().setManagementRequestServiceProviderId(clientId); + // missing TimeStampingIntervalSeconds + + assertThrows(MarshalException.class, () -> marshaller.marshall(privateParams)); + } +} diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoaderTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoaderTest.java index ebe64628bc..688ce3a5aa 100644 --- a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoaderTest.java +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersLoaderTest.java @@ -36,6 +36,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.niis.xroad.cs.admin.api.domain.ApprovedTsa; import org.niis.xroad.cs.admin.api.domain.AuthCert; +import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKey; import org.niis.xroad.cs.admin.api.domain.FlattenedSecurityServerClientView; import org.niis.xroad.cs.admin.api.domain.GlobalGroup; import org.niis.xroad.cs.admin.api.domain.GlobalGroupMember; @@ -48,6 +49,7 @@ import org.niis.xroad.cs.admin.api.dto.OcspResponder; import org.niis.xroad.cs.admin.api.service.CertificationServicesService; import org.niis.xroad.cs.admin.api.service.ClientService; +import org.niis.xroad.cs.admin.api.service.ConfigurationService; import org.niis.xroad.cs.admin.api.service.GlobalGroupMemberService; import org.niis.xroad.cs.admin.api.service.GlobalGroupService; import org.niis.xroad.cs.admin.api.service.MemberClassService; @@ -56,6 +58,7 @@ import org.niis.xroad.cs.admin.api.service.TimestampingServicesService; import java.util.List; +import java.util.Map; import java.util.Set; import static ee.ria.xroad.common.identifier.XRoadObjectType.MEMBER; @@ -66,29 +69,31 @@ @ExtendWith(MockitoExtension.class) class SharedParametersLoaderTest { - public static final String CA_NAME = "ca name"; - public static final byte[] CA_CERT = "ca cert".getBytes(UTF_8); - public static final String CA_PROFILE_INFO = "profile-info"; - public static final String CA_OCSP_URL = "ca ocsp url"; - public static final byte[] CA_OCSP_CERT = "ca ocsp cert".getBytes(UTF_8); - public static final byte[] INTERMEDIATE_CA_CERT = "intermediate ca cert".getBytes(UTF_8); - public static final String INTERMEDIATE_CA_OCSP_URL = "intermediate ca ocsp url"; - public static final byte[] INTERMEDIATE_CA_OCSP_CERT = "intermediate ca ocsp cert".getBytes(UTF_8); - public static final String TSA_NAME = "TSA name"; - public static final String TSA_URL = "TSA url"; - public static final byte[] TSA_CERT = "TSA cert".getBytes(UTF_8); - public static final String XROAD_INSTANCE = "XRD"; - public static final String SECURITY_SERVER_ADDRESS = "security-server-address"; - public static final String SECURITY_SERVER_CODE = "SS1"; - public static final int SECURITY_SERVER_ID = 1; - public static final byte[] SECURITY_SERVER_AUTH_CERT = "auth cert".getBytes(UTF_8); - public static final String GLOBAL_GROUP_CODE = "GG"; - public static final String GLOBAL_GROUP_DESCRIPTION = "GG description"; - public static final int GLOBAL_GROUP_ID = 2; - public static final String CENTRAL_SERVICE_CODE = "service-code"; - public static final String MEMBER_CLASS_CODE = "MCLASS"; - public static final String MEMBER_CLASS_DESCRIPTION = "Member class description"; - public static final int OCSP_FRESHNESS_SECONDS = 333; + private static final String CA_NAME = "ca name"; + private static final byte[] CA_CERT = "ca cert".getBytes(UTF_8); + private static final String CA_PROFILE_INFO = "profile-info"; + private static final String CA_OCSP_URL = "ca ocsp url"; + private static final byte[] CA_OCSP_CERT = "ca ocsp cert".getBytes(UTF_8); + private static final byte[] INTERMEDIATE_CA_CERT = "intermediate ca cert".getBytes(UTF_8); + private static final String INTERMEDIATE_CA_OCSP_URL = "intermediate ca ocsp url"; + private static final byte[] INTERMEDIATE_CA_OCSP_CERT = "intermediate ca ocsp cert".getBytes(UTF_8); + private static final String TSA_NAME = "TSA name"; + private static final String TSA_URL = "TSA url"; + private static final byte[] TSA_CERT = "TSA cert".getBytes(UTF_8); + private static final String XROAD_INSTANCE = "XRD"; + private static final String SECURITY_SERVER_ADDRESS = "security-server-address"; + private static final String SECURITY_SERVER_CODE = "SS1"; + private static final int SECURITY_SERVER_ID = 1; + private static final byte[] SECURITY_SERVER_AUTH_CERT = "auth cert".getBytes(UTF_8); + private static final String GLOBAL_GROUP_CODE = "GG"; + private static final String GLOBAL_GROUP_DESCRIPTION = "GG description"; + private static final int GLOBAL_GROUP_ID = 2; + private static final String MEMBER_CLASS_CODE = "MCLASS"; + private static final String MEMBER_CLASS_DESCRIPTION = "Member class description"; + private static final int OCSP_FRESHNESS_SECONDS = 333; + private static final String CENTRAL_SERVICE = "cs"; + private static final byte[] CONFIGURATION_SIGNING_CERT = "conf signing cert".getBytes(UTF_8); + @Mock SystemParameterService systemParameterService; @Mock @@ -105,6 +110,8 @@ class SharedParametersLoaderTest { GlobalGroupMemberService globalGroupMemberService; @Mock MemberClassService memberClassService; + @Mock + ConfigurationService configurationService; @InjectMocks SharedParametersLoader sharedParametersLoader; @@ -112,6 +119,8 @@ class SharedParametersLoaderTest { @Test void loadSharedParameters() { when(systemParameterService.getInstanceIdentifier()).thenReturn(XROAD_INSTANCE); + when(configurationService.getNodeAddressesWithConfigurationSigningKeys()) + .thenReturn(getNodeAddressesWithConfigurationSigningKeys()); when(certificationServicesService.findAll()).thenReturn(List.of(getCertificationService())); when(timestampingServicesService.getTimestampingServices()).thenReturn(Set.of(getApprovedTsa())); @@ -132,6 +141,7 @@ void loadSharedParameters() { assertThat(parameters).isNotNull(); assertThat(parameters.getInstanceIdentifier()).isEqualTo(XROAD_INSTANCE); + assertNodeAddressesWithConfigurationSigningKeys(parameters); assertApprovedCa(parameters); assertApproveTsa(parameters); assertSecurityServers(parameters); @@ -199,6 +209,17 @@ private void assertApprovedCa(SharedParameters parameters) { }); } + private void assertNodeAddressesWithConfigurationSigningKeys(SharedParameters parameters) { + assertThat(parameters.getSources()).singleElement().satisfies(src -> { + assertThat(src.getAddress()).isEqualTo(CENTRAL_SERVICE); + assertThat(src.getVerificationCerts()).hasSize(1); + assertThat(src.getVerificationCerts().get(0)).isEqualTo(CONFIGURATION_SIGNING_CERT); + }); + } + + private Map> getNodeAddressesWithConfigurationSigningKeys() { + return Map.of(CENTRAL_SERVICE, List.of(new ConfigurationSigningKey().setCert(CONFIGURATION_SIGNING_CERT))); + } private CertificationService getCertificationService() { var certificationService = new CertificationService(); diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersConverterTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2ConverterTest.java similarity index 95% rename from src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersConverterTest.java rename to src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2ConverterTest.java index af1e9088f7..04fe987682 100644 --- a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersConverterTest.java +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2ConverterTest.java @@ -52,7 +52,7 @@ import static org.assertj.core.api.Assertions.assertThatNoException; @Slf4j -class SharedParametersConverterTest { +class SharedParametersV2ConverterTest { private static final Map FIELD_NAME_MAP = Map.ofEntries( entry("securityServer", "securityServers"), entry("approvedCA", "approvedCAs"), @@ -70,7 +70,7 @@ class SharedParametersConverterTest { @Test void shouldConvertAllFields() { var sharedParameters = getSharedParameters(); - var xmlType = SharedParametersConverter.INSTANCE.convert(sharedParameters); + var xmlType = SharedParametersV2Converter.INSTANCE.convert(sharedParameters); var conf = RecursiveComparisonConfiguration.builder() .withIntrospectionStrategy(compareRenamedFields()) @@ -100,7 +100,7 @@ void shouldConvertAllFields() { @Test void shouldBeAbleToMarshall() throws JAXBException { - var xmlType = SharedParametersConverter.INSTANCE.convert(getSharedParameters()); + var xmlType = SharedParametersV2Converter.INSTANCE.convert(getSharedParameters()); JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class); var writer = new StringWriter(); @@ -113,6 +113,11 @@ void shouldBeAbleToMarshall() throws JAXBException { log.info(writer.toString()); } + @Test + void shouldReturnNullWhenInputIsNull() { + assertThat(SharedParametersV2Converter.INSTANCE.convert((SharedParameters) null)).isNull(); + } + private static void assertIdReferences(SharedParametersTypeV2 xmlType) { var ownerMember = xmlType.getMember().get(0); var client = ownerMember.getSubsystem().get(0); diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersMarshallerTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2MarshallerTest.java similarity index 95% rename from src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersMarshallerTest.java rename to src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2MarshallerTest.java index 48175ea441..451c758d0b 100644 --- a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersMarshallerTest.java +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV2MarshallerTest.java @@ -34,9 +34,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -class SharedParametersMarshallerTest { +class SharedParametersV2MarshallerTest { - private final SharedParametersMarshaller marshaller = new SharedParametersMarshaller(); + private final SharedParametersV2Marshaller marshaller = new SharedParametersV2Marshaller(); @Test void marshall() { diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3ConverterTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3ConverterTest.java new file mode 100644 index 0000000000..2c6c06505b --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3ConverterTest.java @@ -0,0 +1,223 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ObjectFactory; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SharedParametersTypeV3; +import ee.ria.xroad.common.identifier.ClientId; + +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.recursive.comparison.ComparingNormalizedFields; +import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; +import org.junit.jupiter.api.Test; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; + +import java.io.StringWriter; +import java.math.BigInteger; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Map.entry; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; + +@Slf4j +class SharedParametersV3ConverterTest { + + private static final Map FIELD_NAME_MAP = Map.ofEntries( + entry("securityServer", "securityServers"), + entry("source", "sources"), + entry("verificationCert", "verificationCerts"), + entry("approvedCA", "approvedCAs"), + entry("approvedTSA", "approvedTSAs"), + entry("member", "members"), + entry("globalGroup", "globalGroups"), + entry("intermediateCA", "intermediateCAs"), + entry("subsystem", "subsystems"), + entry("client", "clients"), + entry("memberClass", "memberClasses"), + entry("authCertHash", "authCertHashes"), + entry("groupMember", "groupMembers") + ); + + @Test + void shouldConvertAllFields() { + var sharedParameters = getSharedParameters(); + var xmlType = SharedParametersV3Converter.INSTANCE.convert(sharedParameters); + + var conf = RecursiveComparisonConfiguration.builder() + .withIntrospectionStrategy(compareRenamedFields()) + .withIgnoredFields("securityServers.owner", + "securityServers.clients", + "members.id", + "members.subsystems.id", + "centralService", + "sources.verificationCerts" + ) + .withEqualsForFields((a, b) -> + new BigInteger(a.toString()).compareTo(new BigInteger(b.toString())) == 0, + "globalSettings.ocspFreshnessSeconds") + .build(); + + assertThat(xmlType) + .hasNoNullFieldsOrPropertiesExcept("centralService") + .usingRecursiveComparison(conf) + .isEqualTo(sharedParameters); + + assertThat(xmlType) + .usingRecursiveAssertion() + .ignoringFields("globalGroup.groupMember.id") + .allFieldsSatisfy(Objects::nonNull); + + assertIdReferences(xmlType); + } + + @Test + void shouldBeAbleToMarshall() throws JAXBException { + var xmlType = SharedParametersV3Converter.INSTANCE.convert(getSharedParameters()); + + JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class); + var writer = new StringWriter(); + var marshaller = jaxbContext.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + var conf = new ObjectFactory().createConf(xmlType); + + assertThatNoException().isThrownBy(() -> marshaller.marshal(conf, writer)); + + log.info(writer.toString()); + } + + @Test + void shouldReturnNullWhenInputIsNull() { + assertThat(SharedParametersV3Converter.INSTANCE.convert((SharedParameters) null)).isNull(); + } + + private static void assertIdReferences(SharedParametersTypeV3 xmlType) { + var ownerMember = xmlType.getMember().get(0); + var client = ownerMember.getSubsystem().get(0); + + assertThat(ownerMember).isNotNull(); + assertThat(client).isNotNull(); + + assertThat(xmlType.getSecurityServer()).singleElement() + .satisfies(ss -> { + assertThat(ss.getOwner()).isSameAs(ownerMember); + assertThat(ss.getClient()) + .map(JAXBElement::getValue) + .singleElement().isSameAs(client); + }); + } + + private static ComparingNormalizedFields compareRenamedFields() { + return new ComparingNormalizedFields() { + @Override + protected String normalizeFieldName(String fieldName) { + return FIELD_NAME_MAP.getOrDefault(fieldName, fieldName); + } + }; + } + + private static SharedParameters getSharedParameters() { + var parameters = new SharedParameters(); + parameters.setInstanceIdentifier("INSTANCE"); + parameters.setSources(getConfigurationSources()); + parameters.setApprovedCAs(List.of(getApprovedCA())); + parameters.setApprovedTSAs(List.of(new SharedParameters.ApprovedTSA("tsa-name", "tsa-url", "tsa cert".getBytes(UTF_8)))); + parameters.setMembers(getMembers()); + parameters.setSecurityServers(List.of(getSecurityServer())); + parameters.setGlobalGroups(List.of(new SharedParameters.GlobalGroup("group-code", "group-description", + List.of(subsystemId(memberId(), "SUB1"))))); + parameters.setGlobalSettings(new SharedParameters.GlobalSettings(List.of(getMemberClass()), 333)); + return parameters; + } + + private static List getConfigurationSources() { + var configurationSource = new SharedParameters.ConfigurationSource(); + configurationSource.setAddress("cs"); + configurationSource.setVerificationCerts(List.of("conf-singing-cert".getBytes(UTF_8))); + return List.of(configurationSource); + } + + private static SharedParameters.ApprovedCA getApprovedCA() { + var approvedCA = new SharedParameters.ApprovedCA(); + approvedCA.setName("approved ca name"); + approvedCA.setAuthenticationOnly(true); + approvedCA.setTopCA(getCaInfo()); + approvedCA.setCertificateProfileInfo("certificateProfileInfo"); + approvedCA.setIntermediateCAs(List.of(getCaInfo())); + return approvedCA; + } + + private static SharedParameters.CaInfo getCaInfo() { + return new SharedParameters.CaInfo(List.of( + new SharedParameters.OcspInfo("ocsp:url", "ocsp-cert".getBytes(UTF_8))), "ca-cert".getBytes(UTF_8)); + } + + private static List getMembers() { + SharedParameters.Member member = new SharedParameters.Member(); + member.setMemberCode("M1"); + member.setMemberClass(getMemberClass()); + member.setName("Member1"); + var clientId = memberId(); + member.setId(clientId); + member.setSubsystems(List.of(subsystem(clientId, "SUB1"))); + return List.of(member); + } + + private static ClientId.Conf memberId() { + return ClientId.Conf.create("INSTANCE", "CLASS1", "M1"); + } + + private static SharedParameters.SecurityServer getSecurityServer() { + var securityServer = new SharedParameters.SecurityServer(); + securityServer.setOwner(memberId()); + securityServer.setServerCode("security-server-code"); + securityServer.setAddress("security-server-address"); + securityServer.setClients(List.of(subsystemId(memberId(), "SUB1"))); + securityServer.setAuthCertHashes(List.of("ss-auth-cert".getBytes(UTF_8))); + return securityServer; + } + + private static SharedParameters.MemberClass getMemberClass() { + return new SharedParameters.MemberClass("CLASS1", "member class description"); + } + + private static SharedParameters.Subsystem subsystem(ClientId.Conf clientId, String subsystemCode) { + return new SharedParameters.Subsystem(subsystemCode, subsystemId(clientId, subsystemCode)); + } + + private static ClientId.Conf subsystemId(ClientId.Conf clientId, String subsystemCode) { + return ClientId.Conf.create(clientId.getXRoadInstance(), clientId.getXRoadInstance(), clientId.getMemberCode(), subsystemCode); + } + +} diff --git a/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3MarshallerTest.java b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3MarshallerTest.java new file mode 100644 index 0000000000..049b695798 --- /dev/null +++ b/src/central-server/admin-service/globalconf-generator/src/test/java/org/niis/xroad/cs/admin/globalconf/generator/SharedParametersV3MarshallerTest.java @@ -0,0 +1,69 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.niis.xroad.cs.admin.globalconf.generator; + +import org.junit.jupiter.api.Test; + +import javax.xml.bind.MarshalException; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class SharedParametersV3MarshallerTest { + + private final SharedParametersV3Marshaller marshaller = new SharedParametersV3Marshaller(); + + @Test + void marshall() { + SharedParameters sharedParams = new SharedParameters(); + sharedParams.setInstanceIdentifier("CS"); + + var configurationSource = new SharedParameters.ConfigurationSource(); + configurationSource.setAddress("cs"); + configurationSource.setVerificationCerts(List.of("conf-signing-cert".getBytes(StandardCharsets.UTF_8))); + sharedParams.setGlobalSettings(new SharedParameters.GlobalSettings(null, 60)); + sharedParams.setSources(List.of(configurationSource)); + + final String result = marshaller.marshall(sharedParams); + + assertThat(result).isNotBlank(); + } + + @Test + void marshallShouldFailWhenInvalid() { + SharedParameters sharedParams = new SharedParameters(); + sharedParams.setInstanceIdentifier("CS"); + sharedParams.setSources(List.of(new SharedParameters.ConfigurationSource())); // missing address or cert + sharedParams.setGlobalSettings(new SharedParameters.GlobalSettings(null, 60)); + assertThrows(MarshalException.class, () -> marshaller.marshall(sharedParams)); + } + + +} diff --git a/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/openapi/ConfigurationSourcesController.java b/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/openapi/ConfigurationSourcesController.java index 1f21b89525..913e84136d 100644 --- a/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/openapi/ConfigurationSourcesController.java +++ b/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/openapi/ConfigurationSourcesController.java @@ -28,6 +28,7 @@ import lombok.RequiredArgsConstructor; import org.niis.xroad.cs.admin.api.domain.ConfigurationSourceType; +import org.niis.xroad.cs.admin.api.dto.HAConfigStatus; import org.niis.xroad.cs.admin.api.service.ConfigurationService; import org.niis.xroad.cs.admin.rest.api.converter.GlobalConfDownloadUrlDtoConverter; import org.niis.xroad.cs.openapi.ConfigurationSourcesApi; @@ -50,13 +51,14 @@ public class ConfigurationSourcesController implements ConfigurationSourcesApi { private final ConfigurationService configurationService; private final GlobalConfDownloadUrlDtoConverter globalConfDownloadUrlDtoConverter; + private final HAConfigStatus currentHaConfigStatus; @Override @PreAuthorize("(hasAuthority('VIEW_INTERNAL_CONFIGURATION_SOURCE') and #configurationType.value == 'INTERNAL') " + "or (hasAuthority('VIEW_EXTERNAL_CONFIGURATION_SOURCE') and #configurationType.value == 'EXTERNAL')") public ResponseEntity getDownloadUrl(ConfigurationTypeDto configurationType) { return ok(globalConfDownloadUrlDtoConverter.convert( - configurationService - .getGlobalDownloadUrl(ConfigurationSourceType.valueOf(configurationType.getValue())))); + configurationService.getGlobalDownloadUrl(ConfigurationSourceType.valueOf(configurationType.getValue()))) + ); } } diff --git a/src/central-server/admin-service/infra-jpa/src/main/java/org/niis/xroad/cs/admin/jpa/repository/JpaConfigurationSigningKeyRepository.java b/src/central-server/admin-service/infra-jpa/src/main/java/org/niis/xroad/cs/admin/jpa/repository/JpaConfigurationSigningKeyRepository.java index 1e6b45e96a..843086e71a 100644 --- a/src/central-server/admin-service/infra-jpa/src/main/java/org/niis/xroad/cs/admin/jpa/repository/JpaConfigurationSigningKeyRepository.java +++ b/src/central-server/admin-service/infra-jpa/src/main/java/org/niis/xroad/cs/admin/jpa/repository/JpaConfigurationSigningKeyRepository.java @@ -32,6 +32,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository @@ -44,6 +45,11 @@ public interface JpaConfigurationSigningKeyRepository + "AND (:haNodeName is null OR cs.haNodeName = :haNodeName)") Optional findActiveForSource(String sourceType, String haNodeName); + @Override + @Query("SELECT cs.configurationSigningKey FROM ConfigurationSourceEntity cs " + + "WHERE cs.sourceType in :sourceTypes") + List findForSourceIn(List sourceTypes); + @Override @Query("SELECT count(sk.id) FROM ConfigurationSigningKeyEntity sk " + "WHERE sk.configurationSource.sourceType = :sourceType " diff --git a/src/common/common-test/src/main/java/ee/ria/xroad/common/conf/globalconf/EmptyGlobalConf.java b/src/common/common-test/src/main/java/ee/ria/xroad/common/conf/globalconf/EmptyGlobalConf.java index a904c7f7de..8b862483a9 100644 --- a/src/common/common-test/src/main/java/ee/ria/xroad/common/conf/globalconf/EmptyGlobalConf.java +++ b/src/common/common-test/src/main/java/ee/ria/xroad/common/conf/globalconf/EmptyGlobalConf.java @@ -28,7 +28,6 @@ import ee.ria.xroad.common.cert.CertChain; import ee.ria.xroad.common.certificateprofile.AuthCertificateProfileInfo; import ee.ria.xroad.common.certificateprofile.SignCertificateProfileInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -215,12 +214,12 @@ public String getMemberName(ClientId member) { } @Override - public List getApprovedTsps(String instanceIdentifier) { + public List getApprovedTspUrls(String instanceIdentifier) { return null; } @Override - public List getApprovedTspTypes(String instanceIdentifier) { + public List getApprovedTsps(String instanceIdentifier) { return null; } @@ -236,7 +235,7 @@ public SecurityServerId.Conf getServerId(X509Certificate cert) throws Exception } @Override - public ClientId.Conf getServerOwner(SecurityServerId serverId) { + public ClientId getServerOwner(SecurityServerId serverId) { return null; } diff --git a/src/common/common-util/build.gradle b/src/common/common-util/build.gradle index c2032d4101..304fd7aff2 100644 --- a/src/common/common-util/build.gradle +++ b/src/common/common-util/build.gradle @@ -90,22 +90,38 @@ task xjc() { binding: 'src/main/resources/identifiers-bindings.xml' ) - // Generate classes for federateable global external conf + // Generate classes for federateable global external conf v2 ant.xjc( destdir: project.ext.schemaTargetDir, package: 'ee.ria.xroad.common.conf.globalconf.sharedparameters.v2', - schema: 'src/main/resources/globalconf/shared-parameters.xsd', + schema: 'src/main/resources/globalconf/v2/shared-parameters.xsd', binding: 'src/main/resources/identifiers-bindings.xml' ) - // Generate classes for federateable global internal conf + // Generate classes for federateable global internal conf v2 ant.xjc( destdir: project.ext.schemaTargetDir, package: 'ee.ria.xroad.common.conf.globalconf.privateparameters.v2', - schema: 'src/main/resources/globalconf/private-parameters.xsd', + schema: 'src/main/resources/globalconf/v2/private-parameters.xsd', binding: 'src/main/resources/identifiers-bindings.xml' ) + // Generate classes for federateable global external conf v3 + ant.xjc( + destdir: project.ext.schemaTargetDir, + package: 'ee.ria.xroad.common.conf.globalconf.sharedparameters.v3', + schema: 'src/main/resources/globalconf/v3/shared-parameters.xsd', + binding: 'src/main/resources/identifiers-bindings.xml' + ) + + // Generate classes for federateable global internal conf v3 + ant.xjc( + destdir: project.ext.schemaTargetDir, + package: 'ee.ria.xroad.common.conf.globalconf.privateparameters.v3', + schema: 'src/main/resources/globalconf/v2/private-parameters.xsd', + binding: 'src/main/resources/identifiers-bindings.xml' + ) + // Generate classes for request, using identifier classes ant.xjc( destdir: project.ext.schemaTargetDir, diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java index 9837167fe4..f7717b8204 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java @@ -53,7 +53,7 @@ private SystemProperties() { PREFIX + "common.configuration-path"; /** Current version number of the global configuration **/ - public static final int CURRENT_GLOBAL_CONFIGURATION_VERSION = 2; + public static final int CURRENT_GLOBAL_CONFIGURATION_VERSION = 3; /** Minimum supported version number of the global configuration **/ static final int MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION = 2; @@ -1633,16 +1633,16 @@ public static int getHealthCheckPort() { */ public static int getMinimumCentralServerGlobalConfigurationVersion() { // read the setting - int version = Integer.parseInt(System.getProperty(MINIMUM_CENTRAL_SERVER_GLOBAL_CONFIGURATION_VERSION, + int minVersion = Integer.parseInt(System.getProperty(MINIMUM_CENTRAL_SERVER_GLOBAL_CONFIGURATION_VERSION, DEFAULT_MINIMUM_CENTRAL_SERVER_GLOBAL_CONFIGURATION_VERSION)); // check that it is a valid looking version number - checkVersionValidity(version, CURRENT_GLOBAL_CONFIGURATION_VERSION, + checkVersionValidity(minVersion, CURRENT_GLOBAL_CONFIGURATION_VERSION, DEFAULT_MINIMUM_CENTRAL_SERVER_GLOBAL_CONFIGURATION_VERSION); // ignore the versions that are no longer supported - if (version < MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION) { - version = MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION; + if (minVersion < MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION) { + minVersion = MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION; } - return version; + return minVersion; } /** @@ -1650,17 +1650,17 @@ public static int getMinimumCentralServerGlobalConfigurationVersion() { */ public static int getMinimumConfigurationProxyGlobalConfigurationVersion() { // read the setting - int version = Integer.parseInt(System.getProperty( + int minVersion = Integer.parseInt(System.getProperty( MINIMUM_CONFIGURATION_PROXY_SERVER_GLOBAL_CONFIGURATION_VERSION, DEFAULT_MINIMUM_CONFIGURATION_PROXY_SERVER_GLOBAL_CONFIGURATION_VERSION)); // check that it is a valid looking version number - checkVersionValidity(version, CURRENT_GLOBAL_CONFIGURATION_VERSION, + checkVersionValidity(minVersion, CURRENT_GLOBAL_CONFIGURATION_VERSION, DEFAULT_MINIMUM_CONFIGURATION_PROXY_SERVER_GLOBAL_CONFIGURATION_VERSION); // ignore the versions that are no longer supported - if (version < MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION) { - version = MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION; + if (minVersion < MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION) { + minVersion = MINIMUM_SUPPORTED_GLOBAL_CONFIGURATION_VERSION; } - return version; + return minVersion; } /** @@ -1686,8 +1686,8 @@ public static long getServerConfAclCacheSize() { return Long.getLong(SERVER_CONF_ACL_CACHE_SIZE, 100_000); } - private static void checkVersionValidity(int version, int current, String defaultVersion) { - if (version > current || version < 1) { + private static void checkVersionValidity(int min, int current, String defaultVersion) { + if (min > current || min < 1) { throw new IllegalArgumentException("Illegal minimum global configuration version in system parameters"); } } diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/AbstractXmlConf.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/AbstractXmlConf.java index 797d2f9cfe..c2a883a082 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/AbstractXmlConf.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/AbstractXmlConf.java @@ -30,6 +30,7 @@ import ee.ria.xroad.common.util.ResourceUtils; import ee.ria.xroad.common.util.SchemaValidator; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import javax.xml.bind.JAXBContext; @@ -70,6 +71,7 @@ public abstract class AbstractXmlConf implements ConfProvider { protected JAXBElement root; + @Getter protected T confType; private FileContentChangeChecker confFileChecker; diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorV2.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchor.java similarity index 88% rename from src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorV2.java rename to src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchor.java index b520ee9ee4..5f516e6725 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorV2.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchor.java @@ -43,29 +43,25 @@ * Configuration anchor specifies the configuration source where a security * server can download global configuration. */ -public class ConfigurationAnchorV2 +public class ConfigurationAnchor extends AbstractXmlConf implements ConfigurationSource { private static final JAXBContext JAXB_CONTEXT = createJAXBContext(); - ConfigurationAnchorV2(ConfigurationAnchorType t) { - confType = t; - } - /** * @param fileName the configuration anchor file name */ - public ConfigurationAnchorV2(String fileName) { + public ConfigurationAnchor(String fileName) { super(fileName, PrivateParametersSchemaValidatorV2.class); // also applies to stand-alone configuration source } /** * A special constructor for creating a ConfigurationAnchorV2 from bytes instead of a file on the filesystem. * Does not set confFileChecker. This constructor is used e.g. for creating a preview of an - * anchor. {@link ConfigurationAnchorV2#ConfigurationAnchorV2(String)} should usually be preferred! + * anchor. {@link ConfigurationAnchor#ConfigurationAnchor(String)} should usually be preferred! * @param fileBytes the configuration anchor file bytes */ - public ConfigurationAnchorV2(byte[] fileBytes) { + public ConfigurationAnchor(byte[] fileBytes) { super(fileBytes, PrivateParametersSchemaValidatorV2.class); } @@ -88,9 +84,9 @@ public String getInstanceIdentifier() { @Override public List getLocations() { - return confType.getSource().stream().map(l -> new ConfigurationLocation(this, - ConfigurationUtils.generateConfigurationLocation(l.getDownloadURL(), 2), l.getVerificationCert())) - .collect(Collectors.toList()); + return confType.getSource().stream() + .map(l -> new ConfigurationLocation(this, l.getDownloadURL(), l.getVerificationCert())) + .collect(Collectors.toList()); } @Override diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectory.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectory.java index 628deb1b35..9473f8f7dc 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectory.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectory.java @@ -152,7 +152,6 @@ public FileVisitResult visitFile( * * @param consumer the function instance that should be applied to all files belonging to the configuration * directory. - * @throws Exception if an error occurs */ - void eachFile(FileConsumer consumer) throws Exception; + void eachFile(FileConsumer consumer) throws IOException; } diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2.java index 604262478f..02e74a2030 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2.java @@ -25,249 +25,38 @@ */ package ee.ria.xroad.common.conf.globalconf; -import ee.ria.xroad.common.CodedException; -import ee.ria.xroad.common.util.TimeUtils; - -import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.OffsetDateTime; -import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static ee.ria.xroad.common.ErrorCodes.X_INTERNAL_ERROR; -import static ee.ria.xroad.common.conf.globalconf.ConfigurationUtils.escapeInstanceIdentifier; /** - * Class for reading global configuration directory. The directory must have sub directory per instance identifier. - * Each sub directory must contain private and/or shared parameters. - * - * When querying the parameters from this class, the parameters XML is checked for modifications and if the XML has - * been modified, the parameters are reloaded from the XML. + * Class for reading version 2 of global configuration directory. The directory must have subdirectory per instance + * identifier. + * Each subdirectory must contain private and/or shared parameters. + *
When querying the parameters from this class, the parameters XML is checked for modifications and if the XML + * has been modified, the parameters are reloaded from the XML. */ @Slf4j -public class ConfigurationDirectoryV2 implements ConfigurationDirectory { - - @Getter - private final Path path; +public class ConfigurationDirectoryV2 extends VersionableConfigurationDirectory { - private final String instanceIdentifier; - - private final Map privateParameters = new HashMap<>(); - private final Map sharedParameters = new HashMap<>(); - - // ------------------------------------------------------------------------ - - /** - * Constructs new directory from the given path. - * @param directoryPath the path to the directory. - * @throws Exception if loading configuration fails - */ public ConfigurationDirectoryV2(String directoryPath) throws Exception { - this.path = Paths.get(directoryPath); - - instanceIdentifier = loadInstanceIdentifier(); - - // empty maps as placeholders - loadParameters(new HashMap<>(), new HashMap<>()); + super(directoryPath); } - /** - * Constructs new directory from the given path using parts from provided base that have not changed. - * @param directoryPath the path to the directory. - * @param base existing configurationdirectory to look for reusable parameter objects - * @throws Exception if loading configuration fails - */ public ConfigurationDirectoryV2(String directoryPath, ConfigurationDirectoryV2 base) throws Exception { - this.path = Paths.get(directoryPath); - - instanceIdentifier = loadInstanceIdentifier(); - - loadParameters(base.privateParameters, base.sharedParameters); - } - - /** - * @return the instance identifier of this configuration. The instance identifier is lazy initialized. - */ - public String getInstanceIdentifier() { - return instanceIdentifier; + super(directoryPath, base); } - /** - * Reloads the configuration directory. Only files that are new or have changed, are actually loaded. - * @throws Exception if an error occurs during reload - */ - private void loadParameters(Map basePrivateParams, - Map baseSharedParams) throws Exception { - log.trace("Reloading configuration from {}", path); + @Override + protected PrivateParametersV2 loadPrivateParameters(String instanceId, Map basePrivateParameters) + throws Exception { - try (DirectoryStream stream = Files.newDirectoryStream(path, Files::isDirectory)) { - for (Path instanceDir : stream) { - log.trace("Loading parameters from {}", instanceDir); - loadPrivateParameters(instanceDir, basePrivateParams); - loadSharedParameters(instanceDir, baseSharedParams); - } - } - } - - /** - * Returns private parameters for a given instance identifier. - * @param instanceId the instance identifier - * @return private parameters or null, if no private parameters exist for given instance identifier - * @throws Exception if an error occurs while reading parameters - */ - public PrivateParametersV2 getPrivate(String instanceId) throws Exception { - String safeInstanceId = escapeInstanceIdentifier(instanceId); - - log.trace("getPrivate(instance = {}, directory = {})", instanceId, safeInstanceId); - - return privateParameters.get(safeInstanceId); - } - - /** - * Returns shared parameters for a given instance identifier. - * @param instanceId the instance identifier - * @return shared parameters or null, if no shared parameters exist for given instance identifier - * @throws Exception if an error occurs while reading parameters - */ - public SharedParametersV2 getShared(String instanceId) throws Exception { - String safeInstanceId = escapeInstanceIdentifier(instanceId); - - log.trace("getShared(instance = {}, directory = {})", instanceId, safeInstanceId); - - SharedParametersV2 parameters = sharedParameters.get(safeInstanceId); - // ignore federated parameters that are expired - if (parameters != null - && (parameters.getInstanceIdentifier().equals(instanceIdentifier) - || parameters.getExpiresOn().isAfter(TimeUtils.offsetDateTimeNow()))) { - return parameters; - } - return null; - } - - /** - * @return all known shared parameters - */ - public List getShared() { - OffsetDateTime now = TimeUtils.offsetDateTimeNow(); - return sharedParameters.values() - .stream() - .filter(p -> p.getInstanceIdentifier().equals(instanceIdentifier) || p.getExpiresOn().isAfter(now)) - .collect(Collectors.toList()); - } - - /** - * Applies the given function to all files belonging to the configuration directory. - * @param consumer the function instance that should be applied to - * @throws Exception if an error occurs - */ - private synchronized void eachFile(final Consumer consumer) throws Exception { - getConfigurationFiles().forEach(consumer); - } - - protected List getConfigurationFiles() throws Exception { - return excludeMetadataAndDirs(Files.walk(path)); - } - - private List excludeMetadataAndDirs(Stream stream) { - return stream.filter(Files::isRegularFile) - .filter(p -> !p.toString().endsWith(ConfigurationDirectory.FILES)) - .filter(p -> !p.toString().endsWith(ConfigurationDirectory.INSTANCE_IDENTIFIER_FILE)) - .filter(p -> !p.toString().endsWith(ConfigurationDirectory.METADATA_SUFFIX)) - .collect(Collectors.toList()); - } - - /** - * Applies the given function to all files belonging to the configuration directory. - * @param consumer the function instance that should be applied to all files belonging to the - * configuration directory. - * @throws Exception if an error occurs - */ - public synchronized void eachFile(FileConsumer consumer) throws Exception { - eachFile(filepath -> { - try (InputStream is = new FileInputStream(filepath.toFile())) { - log.trace("Processing '{}'", filepath); - - ConfigurationPartMetadata metadata; - - try { - metadata = getMetadata(filepath); - } catch (IOException e) { - log.error("Could not open configuration file '{}' metadata: {}", filepath, e); - throw e; - } - - consumer.consume(metadata, is); - } catch (RuntimeException e) { - log.error("Error processing configuration file '{}': {}", filepath, e); - - throw e; - } catch (Exception e) { - log.error("Error processing configuration file '{}': {}", filepath, e); - - throw new RuntimeException(e); - } - }); - } - - /** - * Gets the metadata for the given file. - * @param fileName the file name - * @return the metadata for the given file or null if metadata file does not exist. - * @throws Exception if the metadata cannot be loaded - */ - public static ConfigurationPartMetadata getMetadata(Path fileName) throws IOException { - File file = new File(fileName.toString() + ConfigurationConstants.FILE_NAME_SUFFIX_METADATA); - try (InputStream in = new FileInputStream(file)) { - return ConfigurationPartMetadata.read(in); - } - } - - private static OffsetDateTime getFileExpiresOn(Path filePath) { - try { - return getMetadata(filePath).getExpirationDate(); - } catch (IOException e) { - log.error("Unable to read expiration date", e); - return OffsetDateTime.MAX; - } - } - - // ------------------------------------------------------------------------ - - private String loadInstanceIdentifier() { - Path file = Paths.get(path.toString(), INSTANCE_IDENTIFIER_FILE); - - log.trace("Loading instance identifier from {}", file); - - try { - return FileUtils.readFileToString(file.toFile(), StandardCharsets.UTF_8).trim(); - } catch (Exception e) { - log.error("Failed to read instance identifier from " + file, e); - - throw new CodedException(X_INTERNAL_ERROR, - "Could not read instance identifier of this security server"); - } - } - - private void loadPrivateParameters(Path instanceDir, Map basePrivateParameters) { - String instanceId = instanceDir.getFileName().toString(); - - Path privateParametersPath = Paths.get(instanceDir.toString(), - ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS); + Path instanceDir = Paths.get(getPath().toString(), instanceId); + Path privateParametersPath = Paths.get(instanceDir.toString(), ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS); if (Files.exists(privateParametersPath)) { try { log.trace("Loading private parameters from {}", privateParametersPath); @@ -284,20 +73,22 @@ private void loadPrivateParameters(Path instanceDir, Map baseSharedParameters) { - String instanceId = instanceDir.getFileName().toString(); + protected SharedParametersV2 loadSharedParameters(String instanceId, Map baseSharedParameters) + throws Exception { - Path sharedParametersPath = Paths.get(instanceDir.toString(), - ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS); + Path instanceDir = Paths.get(getPath().toString(), instanceId); + Path sharedParametersPath = Paths.get(instanceDir.toString(), ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS); if (Files.exists(sharedParametersPath)) { try { log.trace("Loading shared parameters from {}", sharedParametersPath); @@ -314,12 +105,14 @@ private void loadSharedParameters(Path instanceDir, Map When querying the parameters from this class, the parameters XML is checked for modifications and if the XML + * has been modified, the parameters are reloaded from the XML. + */ +@Slf4j +public class ConfigurationDirectoryV3 extends VersionableConfigurationDirectory { + + public ConfigurationDirectoryV3(String directoryPath) throws Exception { + super(directoryPath); + } + + public ConfigurationDirectoryV3(String directoryPath, ConfigurationDirectoryV3 base) throws Exception { + super(directoryPath, base); + } + + @Override + protected PrivateParametersV3 loadPrivateParameters(String instanceId, Map basePrivateParameters) + throws Exception { + + Path instanceDir = Paths.get(getPath().toString(), instanceId); + Path privateParametersPath = Paths.get(instanceDir.toString(), ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS); + if (Files.exists(privateParametersPath)) { + try { + log.trace("Loading private parameters from {}", privateParametersPath); + + PrivateParametersV3 existingParameters = basePrivateParameters.get(instanceId); + PrivateParametersV3 parametersToUse; + OffsetDateTime fileExpiresOn = getFileExpiresOn(privateParametersPath); + + if (existingParameters != null && !existingParameters.hasChanged()) { + log.trace("PrivateParametersV2 from {} have not changed, reusing", privateParametersPath); + parametersToUse = new PrivateParametersV3(existingParameters, fileExpiresOn); + } else { + log.trace("Loading PrivateParametersV2 from {}", privateParametersPath); + parametersToUse = new PrivateParametersV3(privateParametersPath, fileExpiresOn); + } + return parametersToUse; + } catch (Exception e) { + log.error("Unable to load private parameters from {}", instanceDir, e); + throw e; + } + } else { + log.trace("Not loading private parameters from {}, file does not exist", privateParametersPath); + return null; + } + } + + protected SharedParametersV3 loadSharedParameters(String instanceId, Map baseSharedParameters) + throws Exception { + + Path instanceDir = Paths.get(getPath().toString(), instanceId); + Path sharedParametersPath = Paths.get(instanceDir.toString(), + ConfigurationConstants.FILE_NAME_SHARED_PARAMETERS); + if (Files.exists(sharedParametersPath)) { + try { + log.trace("Loading shared parameters from {}", sharedParametersPath); + + SharedParametersV3 existingParameters = baseSharedParameters.get(instanceId); + SharedParametersV3 parametersToUse; + OffsetDateTime fileExpiresOn = getFileExpiresOn(sharedParametersPath); + + if (existingParameters != null && !existingParameters.hasChanged()) { + log.trace("SharedParametersV2 from {} have not changed, reusing", sharedParametersPath); + parametersToUse = new SharedParametersV3(existingParameters, fileExpiresOn); + } else { + log.trace("Loading SharedParametersV2 from {}", sharedParametersPath); + parametersToUse = new SharedParametersV3(sharedParametersPath, fileExpiresOn); + } + return parametersToUse; + } catch (Exception e) { + log.error("Unable to load shared parameters from {}", instanceDir, e); + throw e; + } + } else { + log.trace("Not loading shared parameters from {}, file does not exist", sharedParametersPath); + return null; + } + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParameters.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParameters.java new file mode 100644 index 0000000000..31ad34297f --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParameters.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.identifier.ClientId; + +import lombok.Data; + +import java.math.BigInteger; +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; + +@Data +public class PrivateParameters { + private String instanceIdentifier; + private BigInteger timeStampingIntervalSeconds; + private ManagementService managementService; + private List configurationAnchors; + + @Data + public static class ManagementService { + private String authCertRegServiceAddress; + private byte[] authCertRegServiceCert; + private ClientId managementRequestServiceProviderId; + } + + @Data + public static class ConfigurationAnchor implements ConfigurationSource { + private Instant generatedAt; + private String instanceIdentifier; + private List sources; + + @Override + public List getLocations() { + return sources.stream() + .map(l -> new ConfigurationLocation(this, l.getDownloadURL(), l.getVerificationCerts())) + .collect(Collectors.toList()); + } + + @Override + public boolean hasChanged() { + return false; + } + } + + @Data + public static class Source { + private String downloadURL; + private List verificationCerts; + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersProvider.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersProvider.java new file mode 100644 index 0000000000..7303df3941 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersProvider.java @@ -0,0 +1,36 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import java.time.OffsetDateTime; + +public interface PrivateParametersProvider { + + PrivateParameters getPrivateParameters(); + + OffsetDateTime getExpiresOn(); + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV2.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV2.java index 2dbb72f37a..7006e8a47c 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV2.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV2.java @@ -38,7 +38,7 @@ * Schema validator of private parameters. */ public class PrivateParametersSchemaValidatorV2 extends SchemaValidator { - private static final Schema SCHEMA = createSchema("globalconf/private-parameters.xsd"); + private static final Schema SCHEMA = createSchema("globalconf/v2/private-parameters.xsd"); public static Schema getSchema() { return SCHEMA; diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV3.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV3.java new file mode 100644 index 0000000000..a63a128302 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersSchemaValidatorV3.java @@ -0,0 +1,64 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.ErrorCodes; +import ee.ria.xroad.common.util.SchemaValidator; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; + +import java.io.StringReader; + +/** + * Schema validator of private parameters. + */ +public class PrivateParametersSchemaValidatorV3 extends SchemaValidator { + private static final Schema SCHEMA = createSchema("globalconf/v3/private-parameters.xsd"); + + public static Schema getSchema() { + return SCHEMA; + } + + /** + * Validates the input XML as string against the schema. + * @param xml the input XML as string + * @throws Exception if validation fails + */ + public static void validate(String xml) throws Exception { + validate(new StreamSource(new StringReader(xml))); + } + + /** + * Validates the input source against the schema. + * @param source the input source + * @throws Exception if validation fails + */ + public static void validate(Source source) throws Exception { + validate(SCHEMA, source, ErrorCodes.X_MALFORMED_GLOBALCONF); + } +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2.java index 047e6f6978..4a8766413f 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2.java @@ -26,45 +26,54 @@ package ee.ria.xroad.common.conf.globalconf; import ee.ria.xroad.common.conf.AbstractXmlConf; -import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ManagementServiceType; import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ObjectFactory; import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.PrivateParametersType; +import lombok.Getter; + import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; -import java.math.BigInteger; import java.nio.file.Path; import java.time.OffsetDateTime; -import java.util.List; -import java.util.stream.Collectors; /** * Contains private parameters of a configuration instance. */ -public class PrivateParametersV2 extends AbstractXmlConf { +public class PrivateParametersV2 extends AbstractXmlConf implements PrivateParametersProvider { private static final JAXBContext JAXB_CONTEXT = createJAXBContext(); + private final PrivateParametersV2Converter converter = new PrivateParametersV2Converter(); + + @Getter + private final PrivateParameters privateParameters; + + @Getter private final OffsetDateTime expiresOn; - // variable to prevent using load methods after constrution + + // variable to prevent using load methods after construction private boolean initCompleted; - PrivateParametersV2(byte[] content) { + + PrivateParametersV2(byte[] content) throws Exception { super(content, PrivateParametersSchemaValidatorV2.class); expiresOn = OffsetDateTime.MAX; + privateParameters = converter.convert(confType); initCompleted = true; } - PrivateParametersV2(Path privateParametersPath, OffsetDateTime expiresOn) { + PrivateParametersV2(Path privateParametersPath, OffsetDateTime expiresOn) throws Exception { super(privateParametersPath.toString(), PrivateParametersSchemaValidatorV2.class); this.expiresOn = expiresOn; + privateParameters = converter.convert(confType); initCompleted = true; } PrivateParametersV2(PrivateParametersV2 original, OffsetDateTime newExpiresOn) { super(original); expiresOn = newExpiresOn; + privateParameters = original.getPrivateParameters(); initCompleted = true; } @@ -86,28 +95,6 @@ private void throwIfInitCompleted() { } } - String getInstanceIdentifier() { - return confType.getInstanceIdentifier(); - } - - List getConfigurationSource() { - return confType.getConfigurationAnchor().stream() - .map(ConfigurationAnchorV2::new) - .collect(Collectors.toList()); - } - - BigInteger getTimeStampingIntervalSeconds() { - return confType.getTimeStampingIntervalSeconds(); - } - - ManagementServiceType getManagementService() { - return confType.getManagementService(); - } - - public OffsetDateTime getExpiresOn() { - return expiresOn; - } - @Override protected JAXBContext getJAXBContext() { return JAXB_CONTEXT; @@ -120,4 +107,5 @@ private static JAXBContext createJAXBContext() { throw new RuntimeException(e); } } + } diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2Converter.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2Converter.java new file mode 100644 index 0000000000..1e7a01130a --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV2Converter.java @@ -0,0 +1,76 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ConfigurationAnchorType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ConfigurationSourceType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.PrivateParametersType; + +import static java.util.stream.Collectors.toList; + +public class PrivateParametersV2Converter { + + PrivateParameters convert(PrivateParametersType source) { + var target = new PrivateParameters(); + target.setInstanceIdentifier(source.getInstanceIdentifier()); + target.setTimeStampingIntervalSeconds(source.getTimeStampingIntervalSeconds()); + + if (source.getManagementService() != null) { + var managementService = new PrivateParameters.ManagementService(); + managementService.setAuthCertRegServiceAddress(source.getManagementService().getAuthCertRegServiceAddress()); + managementService.setAuthCertRegServiceCert(source.getManagementService().getAuthCertRegServiceCert()); + managementService.setManagementRequestServiceProviderId(source.getManagementService().getManagementRequestServiceProviderId()); + target.setManagementService(managementService); + } + + if (source.getConfigurationAnchor() != null) { + target.setConfigurationAnchors( + source.getConfigurationAnchor().stream().map(this::toConfigurationAnchor).collect(toList()) + ); + } + + return target; + } + + private PrivateParameters.ConfigurationAnchor toConfigurationAnchor(ConfigurationAnchorType source) { + var configurationAnchor = new PrivateParameters.ConfigurationAnchor(); + configurationAnchor.setInstanceIdentifier(source.getInstanceIdentifier()); + if (source.getGeneratedAt() != null) { + configurationAnchor.setGeneratedAt(source.getGeneratedAt().toGregorianCalendar().toInstant()); + } + configurationAnchor.setSources( + source.getSource().stream().map(this::toConfigurationSource).collect(toList()) + ); + return configurationAnchor; + } + + private PrivateParameters.Source toConfigurationSource(ConfigurationSourceType source) { + var configurationSource = new PrivateParameters.Source(); + configurationSource.setDownloadURL(source.getDownloadURL()); + configurationSource.setVerificationCerts(source.getVerificationCert()); + return configurationSource; + } +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV3.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV3.java new file mode 100644 index 0000000000..fd4a96aaab --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV3.java @@ -0,0 +1,111 @@ +/* + * The MIT License + * + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.conf.AbstractXmlConf; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ObjectFactory; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.PrivateParametersType; + +import lombok.Getter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import java.nio.file.Path; +import java.time.OffsetDateTime; + +/** + * Contains private parameters of a configuration instance. + */ +public class PrivateParametersV3 extends AbstractXmlConf implements PrivateParametersProvider { + private static final JAXBContext JAXB_CONTEXT = createJAXBContext(); + + private final PrivateParametersV3Converter converter = new PrivateParametersV3Converter(); + + @Getter + private final PrivateParameters privateParameters; + + @Getter + private final OffsetDateTime expiresOn; + + + // variable to prevent using load methods after constrution + private boolean initCompleted; + + + PrivateParametersV3(byte[] content) throws Exception { + super(content, PrivateParametersSchemaValidatorV2.class); + expiresOn = OffsetDateTime.MAX; + privateParameters = converter.convert(confType); + initCompleted = true; + } + + PrivateParametersV3(Path privateParametersPath, OffsetDateTime expiresOn) throws Exception { + super(privateParametersPath.toString(), PrivateParametersSchemaValidatorV2.class); + this.expiresOn = expiresOn; + privateParameters = converter.convert(confType); + initCompleted = true; + } + + PrivateParametersV3(PrivateParametersV3 original, OffsetDateTime newExpiresOn) { + super(original); + expiresOn = newExpiresOn; + privateParameters = original.getPrivateParameters(); + initCompleted = true; + } + + @Override + public void load(String fileName) throws Exception { + throwIfInitCompleted(); + super.load(fileName); + } + + @Override + public void load(byte[] data) throws Exception { + throwIfInitCompleted(); + super.load(data); + } + + private void throwIfInitCompleted() { + if (initCompleted) { + throw new IllegalStateException("This object can not be reloaded"); + } + } + + @Override + protected JAXBContext getJAXBContext() { + return JAXB_CONTEXT; + } + + private static JAXBContext createJAXBContext() { + try { + return JAXBContext.newInstance(ObjectFactory.class); + } catch (JAXBException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV3Converter.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV3Converter.java new file mode 100644 index 0000000000..29c0c0e9e2 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/PrivateParametersV3Converter.java @@ -0,0 +1,79 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ConfigurationAnchorType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.ConfigurationSourceType; +import ee.ria.xroad.common.conf.globalconf.privateparameters.v3.PrivateParametersType; + +import static java.util.stream.Collectors.toList; + +public class PrivateParametersV3Converter { + + PrivateParameters convert(PrivateParametersType source) { + var target = new PrivateParameters(); + target.setInstanceIdentifier(source.getInstanceIdentifier()); + target.setTimeStampingIntervalSeconds(source.getTimeStampingIntervalSeconds()); + + if (source.getManagementService() != null) { + var managementService = new PrivateParameters.ManagementService(); + managementService.setAuthCertRegServiceAddress(source.getManagementService().getAuthCertRegServiceAddress()); + managementService.setAuthCertRegServiceCert(source.getManagementService().getAuthCertRegServiceCert()); + managementService.setManagementRequestServiceProviderId(source.getManagementService().getManagementRequestServiceProviderId()); + target.setManagementService(managementService); + } + + if (source.getConfigurationAnchor() != null) { + target.setConfigurationAnchors(source.getConfigurationAnchor().stream() + .map(this::toConfigurationAnchor) + .collect(toList()) + ); + } + + return target; + } + + private PrivateParameters.ConfigurationAnchor toConfigurationAnchor(ConfigurationAnchorType source) { + var configurationAnchor = new PrivateParameters.ConfigurationAnchor(); + configurationAnchor.setInstanceIdentifier(source.getInstanceIdentifier()); + if (source.getGeneratedAt() != null) { + configurationAnchor.setGeneratedAt(source.getGeneratedAt().toGregorianCalendar().toInstant()); + } + configurationAnchor.setSources(source.getSource().stream() + .map(this::toConfigurationSource) + .collect(toList()) + ); + return configurationAnchor; + } + + private PrivateParameters.Source toConfigurationSource(ConfigurationSourceType source) { + var configurationSource = new PrivateParameters.Source(); + configurationSource.setDownloadURL(source.getDownloadURL()); + configurationSource.setVerificationCerts(source.getVerificationCert()); + return configurationSource; + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParameters.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParameters.java new file mode 100644 index 0000000000..da3be92a28 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParameters.java @@ -0,0 +1,267 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.identifier.ClientId; +import ee.ria.xroad.common.identifier.SecurityServerId; + +import lombok.Data; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.cert.X509CertificateHolder; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static ee.ria.xroad.common.util.CryptoUtils.encodeBase64; +import static ee.ria.xroad.common.util.CryptoUtils.readCertificate; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +@Getter +public class SharedParameters { + private final String instanceIdentifier; + private final List sources; + private final List approvedCAs; + private final List approvedTSAs; + private final List members; + private final List securityServers; + private final List globalGroups; + private final GlobalSettings globalSettings; + + // Utility maps of existing data to speed up searches, filled at conf initialization + private final Map subjectsAndCaCerts = new HashMap<>(); + private final Map caCertsAndCertProfiles = new HashMap<>(); + private final Map caCertsAndApprovedCAData = new HashMap<>(); + private final Map> caCertsAndOcspData = new HashMap<>(); + private final List verificationCaCerts = new ArrayList<>(); + private final Map> memberAddresses = new HashMap<>(); + private final Map> memberAuthCerts = new HashMap<>(); + private final Map serverByAuthCert = new HashMap<>(); + private final Map> securityServerClients = new HashMap<>(); + private final Set knownAddresses = new HashSet<>(); + private final Map securityServersById = new HashMap<>(); + + public SharedParameters(String instanceIdentifier, List sources, List approvedCAs, + List approvedTSAs, List members, List securityServers, + List globalGroups, GlobalSettings globalSettings) + throws CertificateEncodingException, IOException { + this.instanceIdentifier = instanceIdentifier; + this.sources = sources; + this.approvedCAs = approvedCAs; + this.approvedTSAs = approvedTSAs; + this.members = members; + this.securityServers = securityServers; + this.globalGroups = globalGroups; + this.globalSettings = globalSettings; + + cacheCaCerts(); + cacheKnownAddresses(); + cacheSecurityServers(); + } + + private void cacheCaCerts() throws CertificateEncodingException, IOException { + List allCaCerts = new ArrayList<>(); + + for (ApprovedCA ca : approvedCAs) { + List topCAs = List.of(ca.getTopCA()); + List intermediateCAs = ca.getIntermediateCas(); + + cacheOcspData(topCAs); + cacheOcspData(intermediateCAs); + + List pkiCaCerts = new ArrayList<>(); + + pkiCaCerts.addAll(getTopOrIntermediateCaCerts(topCAs)); + pkiCaCerts.addAll(getTopOrIntermediateCaCerts(intermediateCAs)); + + Boolean authenticationOnly = ca.getAuthenticationOnly(); + if (authenticationOnly == null || !authenticationOnly) { + verificationCaCerts.addAll(pkiCaCerts); + } + + for (X509Certificate pkiCaCert : pkiCaCerts) { + caCertsAndCertProfiles.put(pkiCaCert, ca.getCertificateProfileInfo()); + caCertsAndApprovedCAData.put(pkiCaCert, ca); + } + allCaCerts.addAll(pkiCaCerts); + + for (X509Certificate cert : allCaCerts) { + X509CertificateHolder certHolder = + new X509CertificateHolder(cert.getEncoded()); + subjectsAndCaCerts.put(certHolder.getSubject(), cert); + } + } + } + + private void cacheOcspData(List typesUnderCA) { + for (CaInfo caInfo : typesUnderCA) { + X509Certificate cert = readCertificate(caInfo.getCert()); + List caOcspTypes = caInfo.getOcsp(); + caCertsAndOcspData.put(cert, caOcspTypes); + } + } + + private static List getTopOrIntermediateCaCerts(List typesUnderCA) { + return typesUnderCA.stream() + .map(c -> readCertificate(c.getCert())) + .collect(Collectors.toList()); + } + + private void cacheKnownAddresses() { + securityServers.stream().map(SecurityServer::getAddress) + .filter(StringUtils::isNotBlank) + .forEach(knownAddresses::add); + } + + private void cacheSecurityServers() { + for (SecurityServer securityServer : securityServers) { + for (byte[] certHash: securityServer.getAuthCertHashes()) { + serverByAuthCert.put(encodeBase64(certHash), securityServer); + } + + // Add owner of the security server + addServerClient(securityServer.getOwner(), securityServer); + + // cache security server information by serverId + SecurityServerId securityServerId = SecurityServerId.Conf.create( + instanceIdentifier, securityServer.getOwner().getMemberClass(), + securityServer.getOwner().getMemberCode(), securityServer.getServerCode() + ); + securityServersById.put(securityServerId, securityServer); + + securityServer.getClients().forEach(client -> addServerClient(client, securityServer)); + } + } + + private void addServerClient(ClientId client, SecurityServer server) { + // Add the mapping from client to security server address. + if (isNotBlank(server.getAddress())) { + addToMap(memberAddresses, client, server.getAddress()); + } + + // Add the mapping from client to authentication certificate. + for (byte[] authCert : server.getAuthCertHashes()) { + addToMap(memberAuthCerts, client, authCert); + } + + SecurityServerId securityServerId = SecurityServerId.Conf.create( + instanceIdentifier, server.getOwner().getMemberClass(), + server.getOwner().getMemberCode(), server.getServerCode() + ); + + addToMap(securityServerClients, securityServerId, client); + } + + private static void addToMap(Map> map, K key, V value) { + Set coll = map.computeIfAbsent(key, k -> new HashSet<>()); + coll.add(value); + } + + @Data + public static class ConfigurationSource { + private String address; + private List verificationCerts; + } + + @Data + public static class Member { + private MemberClass memberClass; + private String memberCode; + private String name; + private List subsystems; + } + + @Data + public static class MemberClass { + private String code; + private String description; + } + + @Data + public static class Subsystem { + private String subsystemCode; + } + + @Data + public static class ApprovedCA { + private String name; + private Boolean authenticationOnly; + private CaInfo topCA; + private List intermediateCas; + private String certificateProfileInfo; + } + + @Data + public static class CaInfo { + private byte[] cert; + private List ocsp; + } + + @Data + public static class OcspInfo { + private String url; + private byte[] cert; + } + + @Data + public static class ApprovedTSA { + private String name; + private String url; + private byte[] cert; + } + + @Data + public static class SecurityServer { + private ClientId owner; + private String serverCode; + private String address; + private List authCertHashes; + private List clients; + } + + @Data + public static class GlobalGroup { + private String groupCode; + private String description; + private List groupMembers; + } + + @Data + public static class GlobalSettings { + private List memberClasses; + private BigInteger ocspFreshnessSeconds; + } +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersProvider.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersProvider.java new file mode 100644 index 0000000000..43602ca2eb --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersProvider.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import java.time.OffsetDateTime; + +public interface SharedParametersProvider { + + SharedParameters getSharedParameters(); + + OffsetDateTime getExpiresOn(); +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV2.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV2.java index 6a8929d93a..2ab43049ab 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV2.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV2.java @@ -38,7 +38,7 @@ * Schema validator of shared parameters. */ public class SharedParametersSchemaValidatorV2 extends SchemaValidator { - private static final Schema SCHEMA = createSchema("globalconf/shared-parameters.xsd"); + private static final Schema SCHEMA = createSchema("globalconf/v2/shared-parameters.xsd"); public static Schema getSchema() { return SCHEMA; diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV3.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV3.java new file mode 100644 index 0000000000..54740e8c92 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersSchemaValidatorV3.java @@ -0,0 +1,63 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.ErrorCodes; +import ee.ria.xroad.common.util.SchemaValidator; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; + +import java.io.StringReader; + +public class SharedParametersSchemaValidatorV3 extends SchemaValidator { + + private static final Schema SCHEMA = createSchema("globalconf/v3/shared-parameters.xsd"); + + public static Schema getSchema() { + return SCHEMA; + } + + /** + * Validates the input XML as string against the schema. + * @param xml the input XML as string + * @throws Exception if validation fails + */ + public static void validate(String xml) throws Exception { + validate(new StreamSource(new StringReader(xml))); + } + + /** + * Validates the input source against the schema. + * @param source the input source + * @throws Exception if validation fails + */ + public static void validate(Source source) throws Exception { + validate(SCHEMA, source, ErrorCodes.X_MALFORMED_GLOBALCONF); + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2.java index 4ea53a0f72..83422ae8d1 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2.java @@ -26,70 +26,31 @@ package ee.ria.xroad.common.conf.globalconf; import ee.ria.xroad.common.conf.AbstractXmlConf; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedCATypeV2; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.CaInfoType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.GlobalGroupType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.GlobalSettingsType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.MemberType; import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ObjectFactory; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.OcspInfoType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SecurityServerType; import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SharedParametersTypeV2; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SubsystemType; -import ee.ria.xroad.common.identifier.ClientId; -import ee.ria.xroad.common.identifier.GlobalGroupId; -import ee.ria.xroad.common.identifier.SecurityServerId; import lombok.AccessLevel; import lombok.Getter; -import org.apache.commons.lang3.StringUtils; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.cert.X509CertificateHolder; import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; -import java.io.IOException; import java.nio.file.Path; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static ee.ria.xroad.common.ErrorCodes.translateException; -import static ee.ria.xroad.common.util.CryptoUtils.encodeBase64; -import static ee.ria.xroad.common.util.CryptoUtils.readCertificate; -import static org.apache.commons.lang3.StringUtils.isNotBlank; /** * Contains shared parameters of a configuration instance. */ @Getter(AccessLevel.PACKAGE) -public class SharedParametersV2 extends AbstractXmlConf { +public class SharedParametersV2 extends AbstractXmlConf implements SharedParametersProvider { private static final JAXBContext JAXB_CONTEXT = createJAXBContext(); - // Cached items, filled at conf reload - private Map subjectsAndCaCerts; - private Map caCertsAndCertProfiles; - private Map caCertsAndApprovedCAData; - private Map> caCertsAndOcspData; - private Map> memberAddresses; - private Map> memberAuthCerts; - private Map serverByAuthCert; - private Map> securityServerClients; - private List verificationCaCerts; - private Set knownAddresses; - private Map securityServersById; + private final SharedParametersV2Converter converter = new SharedParametersV2Converter(); + + @Getter + private final SharedParameters sharedParameters; + @Getter private final OffsetDateTime expiresOn; // variable to prevent using load methods after construction @@ -97,57 +58,24 @@ public class SharedParametersV2 extends AbstractXmlConf // This constructor is used for simple verifications after configuration download. // It does not initialise class fully! - SharedParametersV2(byte[] content) { + SharedParametersV2(byte[] content) throws Exception { super(content, SharedParametersSchemaValidatorV2.class); - initCompleted = true; expiresOn = OffsetDateTime.MAX; + sharedParameters = converter.convert(confType); + initCompleted = true; } - public SharedParametersV2(Path sharedParametersPath, OffsetDateTime expiresOn) { + public SharedParametersV2(Path sharedParametersPath, OffsetDateTime expiresOn) throws Exception { super(sharedParametersPath.toString(), SharedParametersSchemaValidatorV2.class); - this.expiresOn = expiresOn; - - subjectsAndCaCerts = new HashMap<>(); - caCertsAndCertProfiles = new HashMap<>(); - caCertsAndApprovedCAData = new HashMap<>(); - caCertsAndOcspData = new HashMap<>(); - memberAddresses = new HashMap<>(); - memberAuthCerts = new HashMap<>(); - serverByAuthCert = new HashMap<>(); - securityServerClients = new HashMap<>(); - verificationCaCerts = new ArrayList<>(); - knownAddresses = new HashSet<>(); - securityServersById = new HashMap<>(); - - try { - cacheCaCerts(); - cacheKnownAddresses(); - cacheSecurityServers(); - } catch (Exception e) { - throw translateException(e); - } - + sharedParameters = converter.convert(confType); initCompleted = true; } - public SharedParametersV2(SharedParametersV2 original, OffsetDateTime newExpiresOn) { + public SharedParametersV2(SharedParametersV2 original, OffsetDateTime newExpiresOn) throws Exception { super(original); - expiresOn = newExpiresOn; - - subjectsAndCaCerts = original.subjectsAndCaCerts; - caCertsAndCertProfiles = original.caCertsAndCertProfiles; - caCertsAndApprovedCAData = original.caCertsAndApprovedCAData; - caCertsAndOcspData = original.caCertsAndOcspData; - memberAddresses = original.memberAddresses; - memberAuthCerts = original.memberAuthCerts; - serverByAuthCert = original.serverByAuthCert; - securityServerClients = original.securityServerClients; - verificationCaCerts = original.verificationCaCerts; - knownAddresses = original.knownAddresses; - securityServersById = original.securityServersById; - + sharedParameters = converter.convert(confType); initCompleted = true; } @@ -169,220 +97,6 @@ private void throwIfInitCompleted() { } } - ClientId.Conf createMemberId(MemberType member) { - return ClientId.Conf.create(confType.getInstanceIdentifier(), - member.getMemberClass().getCode(), member.getMemberCode()); - } - - ClientId.Conf createSubsystemId(MemberType member, SubsystemType subsystem) { - return ClientId.Conf.create(confType.getInstanceIdentifier(), - member.getMemberClass().getCode(), member.getMemberCode(), - subsystem.getSubsystemCode()); - } - - GlobalGroupId.Conf createGlobalGroupId(GlobalGroupType globalGroup) { - return GlobalGroupId.Conf.create(confType.getInstanceIdentifier(), - globalGroup.getGroupCode()); - } - - String getInstanceIdentifier() { - return confType.getInstanceIdentifier(); - } - - List getMembers() { - return confType.getMember(); - } - - List getApprovedCAs() { - return confType.getApprovedCA(); - } - - List getApprovedTSAs() { - return confType.getApprovedTSA(); - } - - List getSecurityServers() { - return confType.getSecurityServer(); - } - - List getGlobalGroups() { - return confType.getGlobalGroup(); - } - - GlobalSettingsType getGlobalSettings() { - return confType.getGlobalSettings(); - } - - GlobalGroupType findGlobalGroup(GlobalGroupId groupId) { - if (!groupId.getXRoadInstance().equals( - confType.getInstanceIdentifier())) { - return null; - } - - return confType.getGlobalGroup().stream() - .filter(g -> g.getGroupCode().equals(groupId.getGroupCode())) - .findFirst().orElse(null); - } - - X509Certificate getCaCertForSubject(X509Certificate subject) - throws Exception { - X509CertificateHolder certHolder = - new X509CertificateHolder(subject.getEncoded()); - if (certHolder.getSubject().equals(certHolder.getIssuer())) { - return null; - } - - return subjectsAndCaCerts.get(certHolder.getIssuer()); - } - - static MemberType getOwner(SecurityServerType serverType) { - if (!(serverType.getOwner() instanceof MemberType)) { - throw new RuntimeException("Server owner must be member"); - } - - return (MemberType) serverType.getOwner(); - } - - private void cacheCaCerts() throws CertificateException, IOException { - List allCaCerts = new ArrayList<>(); - - for (ApprovedCATypeV2 caType : confType.getApprovedCA()) { - List topCAs = Arrays.asList(caType.getTopCA()); - List intermediateCAs = caType.getIntermediateCA(); - - cacheOcspData(topCAs); - cacheOcspData(intermediateCAs); - - List pkiCaCerts = new ArrayList<>(); - - pkiCaCerts.addAll(getTopOrIntermediateCaCerts(topCAs)); - pkiCaCerts.addAll(getTopOrIntermediateCaCerts(intermediateCAs)); - - Boolean authenticationOnly = caType.isAuthenticationOnly(); - if (authenticationOnly == null || !authenticationOnly) { - verificationCaCerts.addAll(pkiCaCerts); - } - - for (X509Certificate pkiCaCert : pkiCaCerts) { - caCertsAndCertProfiles.put(pkiCaCert, - caType.getCertificateProfileInfo()); - caCertsAndApprovedCAData.put(pkiCaCert, - caType); - } - allCaCerts.addAll(pkiCaCerts); - } - - for (X509Certificate cert : allCaCerts) { - X509CertificateHolder certHolder = - new X509CertificateHolder(cert.getEncoded()); - subjectsAndCaCerts.put(certHolder.getSubject(), cert); - } - } - - private void cacheKnownAddresses() { - confType.getSecurityServer().stream().map(s -> s.getAddress()) - .filter(StringUtils::isNotBlank) - .forEach(knownAddresses::add); - } - - private void cacheSecurityServers() { - // Map of XML ID fields mapped to client IDs - Map clientIds = getClientIds(); - - for (SecurityServerType securityServer : confType.getSecurityServer()) { - // Cache the server. - for (byte[] certHash: securityServer.getAuthCertHash()) { - serverByAuthCert.put(encodeBase64(certHash), - securityServer); - } - - // Add owner of the security server. - MemberType owner = (MemberType) securityServer.getOwner(); - addServerClient(createMemberId(owner), securityServer); - - // cache security server information by serverId - SecurityServerId securityServerId = SecurityServerId.Conf.create( - confType.getInstanceIdentifier(), - owner.getMemberClass().getCode(), - owner.getMemberCode(), securityServer.getServerCode()); - securityServersById.put(securityServerId, securityServer); - - // Add clients of the security server. - for (JAXBElement client : securityServer.getClient()) { - Object val = client.getValue(); - - if (val instanceof MemberType) { - addServerClient(createMemberId((MemberType) val), - securityServer); - } else if (val instanceof SubsystemType) { - addServerClient( - clientIds.get(((SubsystemType) val).getId()), - securityServer); - } - } - } - } - - private void addServerClient(ClientId client, SecurityServerType server) { - // Add the mapping from client to security server address. - if (isNotBlank(server.getAddress())) { - addToMap(memberAddresses, client, server.getAddress()); - } - - // Add the mapping from client to authentication certificate. - for (byte[] authCert : server.getAuthCertHash()) { - addToMap(memberAuthCerts, client, authCert); - } - - MemberType owner = getOwner(server); - SecurityServerId securityServerId = SecurityServerId.Conf.create( - confType.getInstanceIdentifier(), - owner.getMemberClass().getCode(), - owner.getMemberCode(), server.getServerCode()); - - addToMap(securityServerClients, securityServerId, client); - } - - private Map getClientIds() { - Map ret = new HashMap<>(); - - for (MemberType member : confType.getMember()) { - ret.put(member.getId(), createMemberId(member)); - - for (SubsystemType subsystem : member.getSubsystem()) { - ret.put(subsystem.getId(), - createSubsystemId(member, subsystem)); - } - } - - return ret; - } - - private void cacheOcspData(List typesUnderCA) - throws CertificateException, IOException { - for (CaInfoType caType : typesUnderCA) { - X509Certificate cert = readCertificate(caType.getCert()); - List caOcspTypes = caType.getOcsp(); - caCertsAndOcspData.put(cert, caOcspTypes); - } - } - - private static void addToMap(Map> map, K key, V value) { - Set coll = map.get(key); - if (coll == null) { - coll = new HashSet<>(); - map.put(key, coll); - } - coll.add(value); - } - - private static List getTopOrIntermediateCaCerts( - List typesUnderCA) { - return typesUnderCA.stream() - .map(c -> readCertificate(c.getCert())) - .collect(Collectors.toList()); - } - @Override protected JAXBContext getJAXBContext() { return JAXB_CONTEXT; @@ -395,4 +109,5 @@ private static JAXBContext createJAXBContext() { throw new RuntimeException(e); } } + } diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2Converter.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2Converter.java new file mode 100644 index 0000000000..3b455dfdbd --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV2Converter.java @@ -0,0 +1,237 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedCATypeV2; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.CaInfoType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.GlobalGroupType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.GlobalSettingsType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.MemberClassType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.MemberType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.OcspInfoType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SecurityServerType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SharedParametersTypeV2; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SubsystemType; +import ee.ria.xroad.common.identifier.ClientId; + +import javax.xml.bind.JAXBElement; + +import java.io.IOException; +import java.security.cert.CertificateEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SharedParametersV2Converter { + + SharedParameters convert(SharedParametersTypeV2 source) throws CertificateEncodingException, IOException { + String instanceIdentifier = source.getInstanceIdentifier(); + List approvedCAs = getApprovedCAs(source.getApprovedCA()); + List approvedTSAs = getApprovedTSAs(source.getApprovedTSA()); + List members = getMembers(source.getMember()); + List securityServers = getSecurityServers(source); + List globalGroups = getGlobalGroups(source.getGlobalGroup()); + SharedParameters.GlobalSettings globalSettings = getGlobalSettings(source.getGlobalSettings()); + return new SharedParameters(instanceIdentifier, List.of(), approvedCAs, approvedTSAs, + members, securityServers, globalGroups, globalSettings); + } + + private List getApprovedCAs(List approvedCATypes) { + List approvedCAs = new ArrayList<>(); + if (approvedCATypes != null) { + approvedCAs.addAll(approvedCATypes.stream().map(this::toApprovedCa).toList()); + } + return approvedCAs; + } + + private List getApprovedTSAs(List approvedTSATypes) { + List approvedTSAs = new ArrayList<>(); + if (approvedTSATypes != null) { + approvedTSAs.addAll(approvedTSATypes.stream().map(this::toApprovedTsa).toList()); + } + return approvedTSAs; + } + + private List getMembers(List memberTypes) { + List members = new ArrayList<>(); + if (memberTypes != null) { + members.addAll(memberTypes.stream().map(this::toMember).toList()); + } + return members; + } + + private List getSecurityServers(SharedParametersTypeV2 source) { + List securityServers = new ArrayList<>(); + if (source.getSecurityServer() != null) { + Map clientIds = getClientIds(source); + securityServers.addAll( + source.getSecurityServer().stream() + .map(s -> toSecurityServer(clientIds, s, source.getInstanceIdentifier())) + .toList() + ); + } + return securityServers; + } + + private Map getClientIds(SharedParametersTypeV2 source) { + Map ret = new HashMap<>(); + source.getMember().forEach(member -> { + ret.put(member.getId(), toClientId(source.getInstanceIdentifier(), member)); + member.getSubsystem().forEach(subsystem -> { + ret.put(subsystem.getId(), toClientId(source.getInstanceIdentifier(), member, subsystem)); + }); + }); + return ret; + } + + private List getGlobalGroups(List globalGroupTypes) { + List globalGroups = new ArrayList<>(); + if (globalGroupTypes != null) { + globalGroups.addAll(globalGroupTypes.stream().map(this::toGlobalGroup).toList()); + } + return globalGroups; + } + + private SharedParameters.GlobalSettings getGlobalSettings(GlobalSettingsType globalSettingsType) { + return globalSettingsType != null ? toGlobalSettings(globalSettingsType) : null; + } + + private SharedParameters.ApprovedCA toApprovedCa(ApprovedCATypeV2 source) { + var target = new SharedParameters.ApprovedCA(); + target.setName(source.getName()); + target.setAuthenticationOnly(source.isAuthenticationOnly()); + if (source.getTopCA() != null) { + target.setTopCA(toCaInfo(source.getTopCA())); + } + if (source.getIntermediateCA() != null) { + target.setIntermediateCas(source.getIntermediateCA().stream().map(this::toCaInfo).toList()); + } + target.setCertificateProfileInfo(source.getCertificateProfileInfo()); + return target; + } + + private SharedParameters.CaInfo toCaInfo(CaInfoType source) { + var caInfo = new SharedParameters.CaInfo(); + caInfo.setCert(source.getCert()); + if (source.getOcsp() != null) { + caInfo.setOcsp(source.getOcsp().stream().map(this::toOcspInfo).toList()); + } + return caInfo; + } + + private SharedParameters.OcspInfo toOcspInfo(OcspInfoType source) { + var ocspInfo = new SharedParameters.OcspInfo(); + ocspInfo.setUrl(source.getUrl()); + ocspInfo.setCert(source.getCert()); + return ocspInfo; + } + + private SharedParameters.ApprovedTSA toApprovedTsa(ApprovedTSAType source) { + var target = new SharedParameters.ApprovedTSA(); + target.setName(source.getName()); + target.setUrl(source.getUrl()); + target.setCert(source.getCert()); + return target; + } + + private SharedParameters.Member toMember(MemberType source) { + var target = new SharedParameters.Member(); + target.setMemberClass(toMemberClass(source.getMemberClass())); + target.setMemberCode(source.getMemberCode()); + target.setName(source.getName()); + if (source.getSubsystem() != null) { + target.setSubsystems(source.getSubsystem().stream().map(this::toSubsystem).toList()); + } + return target; + } + + private SharedParameters.MemberClass toMemberClass(MemberClassType source) { + var target = new SharedParameters.MemberClass(); + target.setCode(source.getCode()); + target.setDescription(source.getDescription()); + return target; + } + + private SharedParameters.Subsystem toSubsystem(SubsystemType source) { + var target = new SharedParameters.Subsystem(); + target.setSubsystemCode(source.getSubsystemCode()); + return target; + } + + private SharedParameters.SecurityServer toSecurityServer( + Map clientIds, SecurityServerType source, String instanceIdentifier) { + var target = new SharedParameters.SecurityServer(); + target.setOwner(toClientId(instanceIdentifier, (MemberType) source.getOwner())); + target.setServerCode(source.getServerCode()); + target.setAddress(source.getAddress()); + target.setAuthCertHashes(source.getAuthCertHash()); + if (source.getClient() != null) { + List clients = new ArrayList<>(); + for (JAXBElement client : source.getClient()) { + if (client.getValue() instanceof MemberType) { + clients.add(toClientId(instanceIdentifier, (MemberType) client.getValue())); + } else if (client.getValue() instanceof SubsystemType) { + clients.add(clientIds.get(((SubsystemType) client.getValue()).getId())); + } + } + target.setClients(clients); + } + return target; + } + + private ClientId toClientId(String instanceIdentifier, MemberType source) { + return ClientId.Conf.create(instanceIdentifier, source.getMemberClass().getCode(), source.getMemberCode()); + } + + private ClientId toClientId(String instanceIdentifier, MemberType member, SubsystemType subsystem) { + return ClientId.Conf.create( + instanceIdentifier, member.getMemberClass().getCode(), member.getMemberCode(), subsystem.getSubsystemCode() + ); + } + + private SharedParameters.GlobalGroup toGlobalGroup(GlobalGroupType source) { + var target = new SharedParameters.GlobalGroup(); + target.setGroupCode(source.getGroupCode()); + target.setDescription(source.getDescription()); + + if (source.getGroupMember() != null) { + target.setGroupMembers(source.getGroupMember().stream().map(ClientId::getMemberId).toList()); + } + return target; + } + + private SharedParameters.GlobalSettings toGlobalSettings(GlobalSettingsType source) { + var target = new SharedParameters.GlobalSettings(); + target.setOcspFreshnessSeconds(source.getOcspFreshnessSeconds()); + if (source.getMemberClass() != null) { + target.setMemberClasses(source.getMemberClass().stream().map(this::toMemberClass).toList()); + } + return target; + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV3.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV3.java new file mode 100644 index 0000000000..beb38f2255 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV3.java @@ -0,0 +1,110 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.conf.AbstractXmlConf; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ObjectFactory; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SharedParametersTypeV3; + +import lombok.AccessLevel; +import lombok.Getter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import java.nio.file.Path; +import java.time.OffsetDateTime; + +@Getter(AccessLevel.PACKAGE) +public class SharedParametersV3 extends AbstractXmlConf implements SharedParametersProvider { + private static final JAXBContext JAXB_CONTEXT = createJAXBContext(); + + private final SharedParametersV3Converter converter = new SharedParametersV3Converter(); + + @Getter + private final SharedParameters sharedParameters; + + @Getter + private final OffsetDateTime expiresOn; + + // variable to prevent using load methods after construction + private final boolean initCompleted; + + // This constructor is used for simple verifications after configuration download. + // It does not initialise class fully! + SharedParametersV3(byte[] content) throws Exception { + super(content, SharedParametersSchemaValidatorV3.class); + expiresOn = OffsetDateTime.MAX; + sharedParameters = converter.convert(confType); + initCompleted = true; + } + + public SharedParametersV3(Path sharedParametersPath, OffsetDateTime expiresOn) throws Exception { + super(sharedParametersPath.toString(), SharedParametersSchemaValidatorV3.class); + this.expiresOn = expiresOn; + sharedParameters = converter.convert(confType); + initCompleted = true; + } + + public SharedParametersV3(SharedParametersV3 original, OffsetDateTime newExpiresOn) throws Exception { + super(original); + expiresOn = newExpiresOn; + sharedParameters = converter.convert(confType); + initCompleted = true; + } + + @Override + public void load(String fileName) throws Exception { + throwIfInitCompleted(); + super.load(fileName); + } + + @Override + public void load(byte[] data) throws Exception { + throwIfInitCompleted(); + super.load(data); + } + + private void throwIfInitCompleted() { + if (initCompleted) { + throw new IllegalStateException("This object can not be reloaded"); + } + } + + @Override + protected JAXBContext getJAXBContext() { + return JAXB_CONTEXT; + } + + private static JAXBContext createJAXBContext() { + try { + return JAXBContext.newInstance(ObjectFactory.class); + } catch (JAXBException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV3Converter.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV3Converter.java new file mode 100644 index 0000000000..966c93bee9 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/SharedParametersV3Converter.java @@ -0,0 +1,255 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ApprovedCATypeV2; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.CaInfoType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.ConfigurationSourceType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.GlobalGroupType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.GlobalSettingsType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.MemberClassType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.MemberType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.OcspInfoType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SecurityServerType; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SharedParametersTypeV3; +import ee.ria.xroad.common.conf.globalconf.sharedparameters.v3.SubsystemType; +import ee.ria.xroad.common.identifier.ClientId; + +import javax.xml.bind.JAXBElement; + +import java.io.IOException; +import java.security.cert.CertificateEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SharedParametersV3Converter { + + SharedParameters convert(SharedParametersTypeV3 source) throws CertificateEncodingException, IOException { + String instanceIdentifier = source.getInstanceIdentifier(); + List configurationSources = getConfigurationSources(source.getSource()); + List approvedCAs = getApprovedCAs(source.getApprovedCA()); + List approvedTSAs = getApprovedTSAs(source.getApprovedTSA()); + List members = getMembers(source.getMember()); + List securityServers = getSecurityServers(source); + List globalGroups = getGlobalGroups(source.getGlobalGroup()); + SharedParameters.GlobalSettings globalSettings = getGlobalSettings(source.getGlobalSettings()); + return new SharedParameters(instanceIdentifier, configurationSources, approvedCAs, approvedTSAs, + members, securityServers, globalGroups, globalSettings); + } + + private List getConfigurationSources(List sources) { + List configurationSources = new ArrayList<>(); + if (sources != null) { + configurationSources.addAll(sources.stream().map(this::toConfigurationSource).toList()); + } + return configurationSources; + } + + private List getApprovedCAs(List approvedCATypes) { + List approvedCAs = new ArrayList<>(); + if (approvedCATypes != null) { + approvedCAs.addAll(approvedCATypes.stream().map(this::toApprovedCa).toList()); + } + return approvedCAs; + } + + + private List getApprovedTSAs(List approvedTSATypes) { + List approvedTSAs = new ArrayList<>(); + if (approvedTSATypes != null) { + approvedTSAs.addAll(approvedTSATypes.stream().map(this::toApprovedTsa).toList()); + } + return approvedTSAs; + } + + private List getMembers(List memberTypes) { + List members = new ArrayList<>(); + if (memberTypes != null) { + members.addAll(memberTypes.stream().map(this::toMember).toList()); + } + return members; + } + + private List getSecurityServers(SharedParametersTypeV3 source) { + List securityServers = new ArrayList<>(); + if (source.getSecurityServer() != null) { + Map clientIds = getClientIds(source); + securityServers.addAll( + source.getSecurityServer().stream() + .map(s -> toSecurityServer(clientIds, s, source.getInstanceIdentifier())) + .toList() + ); + } + return securityServers; + } + + private Map getClientIds(SharedParametersTypeV3 source) { + Map ret = new HashMap<>(); + source.getMember().forEach(member -> { + ret.put(member.getId(), toClientId(source.getInstanceIdentifier(), member)); + member.getSubsystem().forEach(subsystem -> { + ret.put(subsystem.getId(), toClientId(source.getInstanceIdentifier(), member, subsystem)); + }); + }); + return ret; + } + + private List getGlobalGroups(List globalGroupTypes) { + List globalGroups = new ArrayList<>(); + if (globalGroupTypes != null) { + globalGroups.addAll(globalGroupTypes.stream().map(this::toGlobalGroup).toList()); + } + return globalGroups; + } + + private SharedParameters.GlobalSettings getGlobalSettings(GlobalSettingsType globalSettingsType) { + return globalSettingsType != null ? toGlobalSettings(globalSettingsType) : null; + } + + private SharedParameters.ConfigurationSource toConfigurationSource(ConfigurationSourceType source) { + var target = new SharedParameters.ConfigurationSource(); + target.setAddress(source.getAddress()); + target.setVerificationCerts(source.getVerificationCert()); + return target; + } + + private SharedParameters.ApprovedCA toApprovedCa(ApprovedCATypeV2 source) { + var target = new SharedParameters.ApprovedCA(); + target.setName(source.getName()); + target.setAuthenticationOnly(source.isAuthenticationOnly()); + if (source.getTopCA() != null) { + target.setTopCA(toCaInfo(source.getTopCA())); + } + if (source.getIntermediateCA() != null) { + target.setIntermediateCas(source.getIntermediateCA().stream().map(this::toCaInfo).toList()); + } + target.setCertificateProfileInfo(source.getCertificateProfileInfo()); + return target; + } + + private SharedParameters.CaInfo toCaInfo(CaInfoType source) { + var caInfo = new SharedParameters.CaInfo(); + caInfo.setCert(source.getCert()); + if (source.getOcsp() != null) { + caInfo.setOcsp(source.getOcsp().stream().map(this::toOcspInfo).toList()); + } + return caInfo; + } + + private SharedParameters.OcspInfo toOcspInfo(OcspInfoType source) { + var ocspInfo = new SharedParameters.OcspInfo(); + ocspInfo.setUrl(source.getUrl()); + ocspInfo.setCert(source.getCert()); + return ocspInfo; + } + + private SharedParameters.ApprovedTSA toApprovedTsa(ApprovedTSAType source) { + var target = new SharedParameters.ApprovedTSA(); + target.setName(source.getName()); + target.setUrl(source.getUrl()); + target.setCert(source.getCert()); + return target; + } + + private SharedParameters.Member toMember(MemberType source) { + var target = new SharedParameters.Member(); + target.setMemberClass(toMemberClass(source.getMemberClass())); + target.setMemberCode(source.getMemberCode()); + target.setName(source.getName()); + if (source.getSubsystem() != null) { + target.setSubsystems(source.getSubsystem().stream().map(this::toSubsystem).toList()); + } + return target; + } + + private SharedParameters.MemberClass toMemberClass(MemberClassType source) { + var target = new SharedParameters.MemberClass(); + target.setCode(source.getCode()); + target.setDescription(source.getDescription()); + return target; + } + + private SharedParameters.Subsystem toSubsystem(SubsystemType source) { + var target = new SharedParameters.Subsystem(); + target.setSubsystemCode(source.getSubsystemCode()); + return target; + } + + private SharedParameters.SecurityServer toSecurityServer( + Map clientIds, SecurityServerType source, String instanceIdentifier) { + var target = new SharedParameters.SecurityServer(); + target.setOwner(toClientId(instanceIdentifier, (MemberType) source.getOwner())); + target.setServerCode(source.getServerCode()); + target.setAddress(source.getAddress()); + target.setAuthCertHashes(source.getAuthCertHash()); + if (source.getClient() != null) { + List clients = new ArrayList<>(); + for (JAXBElement client : source.getClient()) { + if (client.getValue() instanceof MemberType) { + clients.add(toClientId(instanceIdentifier, (MemberType) client.getValue())); + } else if (client.getValue() instanceof SubsystemType) { + clients.add(clientIds.get(((SubsystemType) client.getValue()).getId())); + } + } + target.setClients(clients); + } + return target; + } + + private ClientId toClientId(String instanceIdentifier, MemberType source) { + return ClientId.Conf.create(instanceIdentifier, source.getMemberClass().getCode(), source.getMemberCode()); + } + + private ClientId toClientId(String instanceIdentifier, MemberType member, SubsystemType subsystem) { + return ClientId.Conf.create( + instanceIdentifier, member.getMemberClass().getCode(), member.getMemberCode(), subsystem.getSubsystemCode() + ); + } + + private SharedParameters.GlobalGroup toGlobalGroup(GlobalGroupType source) { + var target = new SharedParameters.GlobalGroup(); + target.setGroupCode(source.getGroupCode()); + target.setDescription(source.getDescription()); + + if (source.getGroupMember() != null) { + target.setGroupMembers(source.getGroupMember().stream().map(ClientId::getMemberId).toList()); + } + return target; + } + + private SharedParameters.GlobalSettings toGlobalSettings(GlobalSettingsType source) { + var target = new SharedParameters.GlobalSettings(); + target.setOcspFreshnessSeconds(source.getOcspFreshnessSeconds()); + if (source.getMemberClass() != null) { + target.setMemberClasses(source.getMemberClass().stream().map(this::toMemberClass).toList()); + } + return target; + } + +} diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/VersionableConfigurationDirectory.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/VersionableConfigurationDirectory.java new file mode 100644 index 0000000000..2d1d9ab9d6 --- /dev/null +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/conf/globalconf/VersionableConfigurationDirectory.java @@ -0,0 +1,309 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.CodedException; +import ee.ria.xroad.common.util.TimeUtils; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; + +import javax.annotation.concurrent.Immutable; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import static ee.ria.xroad.common.ErrorCodes.X_INTERNAL_ERROR; +import static ee.ria.xroad.common.conf.globalconf.ConfigurationUtils.escapeInstanceIdentifier; + +/** + * Class for reading global configuration directory. The directory must have subdirectory per instance identifier. + * Each subdirectory must contain private and/or shared parameters. + *
When querying the parameters from this class, the parameters XML is checked for modifications and if the XML has + * been modified, the parameters are reloaded from the XML. + * + * @param PrivateParametersProvider + * @param SharedParametersProvider + */ +@Slf4j +@Immutable +public abstract class VersionableConfigurationDirectory + implements ConfigurationDirectory { + + @Getter + private final Path path; + + @Getter + private final String instanceIdentifier; + + protected final Map privateParameters; + protected final Map sharedParameters; + + // ------------------------------------------------------------------------ + + /** + * Constructs new directory from the given path. + * @param directoryPath the path to the directory. + * @throws Exception if loading configuration fails + */ + VersionableConfigurationDirectory(String directoryPath) throws Exception { + this.path = Paths.get(directoryPath); + + instanceIdentifier = loadInstanceIdentifier(); + + // empty maps as placeholders + privateParameters = Map.copyOf(loadPrivateParameters(new HashMap<>())); + sharedParameters = Map.copyOf(loadSharedParameters(new HashMap<>())); + } + + /** + * Constructs new directory from the given path using parts from provided base that have not changed. + * @param directoryPath the path to the directory. + * @param base existing configuration directory to look for reusable parameter objects + * @throws Exception if loading configuration fails + */ + VersionableConfigurationDirectory(String directoryPath, VersionableConfigurationDirectory base) throws Exception { + this.path = Paths.get(directoryPath); + + instanceIdentifier = loadInstanceIdentifier(); + + privateParameters = Map.copyOf(loadPrivateParameters(base.privateParameters)); + sharedParameters = Map.copyOf(loadSharedParameters(base.sharedParameters)); + } + + /** + * Reloads private parameters. Only files that are new or have changed, are actually loaded. + * @throws Exception if an error occurs during reload + */ + private Map loadPrivateParameters(Map basePrivateParams) throws Exception { + log.trace("Reloading private parameters from {}", path); + + Map privateParams = new HashMap<>(); + try (DirectoryStream stream = Files.newDirectoryStream(path, Files::isDirectory)) { + for (Path instanceDir : stream) { + log.trace("Loading private parameters from {}", instanceDir); + String instanceId = instanceDir.getFileName().toString(); + T params = loadPrivateParameters(instanceId, basePrivateParams); + if (params != null) { + privateParams.put(instanceId, params); + } + } + } + return privateParams; + } + + /** + * Reloads shared parameters. Only files that are new or have changed, are actually loaded. + * @throws Exception if an error occurs during reload + */ + private Map loadSharedParameters(Map baseSharedParams) throws Exception { + log.trace("Reloading shared parameters from {}", path); + + Map sharedParams = new HashMap<>(); + try (DirectoryStream stream = Files.newDirectoryStream(path, Files::isDirectory)) { + for (Path instanceDir : stream) { + log.trace("Loading shared parameters from {}", instanceDir); + String instanceId = instanceDir.getFileName().toString(); + S params = loadSharedParameters(instanceId, baseSharedParams); + if (params != null) { + sharedParams.put(instanceId, params); + } + } + } + return sharedParams; + } + + /** + * Returns private parameters for a given instance identifier. + * @param instanceId the instance identifier + * @return private parameters or null, if no private parameters exist for given instance identifier + * @throws Exception if an error occurs while reading parameters + */ + public PrivateParameters getPrivate(String instanceId) throws Exception { + String safeInstanceId = escapeInstanceIdentifier(instanceId); + + log.trace("getPrivate(instance = {}, directory = {})", instanceId, safeInstanceId); + + T provider = privateParameters.get(safeInstanceId); + return provider != null ? provider.getPrivateParameters() : null; + } + + public OffsetDateTime getPrivateExpiresOn(String instanceId) { + String safeInstanceId = escapeInstanceIdentifier(instanceId); + return privateParameters.get(safeInstanceId).getExpiresOn(); + } + + /** + * Returns shared parameters for a given instance identifier. + * @param instanceId the instance identifier + * @return shared parameters or null, if no shared parameters exist for given instance identifier + */ + public SharedParameters getShared(String instanceId) { + String safeInstanceId = escapeInstanceIdentifier(instanceId); + + log.trace("getShared(instance = {}, directory = {})", instanceId, safeInstanceId); + + S parameters = sharedParameters.get(safeInstanceId); + // ignore federated parameters that are expired + if (parameters != null && parameters.getSharedParameters() != null + && (parameters.getSharedParameters().getInstanceIdentifier().equals(instanceIdentifier) + || parameters.getExpiresOn().isAfter(TimeUtils.offsetDateTimeNow()))) { + return parameters.getSharedParameters(); + } + return null; + } + + /** + * @return all known shared parameters + */ + public List getShared() { + OffsetDateTime now = TimeUtils.offsetDateTimeNow(); + return sharedParameters.values() + .stream() + .filter(p -> p.getSharedParameters() != null + && p.getSharedParameters().getInstanceIdentifier().equals(instanceIdentifier) || p.getExpiresOn().isAfter(now) + ) + .map(SharedParametersProvider::getSharedParameters) + .toList(); + } + + public OffsetDateTime getSharedExpiresOn(String instanceId) { + String safeInstanceId = escapeInstanceIdentifier(instanceId); + return sharedParameters.get(safeInstanceId).getExpiresOn(); + } + + /** + * Applies the given function to all files belonging to the configuration directory. + * @param consumer the function instance that should be applied to + * @throws IOException if an error occurs + */ + private synchronized void eachFile(final Consumer consumer) throws IOException { + getConfigurationFiles().forEach(consumer); + } + + protected List getConfigurationFiles() throws IOException { + return excludeMetadataAndDirs(Files.walk(path)); + } + + private List excludeMetadataAndDirs(Stream stream) { + return stream.filter(Files::isRegularFile) + .filter(p -> !p.toString().endsWith(ConfigurationDirectory.FILES)) + .filter(p -> !p.toString().endsWith(ConfigurationDirectory.INSTANCE_IDENTIFIER_FILE)) + .filter(p -> !p.toString().endsWith(ConfigurationDirectory.METADATA_SUFFIX)) + .toList(); + } + + /** + * Applies the given function to all files belonging to the configuration directory. + * @param consumer the function instance that should be applied to all files belonging to the + * configuration directory. + * @throws Exception if an error occurs + */ + public synchronized void eachFile(FileConsumer consumer) throws IOException { + eachFile(filepath -> { + try (InputStream is = new FileInputStream(filepath.toFile())) { + log.trace("Processing '{}'", filepath); + + ConfigurationPartMetadata metadata; + + try { + metadata = getMetadata(filepath); + } catch (IOException e) { + log.error("Could not open configuration file '{}' metadata: {}", filepath, e); + throw e; + } + + consumer.consume(metadata, is); + } catch (RuntimeException e) { + log.error("Error processing configuration file '{}': {}", filepath, e); + + throw e; + } catch (Exception e) { + log.error("Error processing configuration file '{}': {}", filepath, e); + + throw new RuntimeException(e); + } + }); + } + + /** + * Gets the metadata for the given file. + * @param fileName the file name + * @return the metadata for the given file or null if metadata file does not exist. + * @throws Exception if the metadata cannot be loaded + */ + public static ConfigurationPartMetadata getMetadata(Path fileName) throws IOException { + File file = new File(fileName.toString() + ConfigurationConstants.FILE_NAME_SUFFIX_METADATA); + try (InputStream in = new FileInputStream(file)) { + return ConfigurationPartMetadata.read(in); + } + } + + protected static OffsetDateTime getFileExpiresOn(Path filePath) { + try { + return getMetadata(filePath).getExpirationDate(); + } catch (IOException e) { + log.error("Unable to read expiration date", e); + return OffsetDateTime.MAX; + } + } + + // ------------------------------------------------------------------------ + + private String loadInstanceIdentifier() { + Path file = Paths.get(path.toString(), INSTANCE_IDENTIFIER_FILE); + + log.trace("Loading instance identifier from {}", file); + + try { + return FileUtils.readFileToString(file.toFile(), StandardCharsets.UTF_8).trim(); + } catch (Exception e) { + log.error("Failed to read instance identifier from " + file, e); + + throw new CodedException(X_INTERNAL_ERROR, + "Could not read instance identifier of this security server"); + } + } + + protected abstract T loadPrivateParameters(String instanceId, Map basePrivateParameters) throws Exception; + + protected abstract S loadSharedParameters(String instanceId, Map basePrivateParameters) throws Exception; + +} diff --git a/src/common/common-util/src/main/resources/globalconf/common/private-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/common/private-parameters.xsd new file mode 100644 index 0000000000..560f38d67d --- /dev/null +++ b/src/common/common-util/src/main/resources/globalconf/common/private-parameters.xsd @@ -0,0 +1,83 @@ + + + + + + + + + + Address of the authentication certificate registration service that can be called by the + security servers. + + + + + + + Server certificate that is used to authenticate TLS connection to the authentication + certificate registration service. + + + + + + + Identifier of the X-Road member or subsystem providing the management request services. + + + + + + + + + + + Date when this anchor was produced + + + + + + + Code of the X-Road instance that provides configuration to this configuration source. + + + + + + + Describes one configuration source. + + + + + + + + + + + + HTTP URL that can be used to download signed configuration. + + + + + + + Public key that can be used to verify the signed configuration, presented as X.509 certificate. + + + + + + diff --git a/src/common/common-util/src/main/resources/globalconf/common/shared-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/common/shared-parameters.xsd new file mode 100644 index 0000000000..c8b917a0c6 --- /dev/null +++ b/src/common/common-util/src/main/resources/globalconf/common/shared-parameters.xsd @@ -0,0 +1,296 @@ + + + + + + + + + + Member class of the member. + + + + + + + Code that uniquely identifies the member within the given member class. + + + + + + + Full, official name of the member, used in user interfaces. + + + + + + + Represents information about a part of the member's information system that is acting as an + independent service consumer or provider in the X-Road system. + + + + + + + + + + + + + Identifier of the member who is responsible for the security server. + + + + + + + Code that uniquely identifies this server within servers owned by the same member. + + + + + + + Externally visible address of the security server. + + + + + + + Hash of the authentication certificate used by the security server. + + + + + + + Identifier a registered client of this security server. Client can be either a member or a subsystem. + + + + + + + + + + + + Name of the CA, used in user interfaces. + + + + + + + If present and true, indicates that certificates issued by this CA can only be used for TLS + authentication and not for creating and verifying digital signatures/seals. + + + + + + + Topmost (usually self-signed) CA that is used as trust anchor. + + + + + + + Intermediate CA. This information can be used for certificate path building and finding OCSP + responders. + + + + + + + Fully qualified class name implementing the + ee.ria.xroad.common.certificateprofile.CertificateProfileInfoProvider interface. + + + + + + + + + + + + Code that uniquely identifies the group within an X-Road instance. + + + + + + + Description of the group. + + + + + + + Identifier of an X-Road member or a subsystem belonging to this group. + + + + + + + + + + Information about an OCSP provider. + + + + + + + URL of the OSCP server. + + + + + + + Certificate used by the OCSP server to sign OCSP responses. + + + + + + + + + + + + Name of the time-stamping authority, used in user interfaces. + + + + + + + URL of the time-stamping service. + + + + + + + Certificate used by the time-stamping server to sign responses. + + + + + + + + + + This type encapsulates information about a certification authority. + + + + + + + The CA certificate value. + + + + + + + List of OCSP responders that provide status of certificates issued by this CA. + + + + + + + + + + + + Code that uniquely identifies this subsystem within the subsystems of its parent-member. + + + + + + + + + + + + + Code that uniquely identifies the member class in this X-Road instance. + + + + + + + Description of the member class. + + + + + + + + + + + + Code that uniquely identifies a central service in this X-Road instance. + + + + + + + Identifier of the service that implements the central service. + + + + + + + + + + + + Lists the member classes used in this X-Road instance. + + + + + + + Maximum allowed validity time of OCSP responses. If thisUpdate field of an OCSP response is + older than ocspFreshnessSeconds seconds, it is no longer valid. + + + + + + diff --git a/src/common/common-util/src/main/resources/globalconf/private-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/private-parameters.xsd deleted file mode 100644 index df6f6a3293..0000000000 --- a/src/common/common-util/src/main/resources/globalconf/private-parameters.xsd +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - Set of configuration parameters that are used only by members of this X-Road instance. - - - - - - - Information about a source of configuration. - - - - - - - - - - Code that uniquely identifies this instance of the X-Road system within a federation of - systems. - - - - - - - Information about a source of configuration. - - - - - - - Parameters of management services called by the security servers. - - - - - - - Time interval (in seconds) after which a logged signature should be time-stamped. - This ensures that the time-stamped signature can be used as evidence at some later date. - - - - - - - - - - - - Address of the authentication certificate registration service that can be called by the - security servers. - - - - - - - Server certificate that is used to authenticate TLS connection to the authentication - certificate registration service. - - - - - - - Identifier of the X-Road member or subsystem providing the management request services. - - - - - - - - - - - Date when this anchor was produced - - - - - - - Code of the X-Road instance that provides configuration to this configuration source. - - - - - - - Describes one configuration source. - - - - - - - - - - - - HTTP URL that can be used to download signed configuration. - - - - - - - Public key that can be used to verify the signed configuration, presented as X.509 certificate. - - - - - - diff --git a/src/common/common-util/src/main/resources/globalconf/shared-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/shared-parameters.xsd deleted file mode 100644 index f135869062..0000000000 --- a/src/common/common-util/src/main/resources/globalconf/shared-parameters.xsd +++ /dev/null @@ -1,371 +0,0 @@ - - - - - - - - Set of configuration parameters that are used by members of this X-Road instance and other federated - instances. - - - - - - - - - - Code that uniquely identifies this instance of the X-Road system within a federation of - systems. - - - - - - - Certification authority approved by the Governing Authority of providing certification services - for members of this X-Road instance. - - - - - - - Time-stamping authority approved by the Governing Authority of providing time-stamping services - for members of this X-Road instance. - - - - - - - Registered member of this X-Road system. - - - - - - - Security server registered in this X-Road system. - - - - - - - Group of access rights subjects, defined by the Governing Authority. An access rights subject - can be either a member or a subsystem. - - - - - - - Central service, defined by the Governing Authority. - - - - - - - Classifiers and security policy settings used in this X-Road instance. - - - - - - - - - - - - Member class of the member. - - - - - - - Code that uniquely identifies the member within the given member class. - - - - - - - Full, official name of the member, used in user interfaces. - - - - - - - Represents information about a part of the member's information system that is acting as an - independent service consumer or provider in the X-Road system. - - - - - - - - - - - - - Identifier of the member who is responsible for the security server. - - - - - - - Code that uniquely identifies this server within servers owned by the same member. - - - - - - - Externally visible address of the security server. - - - - - - - Hash of the authentication certificate used by the security server. - - - - - - - Identifier a registered client of this security server. Client can be either a member or a subsystem. - - - - - - - - - - - - Name of the CA, used in user interfaces. - - - - - - - If present and true, indicates that certificates issued by this CA can only be used for TLS - authentication and not for creating and verifying digital signatures/seals. - - - - - - - Topmost (usually self-signed) CA that is used as trust anchor. - - - - - - - Intermediate CA. This information can be used for certificate path building and finding OCSP - responders. - - - - - - - Fully qualified class name implementing the - ee.ria.xroad.common.certificateprofile.CertificateProfileInfoProvider interface. - - - - - - - - - - - - Code that uniquely identifies the group within an X-Road instance. - - - - - - - Description of the group. - - - - - - - Identifier of an X-Road member or a subsystem belonging to this group. - - - - - - - - - - Information about an OCSP provider. - - - - - - - URL of the OSCP server. - - - - - - - Certificate used by the OCSP server to sign OCSP responses. - - - - - - - - - - - - Name of the time-stamping authority, used in user interfaces. - - - - - - - URL of the time-stamping service. - - - - - - - Certificate used by the time-stamping server to sign responses. - - - - - - - - - - This type encapsulates information about a certification authority. - - - - - - - The CA certificate value. - - - - - - - List of OCSP responders that provide status of certificates issued by this CA. - - - - - - - - - - - - Code that uniquely identifies this subsystem within the subsystems of its parent-member. - - - - - - - - - - - - - Code that uniquely identifies the member class in this X-Road instance. - - - - - - - Description of the member class. - - - - - - - - - - - - Code that uniquely identifies a central service in this X-Road instance. - - - - - - - Identifier of the service that implements the central service. - - - - - - - - - - - - Lists the member classes used in this X-Road instance. - - - - - - - Maximum allowed validity time of OCSP responses. If thisUpdate field of an OCSP response is - older than ocspFreshnessSeconds seconds, it is no longer valid. - - - - - - diff --git a/src/common/common-util/src/main/resources/globalconf/v2/private-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/v2/private-parameters.xsd new file mode 100644 index 0000000000..9c5538a031 --- /dev/null +++ b/src/common/common-util/src/main/resources/globalconf/v2/private-parameters.xsd @@ -0,0 +1,63 @@ + + + + + + + + + Set of configuration parameters that are used only by members of this X-Road instance. + + + + + + + Information about a source of configuration. + + + + + + + + + + Code that uniquely identifies this instance of the X-Road system within a federation of + systems. + + + + + + + Information about a source of configuration. + + + + + + + Parameters of management services called by the security servers. + + + + + + + Time interval (in seconds) after which a logged signature should be time-stamped. + This ensures that the time-stamped signature can be used as evidence at some later date. + + + + + + + diff --git a/src/common/common-util/src/main/resources/globalconf/v2/shared-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/v2/shared-parameters.xsd new file mode 100644 index 0000000000..bd3dc3853a --- /dev/null +++ b/src/common/common-util/src/main/resources/globalconf/v2/shared-parameters.xsd @@ -0,0 +1,83 @@ + + + + + + + + + Set of configuration parameters that are used by members of this X-Road instance and other federated + instances. + + + + + + + + + + Code that uniquely identifies this instance of the X-Road system within a federation of + systems. + + + + + + + Certification authority approved by the Governing Authority of providing certification services + for members of this X-Road instance. + + + + + + + Time-stamping authority approved by the Governing Authority of providing time-stamping services + for members of this X-Road instance. + + + + + + + Registered member of this X-Road system. + + + + + + + Security server registered in this X-Road system. + + + + + + + Group of access rights subjects, defined by the Governing Authority. An access rights subject + can be either a member or a subsystem. + + + + + + + Central service, defined by the Governing Authority. + + + + + + + Classifiers and security policy settings used in this X-Road instance. + + + + + + + diff --git a/src/common/common-util/src/main/resources/globalconf/v3/private-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/v3/private-parameters.xsd new file mode 100644 index 0000000000..684eb966b1 --- /dev/null +++ b/src/common/common-util/src/main/resources/globalconf/v3/private-parameters.xsd @@ -0,0 +1,64 @@ + + + + + + + + + Set of configuration parameters that are used only by members of this X-Road instance. + + + + + + + Information about a source of configuration. + + + + + + + + + + Code that uniquely identifies this instance of the X-Road system within a federation of + systems. + + + + + + + Information about a source of configuration. + + + + + + + Parameters of management services called by the security servers. + + + + + + + Time interval (in seconds) after which a logged signature should be time-stamped. + This ensures that the time-stamped signature can be used as evidence at some later date. + + + + + + + + diff --git a/src/common/common-util/src/main/resources/globalconf/v3/shared-parameters.xsd b/src/common/common-util/src/main/resources/globalconf/v3/shared-parameters.xsd new file mode 100644 index 0000000000..ab499ec814 --- /dev/null +++ b/src/common/common-util/src/main/resources/globalconf/v3/shared-parameters.xsd @@ -0,0 +1,110 @@ + + + + + + + + + Set of configuration parameters that are used by members of this X-Road instance and other federated + instances. + + + + + + + + + + The address of the central server which provides the signed configuration. + + + + + + + Public key that can be used to verify the signed configuration, presented as X.509 certificate. + + + + + + + + + + + + Code that uniquely identifies this instance of the X-Road system within a federation of + systems. + + + + + + + Describes one configuration source. + + + + + + + Certification authority approved by the Governing Authority of providing certification services + for members of this X-Road instance. + + + + + + + Time-stamping authority approved by the Governing Authority of providing time-stamping services + for members of this X-Road instance. + + + + + + + Registered member of this X-Road system. + + + + + + + Security server registered in this X-Road system. + + + + + + + Group of access rights subjects, defined by the Governing Authority. An access rights subject + can be either a member or a subsystem. + + + + + + + Central service, defined by the Governing Authority. + + + + + + + Classifiers and security policy settings used in this X-Road instance. + + + + + + + + diff --git a/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorTest.java b/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorTest.java index 6722380186..57dd2731f8 100644 --- a/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorTest.java +++ b/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationAnchorTest.java @@ -41,14 +41,14 @@ public class ConfigurationAnchorTest { */ @Test public void readAnchorV2() { - ConfigurationAnchorV2 a = new ConfigurationAnchorV2( + ConfigurationAnchor a = new ConfigurationAnchor( "src/test/resources/configuration-anchor1.xml"); assertEquals("EE", a.getInstanceIdentifier()); assertEquals(3, a.getLocations().size()); ConfigurationLocation l = a.getLocations().get(0); - assertEquals("http://www.bar.com/conf?version=2", l.getDownloadURL()); + assertEquals("http://www.bar.com/conf", l.getDownloadURL()); String hash = "t7+jfR1wnsN1EBtBpCt/q8JIasg="; String hashAlgoId = "http://www.w3.org/2000/09/xmldsig#sha1"; @@ -63,11 +63,11 @@ public void readAnchorV2() { */ @Test public void equalsAnchorV2() { - ConfigurationAnchorV2 a = new ConfigurationAnchorV2( + ConfigurationAnchor a = new ConfigurationAnchor( "src/test/resources/configuration-anchor1.xml"); - ConfigurationAnchorV2 b = new ConfigurationAnchorV2( + ConfigurationAnchor b = new ConfigurationAnchor( "src/test/resources/configuration-anchor1.xml"); - ConfigurationAnchorV2 c = new ConfigurationAnchorV2( + ConfigurationAnchor c = new ConfigurationAnchor( "src/test/resources/configuration-anchor2.xml"); assertEquals(a, a); assertEquals(a, b); diff --git a/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryTest.java b/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2Test.java similarity index 67% rename from src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryTest.java rename to src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2Test.java index 44aa55aa7c..b647cb337b 100644 --- a/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryTest.java +++ b/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV2Test.java @@ -25,6 +25,7 @@ */ package ee.ria.xroad.common.conf.globalconf; +import ee.ria.xroad.common.CodedException; import ee.ria.xroad.common.util.ExpectedCodedException; import org.junit.Rule; @@ -34,13 +35,16 @@ import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; /** - * Tests to verify configuration directories are read correctly. + * Tests to verify v2 configuration directories are read correctly. */ -public class ConfigurationDirectoryTest { +public class ConfigurationDirectoryV2Test { @Rule public ExpectedCodedException thrown = ExpectedCodedException.none(); @@ -56,12 +60,12 @@ public void readDirectoryV2() throws Exception { assertEquals("EE", dir.getInstanceIdentifier()); - PrivateParametersV2 p = dir.getPrivate("foo"); + PrivateParameters p = dir.getPrivate("foo"); assertNotNull(p); assertEquals("foo", p.getInstanceIdentifier()); - SharedParametersV2 s = dir.getShared("foo"); + SharedParameters s = dir.getShared("foo"); assertNotNull(s); assertEquals("foo", s.getInstanceIdentifier()); @@ -92,11 +96,12 @@ public void readEmptyDirectoryV2() throws Exception { * @throws Exception in case of any unexpected errors */ @Test - public void readMalformedDirectoryV2() throws Exception { - ConfigurationDirectoryV2 dir = new ConfigurationDirectoryV2("src/test/resources/globalconf_malformed"); - - assertNull(dir.getPrivate("foo")); - assertNull(dir.getShared("foo")); + public void readMalformedDirectoryV2() { + CodedException exception = assertThrows( + CodedException.class, + () -> new ConfigurationDirectoryV2("src/test/resources/globalconf_malformed") + ); + assertEquals("Content is not allowed in prolog.", exception.getFaultString()); } /** @@ -112,22 +117,22 @@ public void readConfigurationFilesV2() throws Exception { List configurationFiles = dir.getConfigurationFiles(); - assertEquals(false, pathExists(configurationFiles, rootDir + "/instance-identifier")); + assertFalse(pathExists(configurationFiles, rootDir + "/instance-identifier")); - assertEquals(true, pathExists(configurationFiles, rootDir + "/bar/shared-params.xml")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/bar/shared-params.xml.metadata")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/bar/private-params.xml")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/bar/private-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/bar/shared-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/bar/shared-params.xml.metadata")); + assertFalse(pathExists(configurationFiles, rootDir + "/bar/private-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/bar/private-params.xml.metadata")); - assertEquals(true, pathExists(configurationFiles, rootDir + "/EE/shared-params.xml")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/EE/shared-params.xml.metadata")); - assertEquals(true, pathExists(configurationFiles, rootDir + "/EE/private-params.xml")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/EE/private-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/EE/shared-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/EE/shared-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/EE/private-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/EE/private-params.xml.metadata")); - assertEquals(true, pathExists(configurationFiles, rootDir + "/foo/shared-params.xml")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/foo/shared-params.xml.metadata")); - assertEquals(true, pathExists(configurationFiles, rootDir + "/foo/private-params.xml")); - assertEquals(false, pathExists(configurationFiles, rootDir + "/foo/private-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/foo/shared-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/foo/shared-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/foo/private-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/foo/private-params.xml.metadata")); } private boolean pathExists(List paths, String path) { diff --git a/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV3Test.java b/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV3Test.java new file mode 100644 index 0000000000..48dea48492 --- /dev/null +++ b/src/common/common-util/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDirectoryV3Test.java @@ -0,0 +1,147 @@ +/* + * The MIT License + * Copyright (c) 2019- Nordic Institute for Interoperability Solutions (NIIS) + * Copyright (c) 2018 Estonian Information System Authority (RIA), + * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK) + * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package ee.ria.xroad.common.conf.globalconf; + +import ee.ria.xroad.common.CodedException; +import ee.ria.xroad.common.util.ExpectedCodedException; + +import org.junit.Rule; +import org.junit.Test; + +import java.nio.file.Path; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Tests to verify v3 configuration directories are read correctly. + */ +public class ConfigurationDirectoryV3Test { + + @Rule + public ExpectedCodedException thrown = ExpectedCodedException.none(); + + /** + * Test to ensure a correct configuration directory is read properly. + * + * @throws Exception in case of any unexpected errors + */ + @Test + public void readDirectoryV3() throws Exception { + ConfigurationDirectoryV3 dir = new ConfigurationDirectoryV3("src/test/resources/globalconf_good_v3"); + + assertEquals("EE", dir.getInstanceIdentifier()); + + PrivateParameters p = dir.getPrivate("foo"); + + assertNotNull(p); + assertEquals("foo", p.getInstanceIdentifier()); + + SharedParameters s = dir.getShared("foo"); + + assertNotNull(s); + assertEquals("foo", s.getInstanceIdentifier()); + + dir.getShared("foo"); // intentional + + assertNull(dir.getPrivate("bar")); + assertNotNull(dir.getShared("bar")); + assertNull(dir.getShared("xxx")); + } + + /** + * Test to ensure an empty configuration directory is read properly. + * + * @throws Exception in case of any unexpected errors + */ + @Test + public void readEmptyDirectoryV3() throws Exception { + ConfigurationDirectoryV3 dir = new ConfigurationDirectoryV3("src/test/resources/globalconf_empty"); + + assertNull(dir.getPrivate("foo")); + assertNull(dir.getShared("foo")); + } + + /** + * Test to ensure that reading of a reading v2 configuration fails. + * + * @throws Exception in case of any unexpected errors + */ + @Test + public void readConfigurationDirectoryV2() { + CodedException exception = assertThrows( + CodedException.class, + () -> new ConfigurationDirectoryV3("src/test/resources/globalconf_good_v2") + ); + assertEquals( + "cvc-complex-type.2.4.a: Invalid content was found starting with element 'approvedCA'. One of '{source}' is expected.", + exception.getFaultString() + ); + } + + /** + * Test to ensure that the list of available configuration files excluding metadata and directories + * is read properly. + * + * @throws Exception in case of any unexpected errors + */ + @Test + public void readConfigurationFilesV3() throws Exception { + String rootDir = "src/test/resources/globalconf_good_v3"; + ConfigurationDirectoryV3 dir = new ConfigurationDirectoryV3(rootDir); + + List configurationFiles = dir.getConfigurationFiles(); + + assertFalse(pathExists(configurationFiles, rootDir + "/instance-identifier")); + + assertTrue(pathExists(configurationFiles, rootDir + "/bar/shared-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/bar/shared-params.xml.metadata")); + assertFalse(pathExists(configurationFiles, rootDir + "/bar/private-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/bar/private-params.xml.metadata")); + + assertTrue(pathExists(configurationFiles, rootDir + "/EE/shared-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/EE/shared-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/EE/private-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/EE/private-params.xml.metadata")); + + assertTrue(pathExists(configurationFiles, rootDir + "/foo/shared-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/foo/shared-params.xml.metadata")); + assertTrue(pathExists(configurationFiles, rootDir + "/foo/private-params.xml")); + assertFalse(pathExists(configurationFiles, rootDir + "/foo/private-params.xml.metadata")); + } + + private boolean pathExists(List paths, String path) { + return null != paths.stream() + .filter(p -> (p.getParent() + "/" + p.getFileName()).equals(path)) + .findAny() + .orElse(null); + } +} diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/EE/private-params.xml b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/private-params.xml new file mode 100644 index 0000000000..a272c5ca20 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/private-params.xml @@ -0,0 +1,24 @@ + + + EE + + bar + + http://www.bar.com/conf + YmFyCg== + + + + http://mgmt.com:1234 + + + EE + BUSINESS + servicemember2 + + + 123 + diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/EE/private-params.xml.metadata b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/private-params.xml.metadata new file mode 100644 index 0000000000..f8540fdba4 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/private-params.xml.metadata @@ -0,0 +1 @@ +{"contentIdentifier":"PRIVATE-PARAMETERS","instanceIdentifier":"EE","expirationDate":"2124-05-20T17:42:55Z"} \ No newline at end of file diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/EE/shared-params.xml b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/shared-params.xml new file mode 100644 index 0000000000..efc43a5df3 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/shared-params.xml @@ -0,0 +1,487 @@ + + + + EE + + +
cs0
+ MIICqTCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQ0FADAOMQwwCgYDVQQDDANOL0EwHhcNNzAwMTAxMDAwMDAwWhcNMzgwMTAxMDAwMDAwWjAOMQwwCgYDVQQDDANOL0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDe10ai/VApuFjG+cgVLaV18qOEor6il83v0ErKBVznkSEzhzfplPJbfbXVHCezUsZOtVypvS4VCKg3S9wDBJVHmLrTl8z43xHowSE2KhvBxP+boH+9wt4dWdkiM4vohzuDuqz2k7ly50LlaokY/hQfLZKqRAB4PyiA9H1dk9hri9kIckGZpKHxVmXD19pd1hbvRmEcxF0kEAP4oyQ8EaQpgoy4KiN60x6hV8+xZPUqf03eQgh5LXvpmXDtGT58zN43Om8L+dPCtKyK6dTTjNakv6tJxoZJ2yUnVWPZKH9B3nM79bToxA9SiCjg3i6rU8HJ8ih163Dh9upPwqpmdEqDAgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIGQDANBgkqhkiG9w0BAQ0FAAOCAQEAdgVRzoNWG7shsBV+r9I4dB/ghfnxZAcgag9qevG4YrzLEDHupGB7a0Rx4dKp7gxzSV+E82oFOTZMhQdcVinRrqZT1U8DeT1tgvRH6V24g8HCplDp3AuRWKlPFAWIpsyZ6n6oMIrS9uVCaTF4A8uFZ7GxgcByMP+9BwCNQAigFGJOZzwln60idlR8YmtVCn4oVfBVrH+JRNSfgosVqqZe3q/XHNJP4iVqPt7taYzwwdz2XW02p8lgYZ1MwhMbcZ7xqNjYA0U9yQbUc6/oZ54R5FIgNldINCAJaNRRjXVS+1nt6bRM9GtZoeC4vhFqxIpduQRYpMD2MaJqbwDgal2pmA== + + + + pki1 + + + MIIDjTCCAnWgAwIBAgIJAKL3zm5uAgNAMA0GCSqGSIb3DQEBBQUAMF0xCzAJBgNV + BAYTAkVFMRQwEgYDVQQKEwtDeWJlcm5ldGljYTEMMAoGA1UECxMDSVRPMQ4wDAYD + VQQDEwVDeWJlcjEaMBgGCSqGSIb3DQEJARYLYWFhQGJiYi5jY2MwHhcNMTQwOTI5 + MDk0MTM3WhcNMjQwOTI2MDk0MTM3WjBdMQswCQYDVQQGEwJFRTEUMBIGA1UEChML + Q3liZXJuZXRpY2ExDDAKBgNVBAsTA0lUTzEOMAwGA1UEAxMFQ3liZXIxGjAYBgkq + hkiG9w0BCQEWC2FhYUBiYmIuY2NjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB + CgKCAQEA0ntJBTdBj7KT+j37yQ3r9pzO/VgVRQptQO6pDGSYonBRDbziYyBAuo8O + wta2GshTqiqbD9OMqi8EK2fxrnCfo5HhG4BwY4DPGCozwI/9ETCNp/ElxrICbb68 + zCQy6ecOrPbirG3baKUKPxBwnN/S1w57rR66Eb02hlA0/AAqN7GJnNqonpeDnIQ5 + vq4bdrrjGEwke44hfR+wI81fVP2oc28AWk3p1TVA0TPLjKfQOlXMfVYIA+Pf+9N4 + uiOXAcv4ZfUAJbiZQujBdHR7wF4SiV0u3Xfwfk6uj1Ddpv5ehh8HKhiNoDySCXgR + I8I5X1gbQ3MIFR7CSwcZuZkolsQnHQIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0G + A1UdDgQWBBR+egbuTBG1XAUq40xvTvPKht3y3jAfBgNVHSMEGDAWgBR+egbuTBG1 + XAUq40xvTvPKht3y3jANBgkqhkiG9w0BAQUFAAOCAQEAu6QBabq8zQXnxGRCeKpB + vp4iMY4VOWm2QYiwDljaQpMvQWjoBhMEZsaaux/ouSiQvAzbO/NdHHJsXAfwxM2E + o8kFtZNIlTvBs3Os7CvLle1z7pwU/m9LOeakys9xDQRzlPqQwN0Q2oELu0tOHtkd + 2RBLXjy5ZXHHw+KnDwfQlLUzvNRLLmZIfZxMf57z53eP59T0UYBj2bHYV2hxfzYH + mJG6nz8FW/mImr53meFTrM6muw6fKbeKTNvr4n+7AK6Hn6Whie730DB4A9xyWvjd + QWYo7FtYJ/WvbC45E8ppGZH0OWBI028yDvfVgeB8eIpzeMyI1fSHGb66hKc3ruWd + SA== + + http://127.0.0.1:8082/ocsp + + MIIDejCCAmKgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBdMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDDAKBgNVBAsTA0lUTzEOMAwGA1UEAxMFQ3li + ZXIxGjAYBgkqhkiG9w0BCQEWC2FhYUBiYmIuY2NjMB4XDTE0MDkyOTA5NTYxMloX + DTI0MDkyNjA5NTYxMlowYDELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0 + aWNhMQwwCgYDVQQLEwNJVE8xETAPBgNVBAMTCGNvbnN1bWVyMRowGAYJKoZIhvcN + AQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB + AM0nxh0cNjmjmqYIyBpOCnQb4/eIgPcJF7gTMmhlg5HAkczGraGyrywUumZTUU0j + 3CzsXpXjsCWKtgkwzfmDQggfA95x50fu8HxIlHyd75FnA0EnXS9c9aw5v8SOEKYB + 5UADIhqoGUkqZd21O3o8RJyO8pI4hfe0EiVbQumH3VtNwkgoiK0XlZVRvJeYBYe8 + OODIU+xj8db+BV7QHcRVHBzuynJoy15kByNMzx+kjAPZH+AbB7r6c11i/qd0weno + 55QMlilG/Ez/TZiW7oDBgj7lH8c7AQy8bwhEJSLXAD0H3uytOVaWB9O5PkDDdUD+ + O0yRvSf+hCtaQ828sfQxYz8CAwEAAaNCMEAwHQYDVR0OBBYEFGe3oWflVEr3ammj + rELcGPOdqmwSMB8GA1UdIwQYMBaAFH56Bu5MEbVcBSrjTG9O88qG3fLeMA0GCSqG + SIb3DQEBBQUAA4IBAQC968pzwVBu+nJgpLnQDF4oEyoJHg+fteCBo/IU0DHvWgYv + vliTOelxwIOhjerGBFGxWQVYJiB1VRBTa/e8q4NTFjeN0LGkyO8KdYIA4yhZTwIe + 0ctA62R46II4S7cvoCl993b9wxujMjz9v4Zz7oOx+sFOV8fOI828YQjQCRSOCbcJ + okpGIjJQrdDq3nBVf5f7bCUH6SRWnng3y9ntzgjx8SiQgX+CYTcdWew/9c0Ko6je + neKQsBCiYuP03CJX5gg5yC37MxlcC2NpwdM60Q+7sp+Riz+eGw4tpVnAEmD8ZwHl + vuN63j9maswGt/KrgylIF99T/5WpbFVRWQHibbEH + + + + http://www.example.net/ocsp + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + pki2 + true + + + MIIDiDCCAnCgAwIBAgIIEVk07cr7+SMwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTE5MDkxODU2WhcNMTQxMTE5MDkxODU2WjATMREwDwYDVQQDDAhjb25z + dW1lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM64hfHPpteJYaUm + DJaEVQ+3yst6hNocO1Ax8Bu1Zk1MKkyOiayfwsnCDN5XpDSlFRx/+aP6x8PFte2D + YFPq+3aP1ymN/iBCJlp2vDukkD8TAMaewKJpdWZD8WFAUnncRPy1q8BcLehexieE + rTGlPLrgbW115FXur7YN8CHZPb0TyfELsXPPWK3i/YREhl4Xk7keI7z3qQnUQbJL + wIrkSLq07pt2ciVmmZxFJq3TpB9grw/mnCURLJ1yY14FWLZ+hPrYGnzlkTcfKB6c + JfBKWUxkB5+JRL3yFo4dySfdiZ8wsJh0cbqEHDW2UghQQ/hkbJnn4UmZrrHn95we + t5pZQAcCAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGGPGh0 + dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dlYi9z + dGF0dXMvb2NzcDAdBgNVHQ4EFgQUfbgfWLDuAcEKrjXT3/CdH4D/CEEwDAYDVR0T + AQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNVHQ8B + Af8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBADe8dzcmKMa6RHzrgRTmApBMBlHR + Vg2kRRJF4NdSUbxUotLxBCA5ZlXdqm5cb3m9XtcU45+mC9S1eLPO69ZuVe6K3zY8 + MSoKSfKzVkWEEtqEn/wHiqkb90qtAITjt4FkWo3mSufMzSpBkUrxasaqIYBloLKm + tYmuCfu1gS2euG0KDPfH+i0IBgCZLBeZzdU+H2qTXH734Y3CF3eYGJ3XP6RQzZaZ + vE8J5km9BgGS1wqIsuBwdy3Zt8yuq1kR02CQ/0BnfnUsqVIvZR61Nl0j6VK8RtUS + yoYV9OkEmN6OTK4J8F47fh8AZUeagLJ29t0KdlS9VR849VWHQqAzakOU1uk= + + + http://127.0.0.1:8082/ocsp + + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + http://www.example.net/ocsp + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + pki3 + false + + + MIIDiDCCAnCgAwIBAgIIVYNTWA8JcLwwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTE5MDkxNDIzWhcNMTQxMTE5MDkxNDIzWjATMREwDwYDVQQDDAhwcm9k + dWNlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALKNC381RiACCftv + ApBzk5HD5YHw0u9SOkwcIkn4cZ4eQWrlROnqHTpS9IVSBoOz6pjCx/FwxZTdpw0j + X+bRYpxnj11I2XKzHfhfa6BvL5VkaDtjGpOdSGMJUtrI6m9jFiYryEmYHWxPlL9V + pDK0KknevYm2BR23/xDHweBSZ7tkMENU1kXFWLunoBys+W0waR+Z8HH5WNuBLz8X + z2iz/6KQ5BoWSPJc9P5TXNOBB+5XyjBR2ogoAOtX53OJzu0wMgLpjuJGdfcpy1S9 + ukU27B21i2MfZ6Tjhu9oKrAIgcMWJaHJ/gRX6iX1vXlfhUTkE1ACSfvhZdntKLzN + TZGEcxsCAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGGPGh0 + dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dlYi9z + dGF0dXMvb2NzcDAdBgNVHQ4EFgQUUHtGmEl0Cuh/x/wj+UU5S7Wui48wDAYDVR0T + AQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNVHQ8B + Af8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACJqqey5Ywoegq+Rjo4v89AN78Ou + tKtRzQZtuCZP9+ZhY6ivCPK4F8Ne6qpWZb63OLORyQosDAvj6m0iCFMsUZS3nC0U + DR0VyP2WrOihBOFC4CA7H2X4l7pkSyMN73ZC6icXkbj9H0ix5/Bv3Ug64DK9SixG + RxMwLxouIzk7WvePQ6ywlhGvZRTXxhr0DwvfZnPXxHDPB2q+9pKzC9h2txG1tyD9 + ffohEC/LKdGrHSe6hnTRedQUN3hcMQqCTc5cHsaB8bh5EaHrib3RR0YsOhjAd6IC + ms33BZnfNWQuGVTXw74Eu/P1JkwR0ReO+XuxxMp3DW2epMfL44OHWTb6JGY= + + + http://127.0.0.1:8082/ocsp + + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + http://www.example.net/ocsp + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + pki4 + true + + + MIIDZzCCAk+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDTALBgNVBAsTBENBIDExGjAYBgkqhkiG9w0B + CQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDExNTk0MFoXDTIyMDkxMjExNTk0MFow + TjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQLEwRD + QSAyMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAM1Ex4Bh8zHU+wWyp2fm7U2dAqooUamE4hyLVrmNifvB + AjKT7gSMeTB2bxCE38BYfzvnbQCs82piQRC6iCgHE/Ywr1zz86Pa/OI36tBmCCjW + NDm/U6MAlwT7s+GL3bpty4aY4pLilQZbmyDsE2hsJ+R82GMBttRku3LMKKE/jyQI + 26gK9xhYPPF85cfv7hylekcr8fUeGFmxEULLWyFFwhR9pr7HPcKhJR/h4rhJ3e0d + EDfROPtVfBSViS5UCh7UNut8Q3kbwwZBIa1NEN9vPUIBhH/ZvKr3a7188y3n1GY8 + paSVdYmGZYDSyK7ugztEOFWqekiA7gfLdyeCto12K10CAwEAAaNQME4wDAYDVR0T + BAUwAwEB/zAdBgNVHQ4EFgQUJDYGHNJmNdoV9S/T4ZLv/ze+JYIwHwYDVR0jBBgw + FoAUqV/rN9mEwnTBN+y4Di3aLz4BKj8wDQYJKoZIhvcNAQEFBQADggEBAC63dW7v + 5J1Yf7ue2ybTfIYVFAN1LOY4Ge+zLai2wkhRjaOqzV67HB/e1zItBbq0M1NkA4DQ + DM/aEoave5aMoZtR77JUrFG2KLnTqJZb3AZDWi3qsdYNo1yW0YMgGBVq8pThJ4NH + +QV5MdgkMZjDUJArtU0Z6eD7br0BiA4uEx4irr0j8e5oInBbMPb4Orv05yuaXc9n + utPIm7iudKcNsHs+16ACAo0KdU38GnwgGW83B0LB0sCVwFMH1OpC435dXLDycvg+ + Pe5VvXxCL6guFtZtBbnAAtRreTC3bhS+bnxLyj+Hk7oAYyaW441BnzPcVWYeAf56 + 89A9e6HCmXEY1bo= + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + + pki5 with intermediate certs + true + + + MIIDdTCCAl2gAwIBAgIJAOuBNCIUm0gwMA0GCSqGSIb3DQEBBQUAMFExCzAJBgNV + BAYTAkVFMRQwEgYDVQQKEwtDeWJlcm5ldGljYTEQMA4GA1UECxMHUm9vdCBDQTEa + MBgGCSqGSIb3DQEJARYLYWFhQGJiYi5jY2MwHhcNMTIwOTE0MTE1NjM3WhcNMjIw + OTEyMTE1NjM3WjBRMQswCQYDVQQGEwJFRTEUMBIGA1UEChMLQ3liZXJuZXRpY2Ex + EDAOBgNVBAsTB1Jvb3QgQ0ExGjAYBgkqhkiG9w0BCQEWC2FhYUBiYmIuY2NjMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArnYuIDCNNqIZ/GH0THglNHoU + T8PCfH5HGeVadaQu5xJFg2hLfbCvJNDGDgOcGXlss8tZ51y80EGwJFAU1IajhELF + yRDhEUsBd7FzulMxMwMFwluoPB1u0XUsNmYunmdlBc6BERkrTQi8oRXO7psslbiU + 4LDqeIdP04RhySNnVRwfb3eBfGR7Gh/EbdFeB814gCpoM6nmK1XR2f3JdCTJxPyE + 7EppIDPBBmgpzq2TzHF3qzd1Qv5Xe0XSC6DnkTbzpxrCvalGqGrIYOsV5vtOFt+2 + Tlx+QHIWhvZ9bDdEGY58O0jWj3lO5VkFYsloauYa8trCm7w20J6QqwtCIskMvwID + AQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRSFYADqiIAKTGIT44uTLwS + hz1YZzAfBgNVHSMEGDAWgBRSFYADqiIAKTGIT44uTLwShz1YZzANBgkqhkiG9w0B + AQUFAAOCAQEAMn7YD7C3cjkQL0wm1v47KYda/Y05jR5zMwV648VHgPeNLRyZYWJr + pHdUQiAqKL3zhF8neOQO100fwUxSxLsuPNqkce02DwjMSMWi3bF9xX7MlrQnAb6a + SJ47YaPyZSvXlkzRC3dcDjcBIRSGNxsftISSEJJeqGWQz6b9LkIfxTjtcHbTnm/y + GPWpmr2blkm7qRKK4eFwvooJ6KqBmm8/J086VpDOc9qRy/ar3za6UdFEBDX2aHQD + 4OLgBvj0dLYCu3w32ltmVOgBoewIq5M1wBGp8dIs5Jrr4P9xYprRY1une3IWvviJ + NXoWm1enl1+N31r32YIc4vXZiA2L+cjlvQ== + + + + MIIDajCCAlKgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGjAYBgkqhkiG + 9w0BCQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDExNTY1OFoXDTIyMDkxMjExNTY1 + OFowTjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQL + EwRDQSAxMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcN + AQEBBQADggEPADCCAQoCggEBAOnguIBD8dfb4vM73WKR+T2zWKAbFeUu7Wcpio/2 + CDLJZ3mF2Zo+JWOk8nYSUrZkFpCvH+S5Mhj0Eo4LcCk2PTiRP2fPPABIQmEXgLKU + gcqH132fVCyPRKdL+hG+CA7yzDOIO0h8ME/nQBuEJHc+ayGSyKG5/PfsETfseD0f + 9QoaAXsrztkhH+yNX+JgaPAyxQqFB8p8PLX3DrkD1JtslSjMJTuitVsf4JKb9zmI + /lGaMGqkq5ss3c1weF8s38+Zt8rU4FHS+DvFTVJVMHjnTu/emgiRiLJWXioKmijy + glMoZvpahgtOieS50Vgn8V+ttL4kLYSBFlAVkNOa0Fbz8eMCAwEAAaNQME4wDAYD + VR0TBAUwAwEB/zAdBgNVHQ4EFgQUqV/rN9mEwnTBN+y4Di3aLz4BKj8wHwYDVR0j + BBgwFoAUUhWAA6oiACkxiE+OLky8Eoc9WGcwDQYJKoZIhvcNAQEFBQADggEBAKBk + ++HBiGxSqDQUVWRjrD/5uBk/RH9oH2C/ZXYUyFCjAvmUWa+dWFyJScyVcZpchnbO + SUPKtFR78N3nJp01mbWyvzws4C+DbwPOdwPJHNKqwybn4uz1oWDoNioi1ITkjlYo + haDs9uVI9sLrApqQnSgL7Oc4yG2TSoa0YkLmdICHxH9TCK0NEUxW6Sa4aehftLD/ + 7gNORIe8YT9MqPGWDW6Za9f74Vx+H5/ejRkTKUA6jHTLmZCly4L2f+tpDIs22omd + 0X3Ct9os/XA7ZbbwiMuqAiiXKVGerTmeCrkWcixDkN9ATCI0ur5NZniSVnXGjV6m + u3cl4oYr+u2NJVPDgKI= + + + + + MIIDZzCCAk+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDTALBgNVBAsTBENBIDExGjAYBgkqhkiG9w0B + CQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDExNTk0MFoXDTIyMDkxMjExNTk0MFow + TjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQLEwRD + QSAyMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAM1Ex4Bh8zHU+wWyp2fm7U2dAqooUamE4hyLVrmNifvB + AjKT7gSMeTB2bxCE38BYfzvnbQCs82piQRC6iCgHE/Ywr1zz86Pa/OI36tBmCCjW + NDm/U6MAlwT7s+GL3bpty4aY4pLilQZbmyDsE2hsJ+R82GMBttRku3LMKKE/jyQI + 26gK9xhYPPF85cfv7hylekcr8fUeGFmxEULLWyFFwhR9pr7HPcKhJR/h4rhJ3e0d + EDfROPtVfBSViS5UCh7UNut8Q3kbwwZBIa1NEN9vPUIBhH/ZvKr3a7188y3n1GY8 + paSVdYmGZYDSyK7ugztEOFWqekiA7gfLdyeCto12K10CAwEAAaNQME4wDAYDVR0T + BAUwAwEB/zAdBgNVHQ4EFgQUJDYGHNJmNdoV9S/T4ZLv/ze+JYIwHwYDVR0jBBgw + FoAUqV/rN9mEwnTBN+y4Di3aLz4BKj8wDQYJKoZIhvcNAQEFBQADggEBAC63dW7v + 5J1Yf7ue2ybTfIYVFAN1LOY4Ge+zLai2wkhRjaOqzV67HB/e1zItBbq0M1NkA4DQ + DM/aEoave5aMoZtR77JUrFG2KLnTqJZb3AZDWi3qsdYNo1yW0YMgGBVq8pThJ4NH + +QV5MdgkMZjDUJArtU0Z6eD7br0BiA4uEx4irr0j8e5oInBbMPb4Orv05yuaXc9n + utPIm7iudKcNsHs+16ACAo0KdU38GnwgGW83B0LB0sCVwFMH1OpC435dXLDycvg+ + Pe5VvXxCL6guFtZtBbnAAtRreTC3bhS+bnxLyj+Hk7oAYyaW441BnzPcVWYeAf56 + 89A9e6HCmXEY1bo= + + + + + MIIDZzCCAk+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDTALBgNVBAsTBENBIDIxGjAYBgkqhkiG9w0B + CQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDEyMDEyNVoXDTIyMDkxMjEyMDEyNVow + TjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQLEwRD + QSAzMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBALxWxIfonRRiiS+mylDJdep1uyNqeq6LkfLZjJHdrgBB + oBi9TB2l4BSHND5jxvyFKpvCDEebx4ye+eWTNdzL+JRP/fstNhM4hb6Ikxjko4nK + DsJHkzKH7pV0B6BfTeWTWyO2Lu2hmfkYHYRzXTH0dxTBe9PibHLNoZYTk6aA3rH/ + q+Wqs+G1adKg9JJ98iCqzcP4dw/6C+EFI1irADu3UB02WXn5LW3r4j3s683EHbg1 + LVEpYtN/12lMXzPN26D9+AfoW1pCma88K0W4tYMERxTU+TJgZP4QnTO8obANlJKJ + NT3NCoFfc5A93hdcz5LZI0toqhf4NVRCYFo8PSwcTyUCAwEAAaNQME4wDAYDVR0T + BAUwAwEB/zAdBgNVHQ4EFgQUuAqclcUU2JuYKrI5EBrP7vlheJswHwYDVR0jBBgw + FoAUJDYGHNJmNdoV9S/T4ZLv/ze+JYIwDQYJKoZIhvcNAQEFBQADggEBAHmyfjiQ + mkjnXxC/Z350Re99WUHqmaSdWoK96yCkeAJrTAe57KV99/ekTGCAeXkicFUothgp + eEZ/TGEdtrcl/dKma7XKYc7OcUzxWlA4YM6XkS8ewYue9+Ve+ia1tLEQua62Z/zk + GUf+jnHFaVK34jNUdN1FpCJjj3CdLJ3TIkWvQ55pAkc6yXUp3rR0zRjpX/Mcz+Ca + 8+pBGcKD9DWQQTI7ZMEqOvClDGEFF2TM6Ye0vN4uM/Ye7xyogFGFt9XCBKUi2XPM + uk/rtVp9PsdYPCM92EN77lA0iMR5+qvVp1Q17OuF+tEHHI3jaGzchYkkMhmBtVpb + 1Z2YSB+hTVhscCU= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + + Test TSP + http://www.foo.bar + MIICwjCCAaqgAwIBAgIIb+RPNmkfCdYwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTI5MTE1MzA2WhcNMTQxMTI5MTE1MzA2WjAVMRMwEQYDVQQDDAp0aW1l + c3RhbXAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCb55NVDtHzs91sflX3 + fatZWUS69rxkxDMpcGo6doJ7YaKrCMr3BZ3ZlDTfCdEosWocTcYXdm3CO8BXlZvh + kvKyHN/hr0UzD0T8j8mBYoq3fGjTVTJOIG2yTsyT/3z3dpcMyGMWwsiqOd9TTtI8 + DcR2cOvQzlLiV9hz/kB9iLJeSQIDAQABo3gwdjAdBgNVHQ4EFgQUbdmtvKHCe0+v + hKP+ZcVUjmf5w/AwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJl + OTE1ItBGGujSCTAOBgNVHQ8BAf8EBAMCBkAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH + AwgwDQYJKoZIhvcNAQEFBQADggEBAFJ3AJ4I4RTeMBWhN8RLPQdJzcd0VRp9FUyY + hnIkR679nXU+ZbIyaQNx3+hPIbhcOMKxlKGm0LcDnjHL4EuJ6Gb027vF7mSwFbcK + PM+L23x2QLvuVcUEjcbP3Kcm93XCSu3RI71JINM+WinjXke/COuFzhMWJcLYj7S5 + dGR53ya0NnSf7dlua5FLBRiOFA5kRWTft6RcEW0jGZzscL6wZn+hH99IihjqgdxV + 1GydL+BgDMfryZzhl+h1WtTwv0Bi5Gs81v8UlNUTnCCfLu9fatHx85/ttFcXEyt9 + SQze3NGcaR1i3kyZvNijzG3C+jrUnJ/lFs5AcIiPG0Emz6oZEYs= + + + + + BUSINESS + 1 + + producer + Experimental producer + + + + + BUSINESS + 1 + + consumer + Experimental consumer + + + + + BUSINESS + 1 + + foo + Org with no address + + foosubsystem + + + + + producerId + producerServerCode +
127.0.0.1
+ + BnAMEvOVGDx3mIT81J1MpV+khaplYX2lt12EknvsLJE= + consumerId + fooId + foosubsystemId +
+ + + consumerId + consumerServerCode +
https://www.foo.com/bar
+ mxwUY66bn81Nkvbmbgif0agWZgM= +
+ + + fooId + fooServerCode + GLx/0DiFv3V1I1Nbd04r3z0oUno= + producerId + + + + fooId + FooBarServerCode +
https://foo.bar.baz
+ S6j8iYRoUfcZEtUu/MPtToSYxLI= + fooId +
+ + + Test group + Description + + EE + BUSINESS + member1 + subsys + + + EE + BUSINESS + member2 + + + EE + BUSINESS + member3 + + + EE + BUSINESS + member4 + + + + + central1 + + EE + BUSINESS + foobar + bazservice + + + + + + BUSINESS + Business clients + + 42 + + +
diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/EE/shared-params.xml.metadata b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/shared-params.xml.metadata new file mode 100644 index 0000000000..f01fbe2dc5 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/EE/shared-params.xml.metadata @@ -0,0 +1 @@ +{"contentIdentifier":"SHARED-PARAMETERS","instanceIdentifier":"EE","expirationDate":"2124-05-20T17:42:55Z"} \ No newline at end of file diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/bar/shared-params.xml b/src/common/common-util/src/test/resources/globalconf_good_v3/bar/shared-params.xml new file mode 100644 index 0000000000..03524c4a62 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/bar/shared-params.xml @@ -0,0 +1,213 @@ + + + + bar + + +
cs0
+ MIICqTCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQ0FADAOMQwwCgYDVQQDDANOL0EwHhcNNzAwMTAxMDAwMDAwWhcNMzgwMTAxMDAwMDAwWjAOMQwwCgYDVQQDDANOL0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDe10ai/VApuFjG+cgVLaV18qOEor6il83v0ErKBVznkSEzhzfplPJbfbXVHCezUsZOtVypvS4VCKg3S9wDBJVHmLrTl8z43xHowSE2KhvBxP+boH+9wt4dWdkiM4vohzuDuqz2k7ly50LlaokY/hQfLZKqRAB4PyiA9H1dk9hri9kIckGZpKHxVmXD19pd1hbvRmEcxF0kEAP4oyQ8EaQpgoy4KiN60x6hV8+xZPUqf03eQgh5LXvpmXDtGT58zN43Om8L+dPCtKyK6dTTjNakv6tJxoZJ2yUnVWPZKH9B3nM79bToxA9SiCjg3i6rU8HJ8ih163Dh9upPwqpmdEqDAgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIGQDANBgkqhkiG9w0BAQ0FAAOCAQEAdgVRzoNWG7shsBV+r9I4dB/ghfnxZAcgag9qevG4YrzLEDHupGB7a0Rx4dKp7gxzSV+E82oFOTZMhQdcVinRrqZT1U8DeT1tgvRH6V24g8HCplDp3AuRWKlPFAWIpsyZ6n6oMIrS9uVCaTF4A8uFZ7GxgcByMP+9BwCNQAigFGJOZzwln60idlR8YmtVCn4oVfBVrH+JRNSfgosVqqZe3q/XHNJP4iVqPt7taYzwwdz2XW02p8lgYZ1MwhMbcZ7xqNjYA0U9yQbUc6/oZ54R5FIgNldINCAJaNRRjXVS+1nt6bRM9GtZoeC4vhFqxIpduQRYpMD2MaJqbwDgal2pmA== + + + + pki1 + + + MIIDUzCCAjugAwIBAgIIU1eWoysptjUwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwNjE0MTAwNDI5WhcNMjIwNjEyMTAwNDI5WjA3MREwDwYDVQQDDAhBZG1p + bkNBMTEVMBMGA1UECgwMRUpCQ0EgU2FtcGxlMQswCQYDVQQGEwJTRTCCASIwDQYJ + KoZIhvcNAQEBBQADggEPADCCAQoCggEBAILYKYehC6hsbPQnqBPWoatI8I7qZGow + 3otWO9pW8lMvjgNiE8Cl8oFQS+C3CaqSvHU+iXUVkIlHuAr6k30G/mm6JqU0zA2o + 2apt5HJFzkg/0/LvLbSB1S5e0VTRDhMncgJakEUJvHFL0aKtq1RigP9C7Zt5BdDy + RBuJiutvaFjSeJ2sCQrHDcrJ1uAtdidv3z3Zih9O8CnalNZFltFf7M8pm+O+HIbu + miA19kShJwvpcdC9fVPuwsF1Qbeo4SeKuDPU1KHq7ZP9Heh7P6eywxghkYC4yewj + Bu8COi1FJMGHt9OdD+rNa/GTZ7ULPFiCH8wwCTn+YUtFe5pFLkvCG7sCAwEAAaNj + MGEwHQYDVR0OBBYEFHctiS4Dtv340mU5MTUi0EYa6NIJMA8GA1UdEwEB/wQFMAMB + Af8wHwYDVR0jBBgwFoAUdy2JLgO2/fjSZTkxNSLQRhro0gkwDgYDVR0PAQH/BAQD + AgGGMA0GCSqGSIb3DQEBBQUAA4IBAQAnEhhOwvk2Goy+wRwZgQLkmv9QIzBwP+Bw + d45DQOJyPjVTukNoc5w1y1in7yR9T8Cv5Ba1ctAqclztwjhAYAhWcG/CSZ4RvX8z + ysbnthW6qhZGGz5KJATZhFYrIaNGqC9i0FfTe3PF3HaowqndnBFtwjV65mszTaTN + p94LKhLk1ARc/BidplsM1cBSoA9VWvTANI8alKuJxh1QG9TbEJul1BTzA/wItMVD + tganTDrQxmkP1NW7d+MsIB5AQHABaXWgjygcqoMlLjyH/0QOP13iyvMXQU4jtSla + TmGm9CaC/xRQ10YD7AHHvq1P2cvfbQaV3I5xUYF7aqwM93ZjmptI + + + http://127.0.0.1:8082/ocsp + + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + http://www.example.net/ocsp + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + + Test TSP + http://www.foo.bar + MIICwjCCAaqgAwIBAgIIb+RPNmkfCdYwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTI5MTE1MzA2WhcNMTQxMTI5MTE1MzA2WjAVMRMwEQYDVQQDDAp0aW1l + c3RhbXAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCb55NVDtHzs91sflX3 + fatZWUS69rxkxDMpcGo6doJ7YaKrCMr3BZ3ZlDTfCdEosWocTcYXdm3CO8BXlZvh + kvKyHN/hr0UzD0T8j8mBYoq3fGjTVTJOIG2yTsyT/3z3dpcMyGMWwsiqOd9TTtI8 + DcR2cOvQzlLiV9hz/kB9iLJeSQIDAQABo3gwdjAdBgNVHQ4EFgQUbdmtvKHCe0+v + hKP+ZcVUjmf5w/AwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJl + OTE1ItBGGujSCTAOBgNVHQ8BAf8EBAMCBkAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH + AwgwDQYJKoZIhvcNAQEFBQADggEBAFJ3AJ4I4RTeMBWhN8RLPQdJzcd0VRp9FUyY + hnIkR679nXU+ZbIyaQNx3+hPIbhcOMKxlKGm0LcDnjHL4EuJ6Gb027vF7mSwFbcK + PM+L23x2QLvuVcUEjcbP3Kcm93XCSu3RI71JINM+WinjXke/COuFzhMWJcLYj7S5 + dGR53ya0NnSf7dlua5FLBRiOFA5kRWTft6RcEW0jGZzscL6wZn+hH99IihjqgdxV + 1GydL+BgDMfryZzhl+h1WtTwv0Bi5Gs81v8UlNUTnCCfLu9fatHx85/ttFcXEyt9 + SQze3NGcaR1i3kyZvNijzG3C+jrUnJ/lFs5AcIiPG0Emz6oZEYs= + + + + + BUSINESS + 1 + + producer + Experimental producer + + + + + BUSINESS + 1 + + consumer + Experimental consumer + + + + + BUSINESS + 1 + + foo + Org with no address + + foosubsystem + + + + + producerId + producerServerCode +
127.0.0.1
+ + BnAMEvOVGDx3mIT81J1MpV+khaplYX2lt12EknvsLJE= + consumerId + fooId + foosubsystemId +
+ + + consumerId + consumerServerCode +
https://www.foo.com/bar
+ NS21xw8PH7goeyqkzhT9NdqXi9c= +
+ + + fooId + fooServerCode + 6C4LKxhNQ4fCr9g3CNTP6uuHLPc= + producerId + + + + fooId + FooBarServerCode +
https://foo.bar.baz
+ S6j8iYRoUfcZEtUu/MPtToSYxLI= + fooId +
+ + + Test group + Description + + EE + BUSINESS + member1 + subsys + + + EE + BUSINESS + member2 + + + EE + BUSINESS + member3 + + + EE + BUSINESS + member4 + + + + + central1 + + EE + BUSINESS + foobar + bazservice + + + + + + BUSINESS + Business clients + + 420 + + +
diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/bar/shared-params.xml.metadata b/src/common/common-util/src/test/resources/globalconf_good_v3/bar/shared-params.xml.metadata new file mode 100644 index 0000000000..12f1281268 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/bar/shared-params.xml.metadata @@ -0,0 +1 @@ +{"contentIdentifier":"SHARED-PARAMETERS","instanceIdentifier":"bar","expirationDate":"2124-05-20T17:42:55Z"} \ No newline at end of file diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/foo/private-params.xml b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/private-params.xml new file mode 100644 index 0000000000..8c4efd4701 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/private-params.xml @@ -0,0 +1,24 @@ + + + foo + + bar + + http://www.bar.com/conf + YmFyCg== + + + + http://mgmt.com:1234 + + + foo + fooclass + foocode + + + 123 + diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/foo/private-params.xml.metadata b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/private-params.xml.metadata new file mode 100644 index 0000000000..4afb68128f --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/private-params.xml.metadata @@ -0,0 +1 @@ +{"contentIdentifier":"PRIVATE-PARAMETERS","instanceIdentifier":"foo","expirationDate":"2124-05-20T17:42:55Z"} \ No newline at end of file diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/foo/shared-params.xml b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/shared-params.xml new file mode 100644 index 0000000000..2be3c63b81 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/shared-params.xml @@ -0,0 +1,414 @@ + + + + foo + + +
cs0
+ MIICqTCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQ0FADAOMQwwCgYDVQQDDANOL0EwHhcNNzAwMTAxMDAwMDAwWhcNMzgwMTAxMDAwMDAwWjAOMQwwCgYDVQQDDANOL0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDe10ai/VApuFjG+cgVLaV18qOEor6il83v0ErKBVznkSEzhzfplPJbfbXVHCezUsZOtVypvS4VCKg3S9wDBJVHmLrTl8z43xHowSE2KhvBxP+boH+9wt4dWdkiM4vohzuDuqz2k7ly50LlaokY/hQfLZKqRAB4PyiA9H1dk9hri9kIckGZpKHxVmXD19pd1hbvRmEcxF0kEAP4oyQ8EaQpgoy4KiN60x6hV8+xZPUqf03eQgh5LXvpmXDtGT58zN43Om8L+dPCtKyK6dTTjNakv6tJxoZJ2yUnVWPZKH9B3nM79bToxA9SiCjg3i6rU8HJ8ih163Dh9upPwqpmdEqDAgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIGQDANBgkqhkiG9w0BAQ0FAAOCAQEAdgVRzoNWG7shsBV+r9I4dB/ghfnxZAcgag9qevG4YrzLEDHupGB7a0Rx4dKp7gxzSV+E82oFOTZMhQdcVinRrqZT1U8DeT1tgvRH6V24g8HCplDp3AuRWKlPFAWIpsyZ6n6oMIrS9uVCaTF4A8uFZ7GxgcByMP+9BwCNQAigFGJOZzwln60idlR8YmtVCn4oVfBVrH+JRNSfgosVqqZe3q/XHNJP4iVqPt7taYzwwdz2XW02p8lgYZ1MwhMbcZ7xqNjYA0U9yQbUc6/oZ54R5FIgNldINCAJaNRRjXVS+1nt6bRM9GtZoeC4vhFqxIpduQRYpMD2MaJqbwDgal2pmA== + + + + pki2 + true + + + MIIDiDCCAnCgAwIBAgIIEVk07cr7+SMwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTE5MDkxODU2WhcNMTQxMTE5MDkxODU2WjATMREwDwYDVQQDDAhjb25z + dW1lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM64hfHPpteJYaUm + DJaEVQ+3yst6hNocO1Ax8Bu1Zk1MKkyOiayfwsnCDN5XpDSlFRx/+aP6x8PFte2D + YFPq+3aP1ymN/iBCJlp2vDukkD8TAMaewKJpdWZD8WFAUnncRPy1q8BcLehexieE + rTGlPLrgbW115FXur7YN8CHZPb0TyfELsXPPWK3i/YREhl4Xk7keI7z3qQnUQbJL + wIrkSLq07pt2ciVmmZxFJq3TpB9grw/mnCURLJ1yY14FWLZ+hPrYGnzlkTcfKB6c + JfBKWUxkB5+JRL3yFo4dySfdiZ8wsJh0cbqEHDW2UghQQ/hkbJnn4UmZrrHn95we + t5pZQAcCAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGGPGh0 + dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dlYi9z + dGF0dXMvb2NzcDAdBgNVHQ4EFgQUfbgfWLDuAcEKrjXT3/CdH4D/CEEwDAYDVR0T + AQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNVHQ8B + Af8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBADe8dzcmKMa6RHzrgRTmApBMBlHR + Vg2kRRJF4NdSUbxUotLxBCA5ZlXdqm5cb3m9XtcU45+mC9S1eLPO69ZuVe6K3zY8 + MSoKSfKzVkWEEtqEn/wHiqkb90qtAITjt4FkWo3mSufMzSpBkUrxasaqIYBloLKm + tYmuCfu1gS2euG0KDPfH+i0IBgCZLBeZzdU+H2qTXH734Y3CF3eYGJ3XP6RQzZaZ + vE8J5km9BgGS1wqIsuBwdy3Zt8yuq1kR02CQ/0BnfnUsqVIvZR61Nl0j6VK8RtUS + yoYV9OkEmN6OTK4J8F47fh8AZUeagLJ29t0KdlS9VR849VWHQqAzakOU1uk= + + + http://127.0.0.1:8082/ocsp + + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + http://www.example.net/ocsp + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + pki3 + false + + + MIIDiDCCAnCgAwIBAgIIVYNTWA8JcLwwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTE5MDkxNDIzWhcNMTQxMTE5MDkxNDIzWjATMREwDwYDVQQDDAhwcm9k + dWNlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALKNC381RiACCftv + ApBzk5HD5YHw0u9SOkwcIkn4cZ4eQWrlROnqHTpS9IVSBoOz6pjCx/FwxZTdpw0j + X+bRYpxnj11I2XKzHfhfa6BvL5VkaDtjGpOdSGMJUtrI6m9jFiYryEmYHWxPlL9V + pDK0KknevYm2BR23/xDHweBSZ7tkMENU1kXFWLunoBys+W0waR+Z8HH5WNuBLz8X + z2iz/6KQ5BoWSPJc9P5TXNOBB+5XyjBR2ogoAOtX53OJzu0wMgLpjuJGdfcpy1S9 + ukU27B21i2MfZ6Tjhu9oKrAIgcMWJaHJ/gRX6iX1vXlfhUTkE1ACSfvhZdntKLzN + TZGEcxsCAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGGPGh0 + dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dlYi9z + dGF0dXMvb2NzcDAdBgNVHQ4EFgQUUHtGmEl0Cuh/x/wj+UU5S7Wui48wDAYDVR0T + AQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNVHQ8B + Af8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACJqqey5Ywoegq+Rjo4v89AN78Ou + tKtRzQZtuCZP9+ZhY6ivCPK4F8Ne6qpWZb63OLORyQosDAvj6m0iCFMsUZS3nC0U + DR0VyP2WrOihBOFC4CA7H2X4l7pkSyMN73ZC6icXkbj9H0ix5/Bv3Ug64DK9SixG + RxMwLxouIzk7WvePQ6ywlhGvZRTXxhr0DwvfZnPXxHDPB2q+9pKzC9h2txG1tyD9 + ffohEC/LKdGrHSe6hnTRedQUN3hcMQqCTc5cHsaB8bh5EaHrib3RR0YsOhjAd6IC + ms33BZnfNWQuGVTXw74Eu/P1JkwR0ReO+XuxxMp3DW2epMfL44OHWTb6JGY= + + + http://127.0.0.1:8082/ocsp + + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + http://www.example.net/ocsp + MIIDizCCAnOgAwIBAgIIOmOWEyqjUj0wDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIwOTA2MTEzODMwWhcNMTQwOTA2MTEzODMwWjAWMRQwEgYDVQQDDAtPY3Nw + IFNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZTdnxNq1QM + ncmiInNUSpm02V72GNrMrvq2Q4Zz3Zr8zDKMdAiwdrjx9X+Zi5oTjiSUXRuHY5ZN + 9oeLO1cv9NV6OGk3MlrAzxquBfQUgnZMNLkPZW5SuLqlZpWf0vF7EvAVX20hxgMq + 7M26Fxt/B9W81/G/REnuHKJ+nxCAZi5Kd1hdGVTEIwkicqROiEfQUcycs0T5aZI7 + F5qFiZyo3AeRbWYyhEfe326cPaRaswo2WwcBjFYWibTCnNQuLgDL6qroL1T8soI6 + LzBaNao6Lm4YY1OwTPz/UEiJ3KIXoAjfxMlOUnznmeWYNPcJb5Z8fdtWpaZqjV3W + IMAZocNThb8CAwEAAaOBuzCBuDBYBggrBgEFBQcBAQRMMEowSAYIKwYBBQUHMAGG + PGh0dHA6Ly9pa3MyLXVidW50dS5jeWJlci5lZTo4MDgwL2VqYmNhL3B1YmxpY3dl + Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUI1mSgzcFjcBFmmjYwlc9Qm7yF/kwDAYD + VR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJlOTE1ItBGGujSCTAOBgNV + HQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBACRO2KTCVKQxYMlsMDkjT5Qj + zqW0wHNCsxieYv0qfDM1Z5ceW0c0KjJcKXESj7GXT7oNejwI4gZNgxIzemJ3xABH + dftk2WxLQBYJMKQ30EuisFKueqpxaLVkPAbt+XLxSrxaYePB9LTJ+rw3FtbiIbag + 3AH22TFUUUnaTGVF+OiHtthE1u7bnwsTqWXX4PI9I3KnSaIEE55mveNq2jHVWu4r + Myy2flOZMonYh3dw1gmSp2yWo1YDpN3olM0Li6Lnfvg1TZd71xZ6ZkKf+MoAs+pW + 2HaLh8hiYRXpgw3WVSBg6CPTLoU5xFb57BNL3qccVetmbpZgznHMYEBN4b4pyHk= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + pki4 + true + + + MIIDZzCCAk+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDTALBgNVBAsTBENBIDExGjAYBgkqhkiG9w0B + CQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDExNTk0MFoXDTIyMDkxMjExNTk0MFow + TjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQLEwRD + QSAyMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAM1Ex4Bh8zHU+wWyp2fm7U2dAqooUamE4hyLVrmNifvB + AjKT7gSMeTB2bxCE38BYfzvnbQCs82piQRC6iCgHE/Ywr1zz86Pa/OI36tBmCCjW + NDm/U6MAlwT7s+GL3bpty4aY4pLilQZbmyDsE2hsJ+R82GMBttRku3LMKKE/jyQI + 26gK9xhYPPF85cfv7hylekcr8fUeGFmxEULLWyFFwhR9pr7HPcKhJR/h4rhJ3e0d + EDfROPtVfBSViS5UCh7UNut8Q3kbwwZBIa1NEN9vPUIBhH/ZvKr3a7188y3n1GY8 + paSVdYmGZYDSyK7ugztEOFWqekiA7gfLdyeCto12K10CAwEAAaNQME4wDAYDVR0T + BAUwAwEB/zAdBgNVHQ4EFgQUJDYGHNJmNdoV9S/T4ZLv/ze+JYIwHwYDVR0jBBgw + FoAUqV/rN9mEwnTBN+y4Di3aLz4BKj8wDQYJKoZIhvcNAQEFBQADggEBAC63dW7v + 5J1Yf7ue2ybTfIYVFAN1LOY4Ge+zLai2wkhRjaOqzV67HB/e1zItBbq0M1NkA4DQ + DM/aEoave5aMoZtR77JUrFG2KLnTqJZb3AZDWi3qsdYNo1yW0YMgGBVq8pThJ4NH + +QV5MdgkMZjDUJArtU0Z6eD7br0BiA4uEx4irr0j8e5oInBbMPb4Orv05yuaXc9n + utPIm7iudKcNsHs+16ACAo0KdU38GnwgGW83B0LB0sCVwFMH1OpC435dXLDycvg+ + Pe5VvXxCL6guFtZtBbnAAtRreTC3bhS+bnxLyj+Hk7oAYyaW441BnzPcVWYeAf56 + 89A9e6HCmXEY1bo= + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + + pki5 with intermediate certs + true + + + MIIDdTCCAl2gAwIBAgIJAOuBNCIUm0gwMA0GCSqGSIb3DQEBBQUAMFExCzAJBgNV + BAYTAkVFMRQwEgYDVQQKEwtDeWJlcm5ldGljYTEQMA4GA1UECxMHUm9vdCBDQTEa + MBgGCSqGSIb3DQEJARYLYWFhQGJiYi5jY2MwHhcNMTIwOTE0MTE1NjM3WhcNMjIw + OTEyMTE1NjM3WjBRMQswCQYDVQQGEwJFRTEUMBIGA1UEChMLQ3liZXJuZXRpY2Ex + EDAOBgNVBAsTB1Jvb3QgQ0ExGjAYBgkqhkiG9w0BCQEWC2FhYUBiYmIuY2NjMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArnYuIDCNNqIZ/GH0THglNHoU + T8PCfH5HGeVadaQu5xJFg2hLfbCvJNDGDgOcGXlss8tZ51y80EGwJFAU1IajhELF + yRDhEUsBd7FzulMxMwMFwluoPB1u0XUsNmYunmdlBc6BERkrTQi8oRXO7psslbiU + 4LDqeIdP04RhySNnVRwfb3eBfGR7Gh/EbdFeB814gCpoM6nmK1XR2f3JdCTJxPyE + 7EppIDPBBmgpzq2TzHF3qzd1Qv5Xe0XSC6DnkTbzpxrCvalGqGrIYOsV5vtOFt+2 + Tlx+QHIWhvZ9bDdEGY58O0jWj3lO5VkFYsloauYa8trCm7w20J6QqwtCIskMvwID + AQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRSFYADqiIAKTGIT44uTLwS + hz1YZzAfBgNVHSMEGDAWgBRSFYADqiIAKTGIT44uTLwShz1YZzANBgkqhkiG9w0B + AQUFAAOCAQEAMn7YD7C3cjkQL0wm1v47KYda/Y05jR5zMwV648VHgPeNLRyZYWJr + pHdUQiAqKL3zhF8neOQO100fwUxSxLsuPNqkce02DwjMSMWi3bF9xX7MlrQnAb6a + SJ47YaPyZSvXlkzRC3dcDjcBIRSGNxsftISSEJJeqGWQz6b9LkIfxTjtcHbTnm/y + GPWpmr2blkm7qRKK4eFwvooJ6KqBmm8/J086VpDOc9qRy/ar3za6UdFEBDX2aHQD + 4OLgBvj0dLYCu3w32ltmVOgBoewIq5M1wBGp8dIs5Jrr4P9xYprRY1une3IWvviJ + NXoWm1enl1+N31r32YIc4vXZiA2L+cjlvQ== + + + + MIIDajCCAlKgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGjAYBgkqhkiG + 9w0BCQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDExNTY1OFoXDTIyMDkxMjExNTY1 + OFowTjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQL + EwRDQSAxMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcN + AQEBBQADggEPADCCAQoCggEBAOnguIBD8dfb4vM73WKR+T2zWKAbFeUu7Wcpio/2 + CDLJZ3mF2Zo+JWOk8nYSUrZkFpCvH+S5Mhj0Eo4LcCk2PTiRP2fPPABIQmEXgLKU + gcqH132fVCyPRKdL+hG+CA7yzDOIO0h8ME/nQBuEJHc+ayGSyKG5/PfsETfseD0f + 9QoaAXsrztkhH+yNX+JgaPAyxQqFB8p8PLX3DrkD1JtslSjMJTuitVsf4JKb9zmI + /lGaMGqkq5ss3c1weF8s38+Zt8rU4FHS+DvFTVJVMHjnTu/emgiRiLJWXioKmijy + glMoZvpahgtOieS50Vgn8V+ttL4kLYSBFlAVkNOa0Fbz8eMCAwEAAaNQME4wDAYD + VR0TBAUwAwEB/zAdBgNVHQ4EFgQUqV/rN9mEwnTBN+y4Di3aLz4BKj8wHwYDVR0j + BBgwFoAUUhWAA6oiACkxiE+OLky8Eoc9WGcwDQYJKoZIhvcNAQEFBQADggEBAKBk + ++HBiGxSqDQUVWRjrD/5uBk/RH9oH2C/ZXYUyFCjAvmUWa+dWFyJScyVcZpchnbO + SUPKtFR78N3nJp01mbWyvzws4C+DbwPOdwPJHNKqwybn4uz1oWDoNioi1ITkjlYo + haDs9uVI9sLrApqQnSgL7Oc4yG2TSoa0YkLmdICHxH9TCK0NEUxW6Sa4aehftLD/ + 7gNORIe8YT9MqPGWDW6Za9f74Vx+H5/ejRkTKUA6jHTLmZCly4L2f+tpDIs22omd + 0X3Ct9os/XA7ZbbwiMuqAiiXKVGerTmeCrkWcixDkN9ATCI0ur5NZniSVnXGjV6m + u3cl4oYr+u2NJVPDgKI= + + + + + MIIDZzCCAk+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDTALBgNVBAsTBENBIDExGjAYBgkqhkiG9w0B + CQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDExNTk0MFoXDTIyMDkxMjExNTk0MFow + TjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQLEwRD + QSAyMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAM1Ex4Bh8zHU+wWyp2fm7U2dAqooUamE4hyLVrmNifvB + AjKT7gSMeTB2bxCE38BYfzvnbQCs82piQRC6iCgHE/Ywr1zz86Pa/OI36tBmCCjW + NDm/U6MAlwT7s+GL3bpty4aY4pLilQZbmyDsE2hsJ+R82GMBttRku3LMKKE/jyQI + 26gK9xhYPPF85cfv7hylekcr8fUeGFmxEULLWyFFwhR9pr7HPcKhJR/h4rhJ3e0d + EDfROPtVfBSViS5UCh7UNut8Q3kbwwZBIa1NEN9vPUIBhH/ZvKr3a7188y3n1GY8 + paSVdYmGZYDSyK7ugztEOFWqekiA7gfLdyeCto12K10CAwEAAaNQME4wDAYDVR0T + BAUwAwEB/zAdBgNVHQ4EFgQUJDYGHNJmNdoV9S/T4ZLv/ze+JYIwHwYDVR0jBBgw + FoAUqV/rN9mEwnTBN+y4Di3aLz4BKj8wDQYJKoZIhvcNAQEFBQADggEBAC63dW7v + 5J1Yf7ue2ybTfIYVFAN1LOY4Ge+zLai2wkhRjaOqzV67HB/e1zItBbq0M1NkA4DQ + DM/aEoave5aMoZtR77JUrFG2KLnTqJZb3AZDWi3qsdYNo1yW0YMgGBVq8pThJ4NH + +QV5MdgkMZjDUJArtU0Z6eD7br0BiA4uEx4irr0j8e5oInBbMPb4Orv05yuaXc9n + utPIm7iudKcNsHs+16ACAo0KdU38GnwgGW83B0LB0sCVwFMH1OpC435dXLDycvg+ + Pe5VvXxCL6guFtZtBbnAAtRreTC3bhS+bnxLyj+Hk7oAYyaW441BnzPcVWYeAf56 + 89A9e6HCmXEY1bo= + + + + + MIIDZzCCAk+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJFRTEU + MBIGA1UEChMLQ3liZXJuZXRpY2ExDTALBgNVBAsTBENBIDIxGjAYBgkqhkiG9w0B + CQEWC2FhYUBiYmIuY2NjMB4XDTEyMDkxNDEyMDEyNVoXDTIyMDkxMjEyMDEyNVow + TjELMAkGA1UEBhMCRUUxFDASBgNVBAoTC0N5YmVybmV0aWNhMQ0wCwYDVQQLEwRD + QSAzMRowGAYJKoZIhvcNAQkBFgthYWFAYmJiLmNjYzCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBALxWxIfonRRiiS+mylDJdep1uyNqeq6LkfLZjJHdrgBB + oBi9TB2l4BSHND5jxvyFKpvCDEebx4ye+eWTNdzL+JRP/fstNhM4hb6Ikxjko4nK + DsJHkzKH7pV0B6BfTeWTWyO2Lu2hmfkYHYRzXTH0dxTBe9PibHLNoZYTk6aA3rH/ + q+Wqs+G1adKg9JJ98iCqzcP4dw/6C+EFI1irADu3UB02WXn5LW3r4j3s683EHbg1 + LVEpYtN/12lMXzPN26D9+AfoW1pCma88K0W4tYMERxTU+TJgZP4QnTO8obANlJKJ + NT3NCoFfc5A93hdcz5LZI0toqhf4NVRCYFo8PSwcTyUCAwEAAaNQME4wDAYDVR0T + BAUwAwEB/zAdBgNVHQ4EFgQUuAqclcUU2JuYKrI5EBrP7vlheJswHwYDVR0jBBgw + FoAUJDYGHNJmNdoV9S/T4ZLv/ze+JYIwDQYJKoZIhvcNAQEFBQADggEBAHmyfjiQ + mkjnXxC/Z350Re99WUHqmaSdWoK96yCkeAJrTAe57KV99/ekTGCAeXkicFUothgp + eEZ/TGEdtrcl/dKma7XKYc7OcUzxWlA4YM6XkS8ewYue9+Ve+ia1tLEQua62Z/zk + GUf+jnHFaVK34jNUdN1FpCJjj3CdLJ3TIkWvQ55pAkc6yXUp3rR0zRjpX/Mcz+Ca + 8+pBGcKD9DWQQTI7ZMEqOvClDGEFF2TM6Ye0vN4uM/Ye7xyogFGFt9XCBKUi2XPM + uk/rtVp9PsdYPCM92EN77lA0iMR5+qvVp1Q17OuF+tEHHI3jaGzchYkkMhmBtVpb + 1Z2YSB+hTVhscCU= + + + ee.ria.xroad.common.certificateprofile.impl.TestCertificateProfileInfoProvider + + + + Test TSP + http://www.foo.bar + MIICwjCCAaqgAwIBAgIIb+RPNmkfCdYwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE + AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw + HhcNMTIxMTI5MTE1MzA2WhcNMTQxMTI5MTE1MzA2WjAVMRMwEQYDVQQDDAp0aW1l + c3RhbXAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCb55NVDtHzs91sflX3 + fatZWUS69rxkxDMpcGo6doJ7YaKrCMr3BZ3ZlDTfCdEosWocTcYXdm3CO8BXlZvh + kvKyHN/hr0UzD0T8j8mBYoq3fGjTVTJOIG2yTsyT/3z3dpcMyGMWwsiqOd9TTtI8 + DcR2cOvQzlLiV9hz/kB9iLJeSQIDAQABo3gwdjAdBgNVHQ4EFgQUbdmtvKHCe0+v + hKP+ZcVUjmf5w/AwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBR3LYkuA7b9+NJl + OTE1ItBGGujSCTAOBgNVHQ8BAf8EBAMCBkAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH + AwgwDQYJKoZIhvcNAQEFBQADggEBAFJ3AJ4I4RTeMBWhN8RLPQdJzcd0VRp9FUyY + hnIkR679nXU+ZbIyaQNx3+hPIbhcOMKxlKGm0LcDnjHL4EuJ6Gb027vF7mSwFbcK + PM+L23x2QLvuVcUEjcbP3Kcm93XCSu3RI71JINM+WinjXke/COuFzhMWJcLYj7S5 + dGR53ya0NnSf7dlua5FLBRiOFA5kRWTft6RcEW0jGZzscL6wZn+hH99IihjqgdxV + 1GydL+BgDMfryZzhl+h1WtTwv0Bi5Gs81v8UlNUTnCCfLu9fatHx85/ttFcXEyt9 + SQze3NGcaR1i3kyZvNijzG3C+jrUnJ/lFs5AcIiPG0Emz6oZEYs= + + + + + BUSINESS + 1 + + producer + Experimental producer + + + + + BUSINESS + 1 + + consumer + Experimental consumer + + + + + BUSINESS + 1 + + foo + Org with no address + + foosubsystem + + + + + producerId + producerServerCode +
127.0.0.1
+ + BnAMEvOVGDx3mIT81J1MpV+khaplYX2lt12EknvsLJE= + consumerId + fooId + foosubsystemId +
+ + + consumerId + consumerServerCode +
https://www.foo.com/bar
+ NS21xw8PH7goeyqkzhT9NdqXi9c= +
+ + + fooId + fooServerCode + 6C4LKxhNQ4fCr9g3CNTP6uuHLPc= + producerId + + + + fooId + FooBarServerCode +
https://foo.bar.baz
+ S6j8iYRoUfcZEtUu/MPtToSYxLI= + fooId +
+ + + Test group + Description + + EE + BUSINESS + member1 + subsys + + + EE + BUSINESS + member2 + + + EE + BUSINESS + member3 + + + EE + BUSINESS + member4 + + + + + central1 + + EE + BUSINESS + foobar + bazservice + + + + + + BUSINESS + Business clients + + 4200 + + +
diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/foo/shared-params.xml.metadata b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/shared-params.xml.metadata new file mode 100644 index 0000000000..1c98cdba39 --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/foo/shared-params.xml.metadata @@ -0,0 +1 @@ +{"contentIdentifier":"SHARED-PARAMETERS","instanceIdentifier":"foo","expirationDate":"2124-05-20T17:42:55Z"} \ No newline at end of file diff --git a/src/common/common-util/src/test/resources/globalconf_good_v3/instance-identifier b/src/common/common-util/src/test/resources/globalconf_good_v3/instance-identifier new file mode 100644 index 0000000000..5ac9344fbc --- /dev/null +++ b/src/common/common-util/src/test/resources/globalconf_good_v3/instance-identifier @@ -0,0 +1 @@ +EE \ No newline at end of file diff --git a/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConf.java b/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConf.java index 7aaff938db..62c8a91756 100644 --- a/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConf.java +++ b/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConf.java @@ -30,7 +30,6 @@ import ee.ria.xroad.common.cert.CertChain; import ee.ria.xroad.common.certificateprofile.AuthCertificateProfileInfo; import ee.ria.xroad.common.certificateprofile.SignCertificateProfileInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -484,18 +483,18 @@ public static ClientId.Conf getSubjectName( * @param instanceIdentifier the instance identifier * @return all approved TSPs for the given instance identifier */ - public static List getApprovedTsps(String instanceIdentifier) { + public static List getApprovedTspUrls(String instanceIdentifier) { log.trace("getApprovedTsps({})", instanceIdentifier); - return getInstance().getApprovedTsps(instanceIdentifier); + return getInstance().getApprovedTspUrls(instanceIdentifier); } /** * @param instanceIdentifier the instance identifier * @return all approved TSP types for the given instance identifier */ - public static List getApprovedTspTypes(String instanceIdentifier) { - return getInstance().getApprovedTspTypes(instanceIdentifier); + public static List getApprovedTsps(String instanceIdentifier) { + return getInstance().getApprovedTsps(instanceIdentifier); } /** diff --git a/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfImpl.java b/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfImpl.java index 20e05df924..a01272047e 100644 --- a/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfImpl.java +++ b/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfImpl.java @@ -31,14 +31,6 @@ import ee.ria.xroad.common.certificateprofile.CertificateProfileInfoProvider; import ee.ria.xroad.common.certificateprofile.GetCertificateProfile; import ee.ria.xroad.common.certificateprofile.SignCertificateProfileInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedCATypeV2; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.GlobalGroupType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.MemberClassType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.MemberType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.OcspInfoType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SecurityServerType; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.SubsystemType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -51,6 +43,8 @@ import org.apache.commons.lang3.StringUtils; import org.bouncycastle.cert.X509CertificateHolder; +import java.io.IOException; +import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.time.OffsetDateTime; import java.util.ArrayList; @@ -77,11 +71,11 @@ @Slf4j public class GlobalConfImpl implements GlobalConfProvider { - private volatile ConfigurationDirectoryV2 confDir; + private volatile VersionableConfigurationDirectory confDir; GlobalConfImpl() { try { - confDir = new ConfigurationDirectoryV2(getConfigurationPath()); + initConfDir(); } catch (Exception e) { throw translateWithPrefix(X_MALFORMED_GLOBALCONF, e); } @@ -89,11 +83,31 @@ public class GlobalConfImpl implements GlobalConfProvider { @Override public void reload() { - ConfigurationDirectoryV2 original = confDir; + VersionableConfigurationDirectory original = confDir; try { - confDir = new ConfigurationDirectoryV2(getConfigurationPath(), original); + if (original instanceof ConfigurationDirectoryV3 configurationdirectoryv3) { + confDir = new ConfigurationDirectoryV3(getConfigurationPath(), configurationdirectoryv3); + } else { + confDir = new ConfigurationDirectoryV2(getConfigurationPath(), (ConfigurationDirectoryV2) original); + } } catch (Exception e) { - throw translateWithPrefix(X_MALFORMED_GLOBALCONF, e); + log.warn("Error reloading global configuration, trying to reinitialize", e); + try { + initConfDir(); + } catch (Exception ex) { + throw translateWithPrefix(X_MALFORMED_GLOBALCONF, ex); + } + } + } + + private void initConfDir() throws Exception { + try { + confDir = new ConfigurationDirectoryV3(getConfigurationPath()); + log.info("Successfully initialized global configuration V3"); + } catch (Exception e) { + log.warn("Error reading underlying global configuration as V3, defaulting back to V2", e); + confDir = new ConfigurationDirectoryV2(getConfigurationPath()); + log.info("Successfully initialized global configuration V2"); } } @@ -101,16 +115,16 @@ public void reload() { @Override public boolean isValid() { // it is important to get handle of confDir as this variable is volatile - ConfigurationDirectoryV2 checkDir = confDir; + VersionableConfigurationDirectory checkDir = confDir; String mainInstance = checkDir.getInstanceIdentifier(); OffsetDateTime now = TimeUtils.offsetDateTimeNow(); try { - if (now.isAfter(checkDir.getPrivate(mainInstance).getExpiresOn())) { - log.warn("Main privateParameters expired at {}", checkDir.getPrivate(mainInstance).getExpiresOn()); + if (now.isAfter(checkDir.getPrivateExpiresOn(mainInstance))) { + log.warn("Main privateParameters expired at {}", checkDir.getPrivateExpiresOn(mainInstance)); return false; } - if (now.isAfter(checkDir.getShared(mainInstance).getExpiresOn())) { - log.warn("Main sharedParameters expired at {}", checkDir.getShared(mainInstance).getExpiresOn()); + if (now.isAfter(checkDir.getSharedExpiresOn(mainInstance))) { + log.warn("Main sharedParameters expired at {}", checkDir.getSharedExpiresOn(mainInstance)); return false; } return true; @@ -129,7 +143,7 @@ public String getInstanceIdentifier() { @Override public List getInstanceIdentifiers() { return getSharedParameters().stream() - .map(SharedParametersV2::getInstanceIdentifier) + .map(SharedParameters::getInstanceIdentifier) .collect(Collectors.toList()); } @@ -138,13 +152,12 @@ public List getSecurityServers( String... instanceIdentifiers) { List serverIds = new ArrayList<>(); - for (SharedParametersV2 p : getSharedParameters(instanceIdentifiers)) { - for (SecurityServerType s : p.getSecurityServers()) { - MemberType owner = SharedParametersV2.getOwner(s); + for (SharedParameters p : getSharedParameters(instanceIdentifiers)) { + for (SharedParameters.SecurityServer s : p.getSecurityServers()) { serverIds.add(SecurityServerId.Conf.create( - p.getInstanceIdentifier(), - owner.getMemberClass().getCode(), - owner.getMemberCode(), s.getServerCode())); + p.getInstanceIdentifier(), s.getOwner().getMemberClass(), + s.getOwner().getMemberCode(), s.getServerCode()) + ); } } @@ -155,14 +168,12 @@ public List getSecurityServers( public List getMembers(String... instanceIdentifiers) { List clients = new ArrayList<>(); - for (SharedParametersV2 p : getSharedParameters(instanceIdentifiers)) { - for (MemberType member : p.getMembers()) { - clients.add(new MemberInfo(p.createMemberId(member), member - .getName())); + for (SharedParameters p : getSharedParameters(instanceIdentifiers)) { + for (SharedParameters.Member member : p.getMembers()) { + clients.add(new MemberInfo(createMemberId(p, member), member.getName())); - for (SubsystemType subsystem : member.getSubsystem()) { - clients.add(new MemberInfo(p.createSubsystemId(member, - subsystem), member.getName())); + for (SharedParameters.Subsystem subsystem : member.getSubsystems()) { + clients.add(new MemberInfo(createSubsystemId(p, member, subsystem), member.getName())); } } } @@ -170,9 +181,20 @@ public List getMembers(String... instanceIdentifiers) { return clients; } + ClientId.Conf createMemberId(SharedParameters p, SharedParameters.Member member) { + return ClientId.Conf.create(p.getInstanceIdentifier(), member.getMemberClass().getCode(), member.getMemberCode()); + } + + ClientId.Conf createSubsystemId(SharedParameters p, SharedParameters.Member member, SharedParameters.Subsystem subsystem) { + return ClientId.Conf.create( + p.getInstanceIdentifier(), member.getMemberClass().getCode(), + member.getMemberCode(), subsystem.getSubsystemCode() + ); + } + @Override public String getMemberName(ClientId clientId) { - SharedParametersV2 p; + SharedParameters p; try { p = confDir.getShared(clientId.getXRoadInstance()); } catch (Exception e) { @@ -180,31 +202,32 @@ public String getMemberName(ClientId clientId) { } return p == null ? null : p.getMembers().stream() - .filter(m -> p.createMemberId(m).memberEquals(clientId)) - .map(MemberType::getName) + .filter(m -> createMemberId(p, m).memberEquals(clientId)) + .map(SharedParameters.Member::getName) .findFirst() .orElse(null); } @Override - public List getGlobalGroups( - String... instanceIdentifiers) { + public List getGlobalGroups(String... instanceIdentifiers) { List globalGroups = new ArrayList<>(); - - for (SharedParametersV2 p : getSharedParameters(instanceIdentifiers)) { - for (GlobalGroupType globalGroup : p.getGlobalGroups()) { + for (SharedParameters p : getSharedParameters(instanceIdentifiers)) { + for (SharedParameters.GlobalGroup globalGroup : p.getGlobalGroups()) { globalGroups.add( - new GlobalGroupInfo(p.createGlobalGroupId(globalGroup), - globalGroup.getDescription())); + new GlobalGroupInfo(createGlobalGroupId(globalGroup, p), globalGroup.getDescription()) + ); } } - return globalGroups; } + GlobalGroupId.Conf createGlobalGroupId(SharedParameters.GlobalGroup globalGroup, SharedParameters p) { + return GlobalGroupId.Conf.create(p.getInstanceIdentifier(), globalGroup.getGroupCode()); + } + @Override public String getGlobalGroupDescription(GlobalGroupId globalGroupId) { - SharedParametersV2 p; + SharedParameters p; try { p = confDir.getShared(globalGroupId.getXRoadInstance()); } catch (Exception e) { @@ -212,17 +235,16 @@ public String getGlobalGroupDescription(GlobalGroupId globalGroupId) { } return p == null ? null : p.getGlobalGroups().stream() - .filter(g -> g.getGroupCode().equals( - globalGroupId.getGroupCode())) - .map(GlobalGroupType::getDescription) + .filter(g -> g.getGroupCode().equals(globalGroupId.getGroupCode())) + .map(SharedParameters.GlobalGroup::getDescription) .findFirst().orElse(null); } @Override public Set getMemberClasses(String... instanceIdentifiers) { return getSharedParameters(instanceIdentifiers).stream() - .flatMap(p -> p.getGlobalSettings().getMemberClass().stream()) - .map(MemberClassType::getCode) + .flatMap(p -> p.getGlobalSettings().getMemberClasses().stream()) + .map(SharedParameters.MemberClass::getCode) .collect(Collectors.toSet()); } @@ -232,7 +254,7 @@ public Collection getProviderAddress(ClientId clientId) { return null; } - SharedParametersV2 p = getSharedParameters(clientId.getXRoadInstance()); + SharedParameters p = getSharedParameters(clientId.getXRoadInstance()); return p.getMemberAddresses().get(clientId); } @@ -242,10 +264,10 @@ public String getSecurityServerAddress(SecurityServerId serverId) { return null; } - SharedParametersV2 p = getSharedParameters(serverId.getXRoadInstance()); - final SecurityServerType serverType = p.getSecurityServersById().get(serverId); - if (serverType != null) { - return serverType.getAddress(); + SharedParameters p = getSharedParameters(serverId.getXRoadInstance()); + final SharedParameters.SecurityServer server = p.getSecurityServersById().get(serverId); + if (server != null) { + return server.getAddress(); } return null; @@ -260,8 +282,8 @@ private List doGetOcspResponderAddressesForCertificate(X509Certificate c throws Exception { List responders = new ArrayList<>(); - for (SharedParametersV2 p : getSharedParameters()) { - List caOcspData = null; + for (SharedParameters p : getSharedParameters()) { + List caOcspData = null; X509Certificate caCert; try { if (!certificateIsCA) { @@ -276,7 +298,7 @@ private List doGetOcspResponderAddressesForCertificate(X509Certificate c if (caOcspData == null) { continue; } - caOcspData.stream().map(OcspInfoType::getUrl) + caOcspData.stream().map(SharedParameters.OcspInfo::getUrl) .filter(StringUtils::isNotBlank) .map(String::trim) .forEach(responders::add); @@ -300,10 +322,10 @@ public List getOcspResponderAddressesForCaCertificate(X509Certificate ca public List getOcspResponderCertificates() { List responderCerts = new ArrayList<>(); try { - for (SharedParametersV2 p : getSharedParameters()) { - for (List ocspTypes - : p.getCaCertsAndOcspData().values()) { - ocspTypes.stream().map(OcspInfoType::getCert) + for (SharedParameters p : getSharedParameters()) { + for (List ocsps : p.getCaCertsAndOcspData().values()) { + ocsps.stream() + .map(SharedParameters.OcspInfo::getCert) .filter(Objects::nonNull) .map(CryptoUtils::readCertificate) .forEach(responderCerts::add); @@ -358,27 +380,36 @@ public List getAllCaCerts(String instanceIdentifier) { public CertChain getCertChain(String instanceIdentifier, X509Certificate subject) throws Exception { if (subject == null) { - throw new IllegalArgumentException( - "Member certificate must be present to find cert chain!"); + throw new IllegalArgumentException("Member certificate must be present to find cert chain!"); } List chain = new ArrayList<>(); chain.add(subject); - SharedParametersV2 p = getSharedParameters(instanceIdentifier); + SharedParameters sharedParams = getSharedParameters(instanceIdentifier); - X509Certificate ca = p.getCaCertForSubject(subject); + X509Certificate ca = getCaCertForSubject(subject, sharedParams); while (ca != null) { chain.add(ca); - ca = p.getCaCertForSubject(ca); + ca = getCaCertForSubject(ca, sharedParams); + } + + if (chain.size() < 2) { // did not find any CA certs + return null; } - if (chain.size() < 2) { // did not found any CA certs + return CertChain.create(instanceIdentifier, chain.toArray(new X509Certificate[chain.size()])); + } + + X509Certificate getCaCertForSubject(X509Certificate subject, SharedParameters sharedParameters) + throws CertificateEncodingException, IOException { + X509CertificateHolder certHolder = + new X509CertificateHolder(subject.getEncoded()); + if (certHolder.getSubject().equals(certHolder.getIssuer())) { return null; } - return CertChain.create(instanceIdentifier, - chain.toArray(new X509Certificate[chain.size()])); + return sharedParameters.getSubjectsAndCaCerts().get(certHolder.getIssuer()); } @Override @@ -386,11 +417,10 @@ public boolean isOcspResponderCert(X509Certificate ca, X509Certificate ocspCert) { return getSharedParameters().stream() .map(p -> p.getCaCertsAndOcspData().get(ca)) - .filter(Objects::nonNull).flatMap(o -> o.stream()) - .map(OcspInfoType::getCert).filter(Objects::nonNull) + .filter(Objects::nonNull).flatMap(Collection::stream) + .map(SharedParameters.OcspInfo::getCert).filter(Objects::nonNull) .map(CryptoUtils::readCertificate) - .filter(c -> c.equals(ocspCert)) - .findFirst().isPresent(); + .anyMatch(c -> c.equals(ocspCert)); } @Override @@ -408,14 +438,13 @@ public SecurityServerId.Conf getServerId(X509Certificate cert) throws Exception { String b64 = encodeBase64(certHash(cert)); - for (SharedParametersV2 p : getSharedParameters()) { - SecurityServerType serverType = p.getServerByAuthCert().get(b64); - if (serverType != null) { - MemberType owner = SharedParametersV2.getOwner(serverType); - return SecurityServerId.Conf.create(p.getInstanceIdentifier(), - owner.getMemberClass().getCode(), - owner.getMemberCode(), - serverType.getServerCode()); + for (SharedParameters p : getSharedParameters()) { + SharedParameters.SecurityServer server = p.getServerByAuthCert().get(b64); + if (server != null) { + return SecurityServerId.Conf.create( + p.getInstanceIdentifier(), server.getOwner().getMemberClass(), + server.getOwner().getMemberCode(), server.getServerCode() + ); } } @@ -423,12 +452,12 @@ public SecurityServerId.Conf getServerId(X509Certificate cert) } @Override - public ClientId.Conf getServerOwner(SecurityServerId serverId) { - for (SharedParametersV2 p : getSharedParameters()) { - SecurityServerType server = p.getSecurityServersById() + public ClientId getServerOwner(SecurityServerId serverId) { + for (SharedParameters p : getSharedParameters()) { + SharedParameters.SecurityServer server = p.getSecurityServersById() .get(serverId); if (server != null) { - return p.createMemberId((MemberType) server.getOwner()); + return server.getOwner(); } } @@ -450,14 +479,14 @@ public Collection getApprovedCAs( String instanceIdentifier) { return getSharedParameters(instanceIdentifier).getApprovedCAs() .stream() - .map(ca -> createApprovedCAInfo(ca)) + .map(this::createApprovedCAInfo) .collect(Collectors.toList()); } - private ApprovedCAInfo createApprovedCAInfo(ApprovedCATypeV2 ca) { + private ApprovedCAInfo createApprovedCAInfo(SharedParameters.ApprovedCA ca) { return new ApprovedCAInfo( ca.getName(), - ca.isAuthenticationOnly(), + ca.getAuthenticationOnly(), ca.getCertificateProfileInfo() ); } @@ -491,14 +520,14 @@ public SignCertificateProfileInfo getSignCertificateProfileInfo( } @Override - public List getApprovedTsps(String instanceIdentifier) { + public List getApprovedTspUrls(String instanceIdentifier) { return getSharedParameters(instanceIdentifier).getApprovedTSAs() - .stream().map(ApprovedTSAType::getUrl) + .stream().map(SharedParameters.ApprovedTSA::getUrl) .collect(Collectors.toList()); } @Override - public List getApprovedTspTypes(String instanceIdentifier) { + public List getApprovedTsps(String instanceIdentifier) { return getSharedParameters(instanceIdentifier).getApprovedTSAs(); } @@ -507,14 +536,14 @@ public String getApprovedTspName(String instanceIdentifier, String approvedTspUrl) { return getSharedParameters(instanceIdentifier).getApprovedTSAs() .stream().filter(t -> t.getUrl().equals(approvedTspUrl)) - .map(ApprovedTSAType::getName).findFirst().orElse(null); + .map(SharedParameters.ApprovedTSA::getName).findFirst().orElse(null); } @Override public List getTspCertificates() throws Exception { return getSharedParameters().stream() .flatMap(p -> p.getApprovedTSAs().stream()) - .map(ApprovedTSAType::getCert) + .map(SharedParameters.ApprovedTSA::getCert) .filter(Objects::nonNull) .map(CryptoUtils::readCertificate) .collect(Collectors.toList()); @@ -528,34 +557,26 @@ public Set getKnownAddresses() { } @Override - public boolean isSubjectInGlobalGroup(ClientId subjectId, - GlobalGroupId groupId) { - - SharedParametersV2 p; - try { - p = confDir.getShared(groupId.getXRoadInstance()); - } catch (Exception e) { - p = null; - log.warn("Got exception while getting shared parameters.", e); - } - - if (p == null) { - return false; - } + public boolean isSubjectInGlobalGroup(ClientId subjectId, GlobalGroupId groupId) { - GlobalGroupType group = p.findGlobalGroup(groupId); + SharedParameters.GlobalGroup group = findGlobalGroup(groupId); if (group == null) { return false; } - return group.getGroupMember().stream().filter(m -> m.equals(subjectId)) - .findFirst().isPresent(); + return group.getGroupMembers().stream().anyMatch(m -> m.equals(subjectId)); + } + + SharedParameters.GlobalGroup findGlobalGroup(GlobalGroupId groupId) { + return getSharedParameters(groupId.getXRoadInstance()).getGlobalGroups().stream() + .filter(g -> g.getGroupCode().equals(groupId.getGroupCode())) + .findFirst().orElse(null); } @Override public boolean isSecurityServerClient(ClientId clientId, SecurityServerId securityServerId) { - SharedParametersV2 p = getSharedParameters(securityServerId + SharedParameters p = getSharedParameters(securityServerId .getXRoadInstance()); return p.getSecurityServerClients().containsKey(securityServerId) && p.getSecurityServerClients().get(securityServerId) @@ -564,7 +585,7 @@ public boolean isSecurityServerClient(ClientId clientId, @Override public boolean existsSecurityServer(SecurityServerId securityServerId) { - SharedParametersV2 p = getSharedParameters(securityServerId + SharedParameters p = getSharedParameters(securityServerId .getXRoadInstance()); return p.getSecurityServersById().containsKey(securityServerId); @@ -610,8 +631,8 @@ public int getTimestampingIntervalSeconds() { // ------------------------------------------------------------------------ - protected PrivateParametersV2 getPrivateParameters() { - PrivateParametersV2 p; + protected PrivateParameters getPrivateParameters() { + PrivateParameters p; try { p = confDir.getPrivate(getInstanceIdentifier()); } catch (Exception e) { @@ -627,8 +648,8 @@ protected PrivateParametersV2 getPrivateParameters() { return p; } - protected SharedParametersV2 getSharedParameters(String instanceIdentifier) { - SharedParametersV2 p; + protected SharedParameters getSharedParameters(String instanceIdentifier) { + SharedParameters p; try { p = confDir.getShared(instanceIdentifier); } catch (Exception e) { @@ -643,7 +664,7 @@ protected SharedParametersV2 getSharedParameters(String instanceIdentifier) { return p; } - protected List getSharedParameters( + protected List getSharedParameters( String... instanceIdentifiers) { if (ArrayUtils.isEmpty(instanceIdentifiers)) { return confDir.getShared(); @@ -657,7 +678,7 @@ protected List getSharedParameters( private CertificateProfileInfoProvider getCertProfile( String instanceIdentifier, X509Certificate cert) throws Exception { X509Certificate caCert = getCaCert(instanceIdentifier, cert); - SharedParametersV2 p = getSharedParameters(instanceIdentifier); + SharedParameters p = getSharedParameters(instanceIdentifier); String certProfileProviderClass = p.getCaCertsAndCertProfiles().get(caCert); @@ -673,16 +694,16 @@ private CertificateProfileInfoProvider getCertProfile( @Override public ApprovedCAInfo getApprovedCA( String instanceIdentifier, X509Certificate cert) throws CodedException { - SharedParametersV2 p = getSharedParameters(instanceIdentifier); + SharedParameters p = getSharedParameters(instanceIdentifier); - ApprovedCATypeV2 approvedCAType = p.getCaCertsAndApprovedCAData().get(cert); - if (approvedCAType == null) { + SharedParameters.ApprovedCA approvedCA = p.getCaCertsAndApprovedCAData().get(cert); + if (approvedCA == null) { throw new CodedException(X_INTERNAL_ERROR, "Could not find approved CA info for certificate " + cert.getSubjectX500Principal().getName()); } - return createApprovedCAInfo(approvedCAType); + return createApprovedCAInfo(approvedCA); } } diff --git a/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfProvider.java b/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfProvider.java index 75542adf07..cc0c8ef59f 100644 --- a/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfProvider.java +++ b/src/common/common-verifier/src/main/java/ee/ria/xroad/common/conf/globalconf/GlobalConfProvider.java @@ -29,7 +29,6 @@ import ee.ria.xroad.common.cert.CertChain; import ee.ria.xroad.common.certificateprofile.AuthCertificateProfileInfo; import ee.ria.xroad.common.certificateprofile.SignCertificateProfileInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -196,7 +195,7 @@ CertChain getCertChain(String instanceIdentifier, X509Certificate subject) * @return the client id that owns the security server with the specified id * or null if the given id does not match an existing server */ - ClientId.Conf getServerOwner(SecurityServerId serverId); + ClientId getServerOwner(SecurityServerId serverId); /** * @param cert the certificate @@ -241,13 +240,13 @@ SignCertificateProfileInfo getSignCertificateProfileInfo( * @param instanceIdentifier the instance identifier * @return all approved TSPs for the given instance identifier */ - List getApprovedTsps(String instanceIdentifier); + List getApprovedTspUrls(String instanceIdentifier); /** * @param instanceIdentifier the instance identifier * @return all approved TSP types for the given instance identifier */ - List getApprovedTspTypes(String instanceIdentifier); + List getApprovedTsps(String instanceIdentifier); /** * @param instanceIdentifier the instance identifier diff --git a/src/common/common-verifier/src/test/java/ee/ria/xroad/common/conf/globalconf/GlobalConfTest.java b/src/common/common-verifier/src/test/java/ee/ria/xroad/common/conf/globalconf/GlobalConfTest.java index 4e5879bd57..2518fc721a 100644 --- a/src/common/common-verifier/src/test/java/ee/ria/xroad/common/conf/globalconf/GlobalConfTest.java +++ b/src/common/common-verifier/src/test/java/ee/ria/xroad/common/conf/globalconf/GlobalConfTest.java @@ -129,7 +129,7 @@ public void isValidConfiguration() { */ @Test public void getInstanceIdentifiers() { - assertEquals(Arrays.asList("EE", "bar", "foo"), GlobalConf.getInstanceIdentifiers()); + assertTrue(Arrays.asList("EE", "bar", "foo").containsAll(GlobalConf.getInstanceIdentifiers())); } /** diff --git a/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClient.java b/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClient.java index 8c3f15cdc8..063b5bca65 100644 --- a/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClient.java +++ b/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClient.java @@ -34,6 +34,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -50,13 +51,12 @@ class ConfigurationClient { private ConfigurationSource configurationAnchor; - ConfigurationClient(String globalConfigurationDir) { + ConfigurationClient(String globalConfigurationDir, int version) { this.globalConfigurationDir = globalConfigurationDir; - downloader = new ConfigurationDownloader(globalConfigurationDir); + downloader = new ConfigurationDownloader(globalConfigurationDir, version); } - ConfigurationClient(String globalConfigurationDir, ConfigurationDownloader downloader, - ConfigurationSource configurationAnchor) { + ConfigurationClient(String globalConfigurationDir, ConfigurationDownloader downloader, ConfigurationSource configurationAnchor) { this.globalConfigurationDir = globalConfigurationDir; this.downloader = downloader; this.configurationAnchor = configurationAnchor; @@ -72,21 +72,25 @@ synchronized void execute() throws Exception { } downloadConfigurationFromAnchor(); - PrivateParametersV2 privateParameters = loadPrivateParameters(); + List configurationSources = getConfigurationSources(); FederationConfigurationSourceFilter sourceFilter = new FederationConfigurationSourceFilterImpl(configurationAnchor.getInstanceIdentifier()); - deleteExtraConfigurationDirectories(privateParameters, sourceFilter); + deleteExtraConfigurationDirectories(configurationSources, sourceFilter); - downloadConfigurationFromAdditionalSources(privateParameters, sourceFilter); + downloadConfigurationFromAdditionalSources(configurationSources, sourceFilter); + } + + protected List getConfigurationSources() { + PrivateParameters privateParameters = loadPrivateParameters(); + return privateParameters != null ? privateParameters.getConfigurationAnchors() : List.of(); } private void initConfigurationAnchor() throws Exception { log.trace("initConfigurationAnchor()"); String anchorFileName = SystemProperties.getConfigurationAnchorFile(); - if (!Files.exists(Paths.get(anchorFileName))) { log.warn("Cannot download configuration, anchor file {} does not exist", anchorFileName); @@ -94,7 +98,7 @@ private void initConfigurationAnchor() throws Exception { } try { - configurationAnchor = new ConfigurationAnchorV2(anchorFileName); + configurationAnchor = new ConfigurationAnchor(anchorFileName); } catch (Exception e) { String message = String.format("Failed to load configuration anchor from file %s", anchorFileName); @@ -117,9 +121,14 @@ private void downloadConfigurationFromAnchor() throws Exception { handleResult(downloader.download(configurationAnchor), true); } - private PrivateParametersV2 loadPrivateParameters() { + private PrivateParameters loadPrivateParameters() { try { - ConfigurationDirectoryV2 dir = new ConfigurationDirectoryV2(globalConfigurationDir); + VersionableConfigurationDirectory dir; + if (downloader.getConfigurationVersion() > 2) { + dir = new ConfigurationDirectoryV3(globalConfigurationDir); + } else { + dir = new ConfigurationDirectoryV2(globalConfigurationDir); + } return dir.getPrivate(configurationAnchor.getInstanceIdentifier()); } catch (Exception e) { log.error("Failed to read additional configuration sources from" + globalConfigurationDir, e); @@ -127,12 +136,11 @@ private PrivateParametersV2 loadPrivateParameters() { } } - protected void deleteExtraConfigurationDirectories(PrivateParametersV2 privateParameters, + protected void deleteExtraConfigurationDirectories(List configurationSources, FederationConfigurationSourceFilter sourceFilter) { Set directoriesToKeep; - if (privateParameters != null) { - directoriesToKeep = privateParameters.getConfigurationSource() - .stream() + if (configurationSources != null) { + directoriesToKeep = configurationSources.stream() .map(ConfigurationSource::getInstanceIdentifier) .filter(sourceFilter::shouldDownloadConfigurationFor) .map(ConfigurationUtils::escapeInstanceIdentifier) @@ -149,13 +157,12 @@ protected void deleteExtraConfigurationDirectories(PrivateParametersV2 privatePa ConfigurationDirectory.deleteExtraDirs(globalConfigurationDir, directoriesToKeep); } - private void downloadConfigurationFromAdditionalSources(PrivateParametersV2 privateParameters, + private void downloadConfigurationFromAdditionalSources(List configurationSources, FederationConfigurationSourceFilter sourceFilter) throws Exception { - if (privateParameters != null) { - for (ConfigurationSource source : privateParameters.getConfigurationSource()) { + if (configurationSources != null) { + for (ConfigurationSource source : configurationSources) { if (sourceFilter.shouldDownloadConfigurationFor(source.getInstanceIdentifier())) { - DownloadResult result = downloader.download( - source, ConfigurationConstants.CONTENT_ID_SHARED_PARAMETERS); + DownloadResult result = downloader.download(source, ConfigurationConstants.CONTENT_ID_SHARED_PARAMETERS); handleResult(result, false); } } diff --git a/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientMain.java b/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientMain.java index 6f6ee5ec34..a86457a167 100644 --- a/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientMain.java +++ b/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientMain.java @@ -62,6 +62,7 @@ import static ee.ria.xroad.common.DiagnosticsErrorCodes.RETURN_SUCCESS; import static ee.ria.xroad.common.ErrorCodes.translateException; import static ee.ria.xroad.common.SystemProperties.CONF_FILE_PROXY; +import static ee.ria.xroad.common.SystemProperties.CURRENT_GLOBAL_CONFIGURATION_VERSION; import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.CONTENT_ID_PRIVATE_PARAMETERS; import static ee.ria.xroad.common.conf.globalconf.ConfigurationConstants.CONTENT_ID_SHARED_PARAMETERS; @@ -112,10 +113,10 @@ public static void main(String[] args) throws Exception { String[] actualArgs = cmd.getArgs(); if (actualArgs.length == NUM_ARGS_FROM_CONF_PROXY_FULL) { // Run configuration client in one-shot mode downloading the specified global configuration version. - System.exit(download(actualArgs[0], actualArgs[1])); + System.exit(download(actualArgs[0], actualArgs[1], Integer.parseInt(actualArgs[2]))); } else if (actualArgs.length == NUM_ARGS_FROM_CONF_PROXY) { // Run configuration client in one-shot mode downloading the current global configuration version. - System.exit(download(actualArgs[0], actualArgs[1])); + System.exit(download(actualArgs[0], actualArgs[1], CURRENT_GLOBAL_CONFIGURATION_VERSION)); } else if (actualArgs.length == 1) { // Run configuration client in validate mode. System.exit(validate(actualArgs[0], getParamsValidator(cmd))); @@ -137,16 +138,16 @@ private static CommandLine getCommandLine(String[] args) throws Exception { return parser.parse(options, args); } - private static int download(String configurationAnchorFile, String configurationPath) { + private static int download(String configurationAnchorFile, String configurationPath, int version) { log.debug("Downloading configuration using anchor {} path = {})", configurationAnchorFile, configurationPath); System.setProperty(SystemProperties.CONFIGURATION_ANCHOR_FILE, configurationAnchorFile); - client = new ConfigurationClient(configurationPath) { + client = new ConfigurationClient(configurationPath, version) { @Override protected void deleteExtraConfigurationDirectories( - PrivateParametersV2 privateParameters, + List configurationSources, FederationConfigurationSourceFilter sourceFilter) { // do not delete anything } @@ -155,13 +156,14 @@ protected void deleteExtraConfigurationDirectories( return execute(); } - private static int validate(String configurationAnchorFile, final ParamsValidator paramsValidator) { + private static int validate(String configurationAnchorFile, final ParamsValidator paramsValidator) + throws Exception { log.trace("Downloading configuration using anchor {}", configurationAnchorFile); // Create configuration that does not persist files to disk. final String configurationPath = SystemProperties.getConfigurationPath(); - ConfigurationDownloader configurationDownloader = new ConfigurationDownloader(configurationPath) { + var configurationDownloader = new ConfigurationDownloader(configurationPath, CURRENT_GLOBAL_CONFIGURATION_VERSION) { @Override void handleContent(byte[] content, ConfigurationFile file) throws Exception { validateContent(file); @@ -188,10 +190,10 @@ void deleteExtraFiles(String instanceIdentifier, Set neededFiles) { }; - ConfigurationAnchorV2 configurationAnchor = new ConfigurationAnchorV2(configurationAnchorFile); + ConfigurationAnchor configurationAnchor = new ConfigurationAnchor(configurationAnchorFile); client = new ConfigurationClient(configurationPath, configurationDownloader, configurationAnchor) { @Override - protected void deleteExtraConfigurationDirectories(PrivateParametersV2 privateParameters, + protected void deleteExtraConfigurationDirectories(List configurationSources, FederationConfigurationSourceFilter sourceFilter) { // do not delete any files } @@ -234,7 +236,7 @@ private static void startDaemon() throws Exception { private static void setup() { log.trace("setUp()"); - client = new ConfigurationClient(SystemProperties.getConfigurationPath()); + client = new ConfigurationClient(SystemProperties.getConfigurationPath(), CURRENT_GLOBAL_CONFIGURATION_VERSION); adminPort = new AdminPort(SystemProperties.getConfigurationClientAdminPort()); diff --git a/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloader.java b/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloader.java index e4af8eeba6..a0207f8b53 100644 --- a/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloader.java +++ b/src/configuration-client/src/main/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloader.java @@ -27,14 +27,17 @@ import ee.ria.xroad.common.CodedException; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; import org.bouncycastle.operator.DigestCalculator; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.net.URLConnection; @@ -53,6 +56,7 @@ import static ee.ria.xroad.common.ErrorCodes.X_IO_ERROR; import static ee.ria.xroad.common.ErrorCodes.X_MALFORMED_GLOBALCONF; +import static ee.ria.xroad.common.conf.globalconf.ConfigurationUtils.generateConfigurationLocation; import static ee.ria.xroad.common.util.CryptoUtils.createDigestCalculator; import static ee.ria.xroad.common.util.CryptoUtils.decodeBase64; import static ee.ria.xroad.common.util.CryptoUtils.encodeBase64; @@ -78,8 +82,12 @@ class ConfigurationDownloader { private final Map lastSuccessfulLocation = new HashMap<>(); - ConfigurationDownloader(String globalConfigurationDir) { + @Getter + private int configurationVersion; + + ConfigurationDownloader(String globalConfigurationDir, int configurationVersion) { fileNameProvider = new FileNameProviderImpl(globalConfigurationDir); + this.configurationVersion = configurationVersion; } ConfigurationParser getParser() { @@ -139,6 +147,7 @@ private void preferLastSuccessLocation(ConfigurationSource source, List 2) { + URL url = new URL(generateConfigurationLocation(location.getDownloadURL(), configurationVersion)); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + if (connection.getResponseCode() != HttpStatus.SC_OK) { + log.info("Global conf V3 not available, defaulting back to V2"); + configurationVersion = 2; + } + connection.disconnect(); + } + return new ConfigurationLocation(location.getSource(), + ConfigurationUtils.generateConfigurationLocation(location.getDownloadURL(), configurationVersion), + location.getVerificationCerts()); + } + byte[] downloadContent(ConfigurationLocation location, ConfigurationFile file) throws Exception { URLConnection connection = getDownloadURLConnection(getDownloadURL(location, file)); log.info("Downloading content from {}", connection.getURL()); @@ -289,11 +313,21 @@ void validateContent(ConfigurationFile file) { void handleContent(byte[] content, ConfigurationFile file) throws Exception { switch (file.getContentIdentifier()) { case ConfigurationConstants.CONTENT_ID_PRIVATE_PARAMETERS: - PrivateParametersV2 privateParameters = new PrivateParametersV2(content); + PrivateParameters privateParameters; + if (configurationVersion > 2) { + privateParameters = new PrivateParametersV3(content).getPrivateParameters(); + } else { + privateParameters = new PrivateParametersV2(content).getPrivateParameters(); + } handlePrivateParameters(privateParameters, file); break; case ConfigurationConstants.CONTENT_ID_SHARED_PARAMETERS: - SharedParametersV2 sharedParameters = new SharedParametersV2(content); + SharedParameters sharedParameters; + if (configurationVersion > 2) { + sharedParameters = new SharedParametersV3(content).getSharedParameters(); + } else { + sharedParameters = new SharedParametersV2(content).getSharedParameters(); + } handleSharedParameters(sharedParameters, file); break; default: @@ -301,11 +335,11 @@ void handleContent(byte[] content, ConfigurationFile file) throws Exception { } } - void handlePrivateParameters(PrivateParametersV2 privateParameters, ConfigurationFile file) { + void handlePrivateParameters(PrivateParameters privateParameters, ConfigurationFile file) { verifyInstanceIdentifier(privateParameters.getInstanceIdentifier(), file); } - void handleSharedParameters(SharedParametersV2 sharedParameters, ConfigurationFile file) { + void handleSharedParameters(SharedParameters sharedParameters, ConfigurationFile file) { verifyInstanceIdentifier(sharedParameters.getInstanceIdentifier(), file); } diff --git a/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientTest.java b/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientTest.java index f9b54c3052..4430d8244c 100644 --- a/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientTest.java +++ b/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationClientTest.java @@ -129,8 +129,8 @@ public void downloadConfFail() throws Exception { // ------------------------------------------------------------------------ - private static ConfigurationAnchorV2 getConfigurationAnchor(final String fileName) { - return new ConfigurationAnchorV2((String) null) { + private static ConfigurationAnchor getConfigurationAnchor(final String fileName) { + return new ConfigurationAnchor((String) null) { @Override public boolean hasChanged() { @@ -160,10 +160,10 @@ private void initInstanceIdentifier() throws Exception { } private ConfigurationClient getClient(final String confPath, final List receivedParts) { - ConfigurationAnchorV2 configurationAnchor = getConfigurationAnchor(confPath + ".txt"); + ConfigurationAnchor configurationAnchor = getConfigurationAnchor(confPath + ".txt"); ConfigurationDownloader configurations = new ConfigurationDownloader( - tempConfFolder.getRoot().getAbsolutePath()) { + tempConfFolder.getRoot().getAbsolutePath(), 2) { @Override ConfigurationParser getParser() { return new ConfigurationParser() { diff --git a/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloaderTest.java b/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloaderTest.java index 38ab79c10f..a84d8e57b0 100644 --- a/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloaderTest.java +++ b/src/configuration-client/src/test/java/ee/ria/xroad/common/conf/globalconf/ConfigurationDownloaderTest.java @@ -39,6 +39,7 @@ import java.util.Arrays; import java.util.List; +import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -84,7 +85,7 @@ public void rememberLastSuccessfulDownloadLocation() { for (int i = 0; i < MAX_ATTEMPTS; i++) { // Given ConfigurationDownloader downloader = - getDownloader(LOCATION_URL_SUCCESS); + getDownloader(LOCATION_URL_SUCCESS + "?version=2"); List locationUrls = getMixedLocationUrls(); // When @@ -123,11 +124,11 @@ private void verifyLastSuccessfulLocationUsedSecondTime( } private Matcher> hasOnlyOneSuccessfulUrl() { - return new TypeSafeMatcher>() { + return new TypeSafeMatcher<>() { @Override protected boolean matchesSafely(List parsedUrls) { - return parsedUrls.size() == 1 - && parsedUrls.contains(LOCATION_URL_SUCCESS); + return parsedUrls.size() == 1 + && parsedUrls.contains(LOCATION_URL_SUCCESS + "?version=2"); } @Override @@ -146,7 +147,10 @@ private void executeDownload() { downloader.download(getSource(locationUrls)); // Then - verifyLocationsRandomized(downloader, locationUrls); + List expectedLocationUrls = locationUrls.stream() + .map(url -> url + "?version=" + downloader.getConfigurationVersion()) + .collect(toList()); + verifyLocationsRandomized(downloader, expectedLocationUrls); } private void verifyLocationsRandomized( @@ -168,7 +172,7 @@ private boolean haveMoreAttempts(int attemptNo) { private Matcher> sameUrlsAreContained( final List locationUrls) { - return new TypeSafeMatcher>() { + return new TypeSafeMatcher<>() { @Override protected boolean matchesSafely(List parsedUrls) { return locationUrls.size() == parsedUrls.size() @@ -225,7 +229,7 @@ private ConfigurationSource getSource(final List locationUrls) { private ConfigurationDownloader getDownloader( String... successfulLocationUrls) { - return new ConfigurationDownloader("f") { + return new ConfigurationDownloader("f", 3) { ConfigurationParser parser = new TestConfigurationParser(successfulLocationUrls); diff --git a/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilGenerateAnchor.java b/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilGenerateAnchor.java index 1e8e645cf8..8c0de6a0cc 100644 --- a/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilGenerateAnchor.java +++ b/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilGenerateAnchor.java @@ -25,7 +25,7 @@ */ package ee.ria.xroad.confproxy.commandline; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ConfigurationAnchorType; import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ConfigurationSourceType; import ee.ria.xroad.common.conf.globalconf.privateparameters.v2.ObjectFactory; @@ -68,9 +68,9 @@ final void execute(final CommandLine commandLine) throws Exception { ensureProxyExists(commandLine); final ConfProxyProperties conf = loadConf(commandLine); - ConfigurationAnchorV2 sourceAnchor = null; + ConfigurationAnchor sourceAnchor = null; try { - sourceAnchor = new ConfigurationAnchorV2(conf.getProxyAnchorPath()); + sourceAnchor = new ConfigurationAnchor(conf.getProxyAnchorPath()); } catch (Exception ex) { fail("Could not load source anchor: ", ex); } diff --git a/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilViewConf.java b/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilViewConf.java index 4b4e3b905c..4ec5ea5f83 100644 --- a/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilViewConf.java +++ b/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/commandline/ConfProxyUtilViewConf.java @@ -25,7 +25,7 @@ */ package ee.ria.xroad.confproxy.commandline; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import ee.ria.xroad.common.util.CryptoUtils; import ee.ria.xroad.confproxy.ConfProxyProperties; import ee.ria.xroad.confproxy.util.ConfProxyHelper; @@ -102,10 +102,10 @@ final void execute(final CommandLine commandLine) throws Exception { */ private void displayInfo(final String instance, final ConfProxyProperties conf) throws Exception { - ConfigurationAnchorV2 anchor = null; + ConfigurationAnchor anchor = null; String anchorError = null; try { - anchor = new ConfigurationAnchorV2(conf.getProxyAnchorPath()); + anchor = new ConfigurationAnchor(conf.getProxyAnchorPath()); } catch (Exception e) { anchorError = "'" + ConfProxyProperties.ANCHOR_XML + "' could not be loaded: " + e; diff --git a/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/util/ConfProxyHelper.java b/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/util/ConfProxyHelper.java index 9ccc98ebb1..2187944d70 100644 --- a/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/util/ConfProxyHelper.java +++ b/src/configuration-proxy/src/main/java/ee/ria/xroad/confproxy/util/ConfProxyHelper.java @@ -28,6 +28,7 @@ import ee.ria.xroad.common.SystemProperties; import ee.ria.xroad.common.conf.globalconf.ConfigurationDirectory; import ee.ria.xroad.common.conf.globalconf.ConfigurationDirectoryV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationDirectoryV3; import ee.ria.xroad.confproxy.ConfProxyProperties; import lombok.extern.slf4j.Slf4j; @@ -80,7 +81,11 @@ public static ConfigurationDirectory downloadConfiguration( log.info("Running '{} {} {} {}' ...", ConfProxyProperties.getDownloadScriptPath(), sourceAnchor, path, version); runConfClient(pb); - return new ConfigurationDirectoryV2(path); + if (version > 2) { + return new ConfigurationDirectoryV3(path); + } else { + return new ConfigurationDirectoryV2(path); + } } /** diff --git a/src/configuration-proxy/src/test/java/ee/ria/xroad/confproxy/ConfProxyTest.java b/src/configuration-proxy/src/test/java/ee/ria/xroad/confproxy/ConfProxyTest.java index 36c2ab5b15..8acce45a39 100644 --- a/src/configuration-proxy/src/test/java/ee/ria/xroad/confproxy/ConfProxyTest.java +++ b/src/configuration-proxy/src/test/java/ee/ria/xroad/confproxy/ConfProxyTest.java @@ -26,7 +26,6 @@ package ee.ria.xroad.confproxy; import ee.ria.xroad.common.CodedException; -import ee.ria.xroad.common.SystemProperties; import ee.ria.xroad.common.conf.globalconf.ConfigurationDirectoryV2; import ee.ria.xroad.confproxy.util.ConfProxyHelper; import ee.ria.xroad.confproxy.util.OutputBuilder; @@ -69,13 +68,12 @@ public void cleanupTempDirectoriesWhenBuildingSignedDirectoryFails() throws Exce ConfProxyProperties conf = new ConfProxyProperties("PROXY1"); ConfProxyHelper.purgeOutdatedGenerations(conf); ConfigurationDirectoryV2 confDir = new ConfigurationDirectoryV2( - conf.getConfigurationDownloadPath(SystemProperties.CURRENT_GLOBAL_CONFIGURATION_VERSION)); + conf.getConfigurationDownloadPath(2)); try (MockedStatic signerProxyMock = mockStatic(SignerProxy.class)) { signerProxyMock.when(() -> SignerProxy.getSignMechanism(any())) .thenThrow(new CodedException("InternalError", "Signer is unreachable")); - try (OutputBuilder output = new OutputBuilder(confDir, conf, - SystemProperties.CURRENT_GLOBAL_CONFIGURATION_VERSION)) { + try (OutputBuilder output = new OutputBuilder(confDir, conf, 2)) { CodedException exception = assertThrows(CodedException.class, output::buildSignedDirectory); assertEquals("InternalError: Signer is unreachable", exception.getMessage()); } diff --git a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/facade/GlobalConfFacade.java b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/facade/GlobalConfFacade.java index dc8d5e6900..553f0bbb1b 100644 --- a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/facade/GlobalConfFacade.java +++ b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/facade/GlobalConfFacade.java @@ -32,7 +32,7 @@ import ee.ria.xroad.common.conf.globalconf.GlobalConf; import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo; import ee.ria.xroad.common.conf.globalconf.MemberInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -182,10 +182,10 @@ public String getSecurityServerAddress(SecurityServerId securityServerId) { } /** - * {@link GlobalConf#getApprovedTspTypes(String)} + * {@link GlobalConf#getApprovedTsps(String)} */ - public List getApprovedTspTypes(String instanceIdentifier) { - return GlobalConf.getApprovedTspTypes(instanceIdentifier); + public List getApprovedTsps(String instanceIdentifier) { + return GlobalConf.getApprovedTsps(instanceIdentifier); } /** diff --git a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/repository/AnchorRepository.java b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/repository/AnchorRepository.java index 4b5d7395cd..747d8e4ae1 100644 --- a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/repository/AnchorRepository.java +++ b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/repository/AnchorRepository.java @@ -26,7 +26,7 @@ package org.niis.xroad.securityserver.restapi.repository; import ee.ria.xroad.common.SystemProperties; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import ee.ria.xroad.common.util.AtomicSave; import lombok.extern.slf4j.Slf4j; @@ -69,8 +69,8 @@ public byte[] readAnchorFile() throws NoSuchFileException { * Load anchor from file * @return */ - public ConfigurationAnchorV2 loadAnchorFromFile() { - return new ConfigurationAnchorV2(CONFIGURATION_ANCHOR_FILENAME); + public ConfigurationAnchor loadAnchorFromFile() { + return new ConfigurationAnchor(CONFIGURATION_ANCHOR_FILENAME); } /** diff --git a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfChecker.java b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfChecker.java index 38507a6ee8..2c83a412b5 100644 --- a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfChecker.java +++ b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfChecker.java @@ -26,7 +26,7 @@ package org.niis.xroad.securityserver.restapi.scheduling; import ee.ria.xroad.common.SystemProperties; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.conf.serverconf.model.ClientType; import ee.ria.xroad.common.conf.serverconf.model.ServerConfType; import ee.ria.xroad.common.conf.serverconf.model.TspType; @@ -135,7 +135,7 @@ private void updateServerConf() { updateClientStatuses(serverConf, securityServerId); updateAuthCertStatuses(securityServerId); if (SystemProperties.geUpdateTimestampServiceUrlsAutomatically()) { - updateTimestampServiceUrls(globalConfFacade.getApprovedTspTypes( + updateTimestampServiceUrls(globalConfFacade.getApprovedTsps( globalConfFacade.getInstanceIdentifier()), serverConf.getTsp() ); @@ -152,21 +152,21 @@ private void updateServerConf() { * @param globalTsps timestamping services from global configuration * @param localTsps timestamping services from local database */ - void updateTimestampServiceUrls(List globalTsps, List localTsps) { + void updateTimestampServiceUrls(List globalTsps, List localTsps) { for (TspType localTsp : localTsps) { - List globalTspMatches = globalTsps.stream() + List globalTspMatches = globalTsps.stream() .filter(g -> g.getName().equals(localTsp.getName())) .collect(toList()); if (globalTspMatches.size() > 1) { - Optional urlChanges = + Optional urlChanges = globalTspMatches.stream().filter(t -> !t.getUrl().equals(localTsp.getUrl())).findAny(); if (urlChanges.isPresent()) { log.warn("Skipping timestamping service URL update due to multiple services with the same name: {}", globalTspMatches.get(0).getName()); } } else if (globalTspMatches.size() == 1) { - ApprovedTSAType globalTspMatch = globalTspMatches.get(0); + SharedParameters.ApprovedTSA globalTspMatch = globalTspMatches.get(0); if (!globalTspMatch.getUrl().equals(localTsp.getUrl())) { log.info("Timestamping service URL has changed in the global configuration. " + "Updating the changes to the local configuration, Name: {}, Old URL: {}, New URL: {}", diff --git a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/GlobalConfService.java b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/GlobalConfService.java index 2c09784e3f..2ff988b15a 100644 --- a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/GlobalConfService.java +++ b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/GlobalConfService.java @@ -30,7 +30,7 @@ import ee.ria.xroad.common.conf.globalconf.ApprovedCAInfo; import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo; import ee.ria.xroad.common.conf.globalconf.MemberInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.conf.serverconf.model.TspType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -182,8 +182,8 @@ public Collection getAllCaCertsForThisInstance() { * {@link TspType#getId()} is null for all returned items */ public List getApprovedTspsForThisInstance() { - List approvedTspTypes = - globalConfFacade.getApprovedTspTypes(globalConfFacade.getInstanceIdentifier()); + List approvedTspTypes = + globalConfFacade.getApprovedTsps(globalConfFacade.getInstanceIdentifier()); List tsps = approvedTspTypes.stream() .map(this::createTspType) .collect(Collectors.toList()); @@ -193,10 +193,10 @@ public List getApprovedTspsForThisInstance() { /** * init TspType DTO with name and url. id will be null */ - private TspType createTspType(ApprovedTSAType approvedTSAType) { + private TspType createTspType(SharedParameters.ApprovedTSA approvedTSA) { TspType tsp = new TspType(); - tsp.setUrl(approvedTSAType.getUrl()); - tsp.setName(approvedTSAType.getName()); + tsp.setUrl(approvedTSA.getUrl()); + tsp.setName(approvedTSA.getName()); return tsp; } diff --git a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/SystemService.java b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/SystemService.java index c9d287592c..1f52fcbc32 100644 --- a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/SystemService.java +++ b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/service/SystemService.java @@ -28,7 +28,7 @@ import ee.ria.xroad.common.CodedException; import ee.ria.xroad.common.SystemProperties; import ee.ria.xroad.common.conf.InternalSSLKey; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import ee.ria.xroad.common.conf.serverconf.model.TspType; import ee.ria.xroad.common.util.CertUtils; import ee.ria.xroad.common.util.CryptoUtils; @@ -212,7 +212,7 @@ public byte[] generateInternalCsr(String distinguishedName) throws InvalidDistin */ public AnchorFile getAnchorFile() throws AnchorNotFoundException { AnchorFile anchorFile = new AnchorFile(calculateAnchorHexHash(readAnchorFile())); - ConfigurationAnchorV2 anchor = anchorRepository.loadAnchorFromFile(); + ConfigurationAnchor anchor = anchorRepository.loadAnchorFromFile(); anchorFile.setCreatedAt(FormatUtils.fromDateToOffsetDateTime(anchor.getGeneratedAt())); return anchorFile; } @@ -228,7 +228,7 @@ public AnchorFile getAnchorFile() throws AnchorNotFoundException { */ public AnchorFile getAnchorFileFromBytes(byte[] anchorBytes, boolean shouldVerifyAnchorInstance) throws InvalidAnchorInstanceException, MalformedAnchorException { - ConfigurationAnchorV2 anchor = createAnchorFromBytes(anchorBytes); + ConfigurationAnchor anchor = createAnchorFromBytes(anchorBytes); if (shouldVerifyAnchorInstance) { verifyAnchorInstance(anchor); } @@ -300,7 +300,7 @@ private void uploadAnchor(byte[] anchorBytes, boolean shouldVerifyAnchorInstance throws InvalidAnchorInstanceException, AnchorUploadException, MalformedAnchorException, ConfigurationDownloadException, ConfigurationVerifier.ConfigurationVerificationException { auditDataHelper.calculateAndPutAnchorHash(anchorBytes); - ConfigurationAnchorV2 anchor = createAnchorFromBytes(anchorBytes); + ConfigurationAnchor anchor = createAnchorFromBytes(anchorBytes); auditDataHelper.putDate(RestApiAuditProperty.GENERATED_AT, anchor.getGeneratedAt()); if (shouldVerifyAnchorInstance) { verifyAnchorInstance(anchor); @@ -348,10 +348,10 @@ public boolean isAnchorImported() { * @return * @throws MalformedAnchorException if the anchor is malformed or somehow invalid */ - private ConfigurationAnchorV2 createAnchorFromBytes(byte[] anchorBytes) throws MalformedAnchorException { - ConfigurationAnchorV2 anchor = null; + private ConfigurationAnchor createAnchorFromBytes(byte[] anchorBytes) throws MalformedAnchorException { + ConfigurationAnchor anchor = null; try { - anchor = new ConfigurationAnchorV2(anchorBytes); + anchor = new ConfigurationAnchor(anchorBytes); } catch (CodedException ce) { if (isCausedByMalformedAnchorContent(ce)) { throw new MalformedAnchorException("Anchor is invalid"); @@ -389,7 +389,7 @@ private File createTemporaryAnchorFile(byte[] anchorBytes) throws IOException { * @param anchor * @throws InvalidAnchorInstanceException anchor is not generated in the current instance */ - private void verifyAnchorInstance(ConfigurationAnchorV2 anchor) throws InvalidAnchorInstanceException { + private void verifyAnchorInstance(ConfigurationAnchor anchor) throws InvalidAnchorInstanceException { String anchorInstanceId = anchor.getInstanceIdentifier(); String ownerInstance = currentSecurityServerId.getServerId().getOwner().getXRoadInstance(); if (!anchorInstanceId.equals(ownerInstance)) { @@ -419,7 +419,7 @@ public byte[] readAnchorFile() throws AnchorNotFoundException { */ public String getAnchorFilenameForDownload() { DateFormat df = new SimpleDateFormat(ANCHOR_DOWNLOAD_DATE_TIME_FORMAT); - ConfigurationAnchorV2 anchor = anchorRepository.loadAnchorFromFile(); + ConfigurationAnchor anchor = anchorRepository.loadAnchorFromFile(); return ANCHOR_DOWNLOAD_FILENAME_PREFIX + df.format(anchor.getGeneratedAt()) + ANCHOR_DOWNLOAD_FILE_EXTENSION; } diff --git a/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfCheckerTest.java b/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfCheckerTest.java index 34fcd91352..11ab5be2b6 100644 --- a/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfCheckerTest.java +++ b/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/scheduling/GlobalConfCheckerTest.java @@ -26,7 +26,7 @@ package org.niis.xroad.securityserver.restapi.scheduling; import ee.ria.xroad.common.conf.globalconf.MemberInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.conf.serverconf.IsAuthentication; import ee.ria.xroad.common.conf.serverconf.model.ClientType; import ee.ria.xroad.common.conf.serverconf.model.TspType; @@ -230,7 +230,7 @@ public void registerMemberAndChangeSecurityServerOwner() throws Exception { public void testUpdateTimestampServiceUrls() { // test with single matching items - List approvedTSATypes = + List approvedTSATypes = Collections.singletonList(TestUtils.createApprovedTsaType("http://example.com:8121", "Foo")); List tspTypes = Collections.singletonList(TestUtils.createTspType("http://example.com:8121", "Foo")); @@ -242,7 +242,7 @@ public void testUpdateTimestampServiceUrls() { // test the normal update case // the change in approvedTSAType1 URL should be reflected to tspType1 URL - List approvedTSATypes1 = Arrays.asList( + List approvedTSATypes1 = Arrays.asList( TestUtils.createApprovedTsaType("http://example.com:9999", "Foo"), TestUtils.createApprovedTsaType("http://example.net", "Bar") ); @@ -260,7 +260,7 @@ public void testUpdateTimestampServiceUrls() { // test the conflicting update case // the change in approvedTSAType3 URL should not be reflected to tspType3 URL because of ambiguous names - List approvedTSATypes2 = Arrays.asList( + List approvedTSATypes2 = Arrays.asList( TestUtils.createApprovedTsaType("http://example.com:9898", "Foo"), TestUtils.createApprovedTsaType("http://example.net", "Foo"), TestUtils.createApprovedTsaType("http://example.org:8080", "Zzz") diff --git a/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/service/SystemServiceTest.java b/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/service/SystemServiceTest.java index 22df31be8b..db9aae4da5 100644 --- a/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/service/SystemServiceTest.java +++ b/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/service/SystemServiceTest.java @@ -25,7 +25,7 @@ */ package org.niis.xroad.securityserver.restapi.service; -import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchorV2; +import ee.ria.xroad.common.conf.globalconf.ConfigurationAnchor; import ee.ria.xroad.common.conf.serverconf.model.TspType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.SecurityServerId; @@ -245,7 +245,7 @@ public void uploadInitialAnchorAgain() throws Exception { byte[] anchorBytes = FileUtils.readFileToByteArray(TestUtils.ANCHOR_FILE); when(anchorRepository.readAnchorFile()).thenReturn(anchorBytes); when(anchorRepository.loadAnchorFromFile()) - .thenReturn(new ConfigurationAnchorV2("src/test/resources/internal-configuration-anchor.xml")); + .thenReturn(new ConfigurationAnchor("src/test/resources/internal-configuration-anchor.xml")); systemService.uploadInitialAnchor(anchorBytes); } } diff --git a/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/util/TestUtils.java b/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/util/TestUtils.java index d53beae319..49f7c7b429 100644 --- a/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/util/TestUtils.java +++ b/src/security-server/admin-service/application/src/test/java/org/niis/xroad/securityserver/restapi/util/TestUtils.java @@ -27,7 +27,7 @@ import ee.ria.xroad.common.conf.globalconf.GlobalGroupInfo; import ee.ria.xroad.common.conf.globalconf.MemberInfo; -import ee.ria.xroad.common.conf.globalconf.sharedparameters.v2.ApprovedTSAType; +import ee.ria.xroad.common.conf.globalconf.SharedParameters; import ee.ria.xroad.common.conf.serverconf.model.TspType; import ee.ria.xroad.common.identifier.ClientId; import ee.ria.xroad.common.identifier.GlobalGroupId; @@ -311,11 +311,11 @@ public static TspType createTspType(String url, String name) { * @param name * @return */ - public static ApprovedTSAType createApprovedTsaType(String url, String name) { - ApprovedTSAType approvedTSAType = new ApprovedTSAType(); - approvedTSAType.setUrl(url); - approvedTSAType.setName(name); - return approvedTSAType; + public static SharedParameters.ApprovedTSA createApprovedTsaType(String url, String name) { + SharedParameters.ApprovedTSA approvedTSA = new SharedParameters.ApprovedTSA(); + approvedTSA.setUrl(url); + approvedTSA.setName(name); + return approvedTSA; } /** diff --git a/src/security-server/system-test/src/intTest/java/org/niis/xroad/ss/test/ui/hook/MockServerBeforeSuiteHook.java b/src/security-server/system-test/src/intTest/java/org/niis/xroad/ss/test/ui/hook/MockServerBeforeSuiteHook.java index d5cd16f6a9..8ad8e80e6a 100644 --- a/src/security-server/system-test/src/intTest/java/org/niis/xroad/ss/test/ui/hook/MockServerBeforeSuiteHook.java +++ b/src/security-server/system-test/src/intTest/java/org/niis/xroad/ss/test/ui/hook/MockServerBeforeSuiteHook.java @@ -30,6 +30,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.mockserver.mock.Expectation; +import org.mockserver.model.Parameter; import org.niis.xroad.ss.test.ui.container.MockServerService; import org.springframework.stereotype.Component; @@ -51,27 +52,33 @@ public class MockServerBeforeSuiteHook implements BeforeSuiteHook { @Override public void beforeSuite() { - mockFileResponse(GLOBALCONF_DIR, "internalconf", "/"); - mockFileResponse(GLOBALCONF_DIR, "externalconf", "/"); - mockFileResponse(GLOBALCONF_DIR, CONF_PART_DIR + "/private-params.xml", "/v2/"); - mockFileResponse(GLOBALCONF_DIR, CONF_PART_DIR + "/shared-params.xml", "/v2/"); - mockFileResponse(GLOBALCONF_DIR, CONF_PART_DIR + "/fetchinterval-params.xml", "/v2/"); + mockFileResponse(GLOBALCONF_DIR, "/", "internalconf", new Parameter("version", "2")); + mockFileResponse(GLOBALCONF_DIR, "/", "externalconf", new Parameter("version", "2")); + mockFileResponse(GLOBALCONF_DIR, "/v2/", CONF_PART_DIR + "/private-params.xml"); + mockFileResponse(GLOBALCONF_DIR, "/v2/", CONF_PART_DIR + "/shared-params.xml"); + mockFileResponse(GLOBALCONF_DIR, "/v2/", CONF_PART_DIR + "/fetchinterval-params.xml"); - mockFileResponse(TESTSERVICES_DIR, "testopenapi1.yaml", PREFIX_TESTSERVICES); - mockFileResponse(TESTSERVICES_DIR, "testopenapi11.yaml", PREFIX_TESTSERVICES); - mockFileResponse(TESTSERVICES_DIR, "testopenapi2.json", PREFIX_TESTSERVICES); + mockFileResponse(TESTSERVICES_DIR, PREFIX_TESTSERVICES, "testopenapi1.yaml"); + mockFileResponse(TESTSERVICES_DIR, PREFIX_TESTSERVICES, "testopenapi11.yaml"); + mockFileResponse(TESTSERVICES_DIR, PREFIX_TESTSERVICES, "testopenapi2.json"); - mockFileResponse(TESTSERVICES_DIR, "testservice1.wsdl", PREFIX_TESTSERVICES); - mockFileResponse(TESTSERVICES_DIR, "testservice2.wsdl", PREFIX_TESTSERVICES); - mockFileResponse(TESTSERVICES_DIR, "testservice3.wsdl", PREFIX_TESTSERVICES); + mockFileResponse(TESTSERVICES_DIR, PREFIX_TESTSERVICES, "testservice1.wsdl"); + mockFileResponse(TESTSERVICES_DIR, PREFIX_TESTSERVICES, "testservice2.wsdl"); + mockFileResponse(TESTSERVICES_DIR, PREFIX_TESTSERVICES, "testservice3.wsdl"); } - private void mockFileResponse(String fileDir, String fileName, String urlPrefix) { + private void mockFileResponse(String fileDir, String pathPrefix, String path) { + mockFileResponse(fileDir, pathPrefix, path, null); + } + + private void mockFileResponse(String fileDir, String pathPrefix, String path, Parameter queryParam) { var expectations = mockServerService.client() .when(request() - .withPath(urlPrefix + fileName)) + .withPath(pathPrefix + path) + .withQueryStringParameter(queryParam) + ) .respond(response() - .withBody(classpathFileResolver.getFileAsString(fileDir + fileName)) + .withBody(classpathFileResolver.getFileAsString(fileDir + path)) ); for (Expectation expectation : expectations) {