diff --git a/changelog.txt b/changelog.txt index 54fff73846f5f840cd96e5ff22f3c997d35fe376..1984155e5af590c1ac970be8970ac7489ce7016b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,7 +2,8 @@ eDelivery SMP 5.0 - added new properties: smp.truststore.type: Truststore type as JKS/PKCS12 smp.keystore.type: Keystore type as JKS/PKCS12 - + document.restriction.allowed.certificate.types: Allowed key algorithms for certificates to be used in service metadata.Empty value means no restrictions, for other values see the java KeyFactory Algorithms for example: RSA|EC|Ed25519|Ed448; + smp.certificate.validation.allowed.certificate.type: Allowed user certificate JCE types. Empty value means no restrictions, for other values see the java KeyFactory Algorithms for examples: RSA|EC|Ed25519|Ed448; eDelivery SMP 4.2 - added new properties: diff --git a/pom.xml b/pom.xml index 365ec43944025055c445bb8ee7bc29d69d67b434..30e157fe1e8ed38800875ebe09a07040a664124c 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ <ant-commons-net.version>1.6.5</ant-commons-net.version> <aspectj.version>1.9.9.1</aspectj.version> <bdmsl.api.version>4.1.1</bdmsl.api.version> - <bouncycastle.version>1.70</bouncycastle.version> + <bouncycastle.version>1.72</bouncycastle.version> <build.helper.maven.version>1.9.1</build.helper.maven.version> <commons-beanutils.version>1.9.4</commons-beanutils.version> <commons-collections.version>3.2.2</commons-collections.version> diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java index d13a3373899ac7b6bc23add6d7f0c444e3ce71b5..03c02188c42109869129b259e76c9a2ccbec4fea 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java @@ -70,7 +70,7 @@ public class DBDomain extends BaseEntity { @ColumnDescription(comment = "SMP ID used for SML integration") String smlSmpId; @Column(name = "SML_PARTC_IDENT_REGEXP", length = CommonColumnsLengths.MAX_FREE_TEXT_LENGTH) - @ColumnDescription(comment = "Reqular expresion for participant ids") + @ColumnDescription(comment = "Regular expresion for participant ids") String smlParticipantIdentifierRegExp; @Column(name = "SML_CLIENT_CERT_HEADER", length = CommonColumnsLengths.MAX_FREE_TEXT_LENGTH) @ColumnDescription(comment = "Client-Cert header used behind RP - ClientCertHeader for SML integration") diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java index 8c85a419047b83296bb26b7d9da54a6c4765f057..d2070c6575fe4c06ba0a4167401f8dd1219aea36 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java @@ -100,6 +100,9 @@ public enum SMPPropertyEnum { OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, LIST_STRING), CERTIFICATE_SUBJECT_REGULAR_EXPRESSION("smp.certificate.validation.subjectRegex", ".*", "Regular expression to validate subject of the certificate", OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, REGEXP), + CERTIFICATE_ALLOWED_KEY_TYPES("smp.certificate.validation.allowed.certificate.types", + "", "Allowed user certificate types. Empty value means no restrictions, for other values see the java KeyFactory Algorithms for examples: RSA|EC|Ed25519|Ed448", + OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, LIST_STRING), SMP_PROPERTY_REFRESH_CRON("smp.property.refresh.cronJobExpression", "0 48 */1 * * *", "Property refresh cron expression (def 12 minutes to each hour). Property change is refreshed at restart!", OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, CRON_EXPRESSION), @@ -169,7 +172,7 @@ public enum SMPPropertyEnum { OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, LIST_STRING ), - EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED("smp.automation.authentication.external.tls.clientCert.enabled", "false", + EXTERNAL_TLS_AUTHENTICATION_CLIENT_CERT_HEADER_ENABLED(".external.tls.clientCert.enabled", "false", "Authentication with external module as: reverse proxy. Authenticated data are send send to application using 'Client-Cert' HTTP header. Do not enable this feature " + "without properly configured reverse-proxy!", OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, BOOLEAN), @@ -357,6 +360,8 @@ public enum SMPPropertyEnum { CLIENT_CERT_HEADER_ENABLED_DEPRECATED("authentication.blueCoat.enabled", "false", "Property was replaced by property: smp.automation.authentication.external.tls.clientCert.enabled", OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, BOOLEAN), + DOCUMENT_RESTRICTION_CERT_TYPES("document.restriction.allowed.certificate.types", "", "Allowed certificate types registered when composing service metadata. Empty value means no restrictions, for other values see the java KeyFactory Algorithms for examples: RSA|EC|Ed25519|Ed448", + OPTIONAL, NOT_ENCRYPTED, NO_RESTART_NEEDED, LIST_STRING), ; String property; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java index 093c462a36c48fc46250d9ed80c3ddd35f4e2ff2..1a6dad50b2d331e6341ec364d4e5975854b2e526 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ConfigurationService.java @@ -148,6 +148,10 @@ public class ConfigurationService { return configurationDAO.getCachedPropertyValue(CS_PARTICIPANTS); } + public List<String> getAllowedDocumentCertificateTypes() { + return configurationDAO.getCachedPropertyValue(DOCUMENT_RESTRICTION_CERT_TYPES); + } + public boolean getParticipantSchemeMandatory() { // not mandatory by default Boolean value = configurationDAO.getCachedPropertyValue(PARTC_SCH_MANDATORY); @@ -222,7 +226,11 @@ public class ConfigurationService { } public List<String> getAllowedCertificatePolicies() { - return configurationDAO.getCachedPropertyValue(CERTIFICATE_ALLOWED_CERTIFICATEPOLICY_OIDS); + return configurationDAO.getCachedPropertyValue(CERTIFICATE_ALLOWED_CERTIFICATEPOLICY_OIDS); + } + + public List<String> getAllowedCertificateKeyTypes() { + return configurationDAO.getCachedPropertyValue(CERTIFICATE_ALLOWED_KEY_TYPES); } public String getSMLIntegrationServerCertSubjectRegExpPattern() { @@ -332,6 +340,7 @@ public class ConfigurationService { public String getCasURLTokenValidation() { return configurationDAO.getCachedPropertyValue(SSO_CAS_TOKEN_VALIDATION_URL_PATH); } + public URL getCasUserDataURL() { URL casUrl = getCasURL(); if (casUrl == null) { @@ -355,7 +364,7 @@ public class ConfigurationService { public Map<String, String> getCasTokenValidationParams() { - return configurationDAO.getCachedPropertyValue(SSO_CAS_TOKEN_VALIDATION_PARAMS); + return configurationDAO.getCachedPropertyValue(SSO_CAS_TOKEN_VALIDATION_PARAMS); } public List<String> getCasURLTokenValidationGroups() { @@ -551,6 +560,7 @@ public class ConfigurationService { /** * Property is set in "file property configuration and can not be changed via database! + * * @return true if smp server is started in development mode */ public boolean isSMPStartupInDevMode() { diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java index 57ad759cc773bcf54b303a2ce77350b772625d5f..e553920b0d8fbba850ce28d91d539ab87125a8db 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java @@ -48,7 +48,7 @@ public final class ServiceMetadataSigner { private static final SMPLogger LOG = SMPLoggerFactory.getLogger(ServiceMetadataSigner.class); - private static final String RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; + private static final String RSA_SHA256 = org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256; @Autowired @@ -98,8 +98,6 @@ public final class ServiceMetadataSigner { } } - - private KeyInfo createKeyInfo(String alias) { KeyInfoFactory keyInfoFactory = getDomSigFactory().getKeyInfoFactory(); List content = new ArrayList(); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java index e3742cdab3c78014edebcd84df95d249db4a1f19..8a43d193a53127f7d8714a454499c274542f56cc 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java @@ -1,5 +1,6 @@ package eu.europa.ec.edelivery.smp.services.ui; +import eu.europa.ec.edelivery.security.utils.X509CertificateUtils; import eu.europa.ec.edelivery.smp.conversion.CaseSensitivityNormalizer; import eu.europa.ec.edelivery.smp.conversion.ServiceMetadataConverter; import eu.europa.ec.edelivery.smp.data.dao.BaseDao; @@ -13,24 +14,30 @@ import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus; import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; +import eu.europa.ec.edelivery.smp.services.ConfigurationService; import eu.europa.ec.smp.api.exceptions.XmlInvalidAgainstSchemaException; import eu.europa.ec.smp.api.validators.BdxSmpOasisValidator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; -import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; -import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceMetadata; +import org.oasis_open.docs.bdxr.ns.smp._2016._05.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.UnsupportedEncodingException; import java.nio.charset.IllegalCharsetNameException; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Optional; +import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.DOCUMENT_RESTRICTION_CERT_TYPES; import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INVALID_REQUEST; /** - * Serives for managing the Service metadata + * Services for managing the Service metadata */ @Service public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, ServiceMetadataRO> { @@ -40,12 +47,20 @@ public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, S protected final ServiceMetadataDao serviceMetadataDao; protected final UserDao userDao; protected final CaseSensitivityNormalizer caseSensitivityNormalizer; + protected final ConfigurationService configurationService; - public UIServiceMetadataService(DomainDao domainDao, ServiceMetadataDao serviceMetadataDao, UserDao userDao, CaseSensitivityNormalizer caseSensitivityNormalizer) { + + public UIServiceMetadataService(DomainDao domainDao, + ServiceMetadataDao serviceMetadataDao, + UserDao userDao, + CaseSensitivityNormalizer caseSensitivityNormalizer, + ConfigurationService configurationService) { this.domainDao = domainDao; this.serviceMetadataDao = serviceMetadataDao; this.userDao = userDao; this.caseSensitivityNormalizer = caseSensitivityNormalizer; + this.configurationService = configurationService; + } @Override @@ -152,9 +167,74 @@ public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, S return serviceMetadataRO; } } + try { + validateServiceMetadataCertificates(smd); + } catch (CertificateException e) { + serviceMetadataRO.setErrorMessage(ExceptionUtils.getRootCauseMessage(e)); + return serviceMetadataRO; + } } return serviceMetadataRO; } + /** + * Method validates certificates in all endpoints. + * + * @param smd ServiceMetadata document + * @throws CertificateException exception if certificate is not valid or the allowed key type + */ + public void validateServiceMetadataCertificates(ServiceMetadata smd) throws CertificateException { + List<EndpointType> endpointTypeList = searchAllEndpoints(smd); + for (EndpointType endpointType : endpointTypeList) { + validateCertificate(endpointType.getCertificate()); + } + } + + /** + * Method returns all EndpointTypes + * + * @param smd + * @return + */ + public List<EndpointType> searchAllEndpoints(ServiceMetadata smd) { + List<ProcessType> processTypeList = smd.getServiceInformation() != null ? + smd.getServiceInformation().getProcessList().getProcesses() : Collections.emptyList(); + + List<EndpointType> endpointTypeList = new ArrayList<>(); + processTypeList.stream().forEach(processType -> endpointTypeList.addAll(processType.getServiceEndpointList() != null ? + processType.getServiceEndpointList().getEndpoints() : Collections.emptyList())); + + return endpointTypeList; + } + + /** + * Validate the certificate + * + * @param crtData x509 encoded byte array + * @throws CertificateException + */ + public void validateCertificate(byte[] crtData) throws CertificateException { + if (crtData == null || crtData.length == 0) { + LOG.debug("Skip certificate validation: Empty certificate."); + return; + } + X509Certificate cert = X509CertificateUtils.getX509Certificate(crtData); + // validate is certificate is valid + cert.checkValidity(); + // validate if certificate has the right key algorithm + PublicKey key = cert.getPublicKey(); + List<String> allowedKeyAlgs = configurationService.getAllowedDocumentCertificateTypes(); + if (allowedKeyAlgs == null || allowedKeyAlgs.isEmpty()) { + LOG.debug("Ignore the service metadata certificate key type validation (Empty property: [{}]).", DOCUMENT_RESTRICTION_CERT_TYPES.getProperty()); + return; + } + + if (StringUtils.equalsAnyIgnoreCase(key.getAlgorithm(), allowedKeyAlgs.toArray(new String[]{}))) { + LOG.debug("Certificate has valid key algorithm [{}]. Allowed algorithms: [{}] .", key.getAlgorithm(), allowedKeyAlgs); + return; + } + LOG.debug("Certificate has invalid key algorithm [{}]. Allowed algorithms: [{}] .", key.getAlgorithm(), allowedKeyAlgs); + throw new CertificateException("Certificate does not have allowed key type!"); + } } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java index f074781cebab3b6c9f583a06f3547d3d1d027885..53f20f7f87694359160174bd986759f04c57f9fa 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java @@ -262,6 +262,28 @@ public class UITruststoreService { certificateValidator.validateCertificate(x509Certificate); } + /** + * Method validates if certificate public key algorithm is allowed. If the allowedCertificateKeyType list is null or empty, then + * then all certificate types are allowed. + * + * @param x509Certificate certificate to validate + * @throws CertificateException + */ + public void validateAllowedCertificateKeyTypes(X509Certificate x509Certificate) throws CertificateException { + List<String> allowedCertificateKeyTypes = configurationService.getAllowedCertificateKeyTypes(); + if (allowedCertificateKeyTypes == null + || allowedCertificateKeyTypes.isEmpty()) { + LOG.debug("No certificate key types configured. Skip certificate key validation."); + return; + } + PublicKey certKey = x509Certificate.getPublicKey(); + if (!StringUtils.equalsAnyIgnoreCase(certKey.getAlgorithm(), allowedCertificateKeyTypes.toArray(new String[]{}))) { + throw new CertificateException("Certificate does not have allowed key algorithm type! Key type [" + + certKey.getAlgorithm() + "] Allowed values [" + + allowedCertificateKeyTypes + "]!"); + } + } + public void checkFullCertificateValidity(X509Certificate cert) throws CertificateException { // test if certificate is valid cert.checkValidity(); @@ -276,6 +298,8 @@ public class UITruststoreService { throw new CertificateNotTrustedException("Certificate is not trusted!"); } + // validate if certificate key type is valid + validateAllowedCertificateKeyTypes(cert); if (trustStore != null) { validateCertificateWithTruststore(cert); @@ -378,7 +402,7 @@ public class UITruststoreService { } try (InputStream truststoreInputStream = new FileInputStream(truststoreFile)) { - String type = StringUtils.defaultIfEmpty(configurationService.getTruststoreType(),"JKS"); + String type = StringUtils.defaultIfEmpty(configurationService.getTruststoreType(), "JKS"); LOG.info("Load truststore [{}] with type [{}].", truststoreFile, type); KeyStore loadedTrustStore = KeyStore.getInstance(type); loadedTrustStore.load(truststoreInputStream, token.toCharArray()); diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupSearchServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupSearchServiceTest.java index 482ea516178230dd8041a563220219d667ab8747..28de4e7f9f415dcc5ac8e4bedd90fa536d99f7fe 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupSearchServiceTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupSearchServiceTest.java @@ -7,9 +7,7 @@ import eu.europa.ec.edelivery.smp.data.ui.ServiceResult; import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest; import eu.europa.ec.edelivery.smp.testutil.TestConstants; import eu.europa.ec.edelivery.smp.testutil.TestDBUtils; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; @@ -20,8 +18,6 @@ import static org.junit.Assert.assertNull; @ContextConfiguration(classes = {UIServiceGroupSearchService.class, UIServiceMetadataService.class}) public class UIServiceGroupSearchServiceTest extends AbstractServiceIntegrationTest { - @Rule - public ExpectedException expectedExeption = ExpectedException.none(); @Autowired protected UIServiceGroupSearchService testInstance; diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java index 7ec4adeacda723fd21a38b70cd399e5bee1aae31..e8341afead0bc11e0cb89c73648f5ef5d37ea941 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java @@ -1,16 +1,30 @@ package eu.europa.ec.edelivery.smp.services.ui; +import eu.europa.ec.edelivery.smp.conversion.CaseSensitivityNormalizer; +import eu.europa.ec.edelivery.smp.conversion.ServiceMetadataConverter; +import eu.europa.ec.edelivery.smp.data.dao.DomainDao; +import eu.europa.ec.edelivery.smp.data.dao.ServiceMetadataDao; +import eu.europa.ec.edelivery.smp.data.dao.UserDao; import eu.europa.ec.edelivery.smp.data.model.DBServiceMetadata; import eu.europa.ec.edelivery.smp.data.ui.ServiceMetadataRO; import eu.europa.ec.edelivery.smp.data.ui.ServiceMetadataValidationRO; import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest; +import eu.europa.ec.edelivery.smp.services.ConfigurationService; import eu.europa.ec.edelivery.smp.testutil.TestDBUtils; +import eu.europa.ec.edelivery.smp.testutil.XmlTestUtils; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; +import org.oasis_open.docs.bdxr.ns.smp._2016._05.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.transaction.annotation.Transactional; +import java.io.IOException; +import java.security.cert.CertificateException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Optional; import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*; @@ -20,9 +34,13 @@ import static org.junit.Assert.*; @ContextConfiguration(classes = {UIServiceGroupSearchService.class, UIServiceMetadataService.class}) public class UIServiceMetadataServiceTest extends AbstractServiceIntegrationTest { + private static final String RES_PATH = "/examples/services/"; + private static final String RES_PATH_CONV = "/examples/conversion/"; + @Autowired protected UIServiceMetadataService testInstance; + @Before @Transactional public void prepareDatabase() { @@ -132,4 +150,70 @@ public class UIServiceMetadataServiceTest extends AbstractServiceIntegrationTest smv = testInstance.validateServiceMetadata(smv); assertEquals("SAXParseException: Content is not allowed in trailing section.",smv.getErrorMessage()); } + + @Test + public void testSearchAllEndpoints() throws IOException { + //given + byte[] inputDoc = XmlTestUtils.loadDocumentAsByteArray(RES_PATH + "ServiceMetadataDifferentCertificatesTypes.xml"); + ServiceMetadata serviceMetadata = ServiceMetadataConverter.unmarshal(inputDoc); + + List<EndpointType> endpointTypeList = testInstance.searchAllEndpoints(serviceMetadata); + assertEquals(3, endpointTypeList.size()); + } + + @Test + public void testSearchAllEndpointsEmptyList() throws IOException { + //given + byte[] inputDoc = XmlTestUtils.loadDocumentAsByteArray(RES_PATH_CONV + "ServiceMetadataWithRedirect.xml"); + ServiceMetadata serviceMetadata = ServiceMetadataConverter.unmarshal(inputDoc); + + List<EndpointType> endpointTypeList = testInstance.searchAllEndpoints(serviceMetadata); + assertEquals(0, endpointTypeList.size()); + } + + @Test + public void testValidateServiceMetadataCertificatesEmptyOK() throws IOException, CertificateException { + //given + byte[] inputDoc = XmlTestUtils.loadDocumentAsByteArray(RES_PATH + "ServiceMetadataDifferentCertificatesTypes.xml"); + ServiceMetadata serviceMetadata = ServiceMetadataConverter.unmarshal(inputDoc); + // then + testInstance.validateServiceMetadataCertificates(serviceMetadata); + // no error is expected + } + + @Test + public void testValidateServiceMetadataCertificatesRSAOK() throws IOException, CertificateException { + ConfigurationService configurationService = Mockito.mock(ConfigurationService.class); + UIServiceMetadataService testInstance = new UIServiceMetadataService(null, null, + null, null, + configurationService); + + Mockito.doReturn(Arrays.asList("RSA","ED25519","ED448")).when(configurationService).getAllowedDocumentCertificateTypes(); + + //given + byte[] inputDoc = XmlTestUtils.loadDocumentAsByteArray(RES_PATH + "ServiceMetadataDifferentCertificatesTypes.xml"); + ServiceMetadata serviceMetadata = ServiceMetadataConverter.unmarshal(inputDoc); + // then + testInstance.validateServiceMetadataCertificates(serviceMetadata); + + } + + @Test + public void testValidateServiceMetadataCertificatesNotAllowed() throws IOException, CertificateException { + ConfigurationService configurationService = Mockito.mock(ConfigurationService.class); + UIServiceMetadataService testInstance = new UIServiceMetadataService(null, null, + null, null, + configurationService); + + Mockito.doReturn(Collections.singletonList("testKeyAlg")).when(configurationService).getAllowedDocumentCertificateTypes(); + + //given + byte[] inputDoc = XmlTestUtils.loadDocumentAsByteArray(RES_PATH + "ServiceMetadataDifferentCertificatesTypes.xml"); + ServiceMetadata serviceMetadata = ServiceMetadataConverter.unmarshal(inputDoc); + // then + CertificateException result = assertThrows(CertificateException.class, () -> testInstance.validateServiceMetadataCertificates(serviceMetadata)); + // no error is expected + assertEquals("Certificate does not have allowed key type!", result.getMessage()); + + } } \ No newline at end of file diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceIntegrationTest.java index 652e735f1144f5085fd2e26bef362ef412877468..e3ebcda827d35bea5b763fd4bafc888f3856bd1d 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceIntegrationTest.java @@ -13,9 +13,7 @@ import org.apache.commons.io.IOUtils; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; @@ -30,11 +28,11 @@ import java.math.BigInteger; import java.nio.file.Path; import java.nio.file.Paths; import java.security.cert.*; +import java.time.OffsetDateTime; import java.util.*; import static org.junit.Assert.*; - @RunWith(SpringJUnit4ClassRunner.class) public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrationTest { @@ -54,9 +52,6 @@ public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrati Path resourceDirectory = Paths.get("src", "test", "resources", "truststore"); Path targetDirectory = Paths.get("target", "truststore"); - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - @Autowired protected UITruststoreService testInstance; @@ -261,34 +256,33 @@ public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrati public void testCheckFullCertificateValidityNotYetValid() throws Exception { // given String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; - Calendar from = Calendar.getInstance(); - Calendar to = Calendar.getInstance(); - to.add(Calendar.DAY_OF_YEAR, 2); - from.add(Calendar.DAY_OF_YEAR, 1); - X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( - "10af", certSubject, certSubject, from.getTime(), to.getTime(), Collections.emptyList()); - - //then - expectedEx.expect(CertificateNotYetValidException.class); + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest("10af", certSubject, certSubject, + OffsetDateTime.now().plusDays(1), + OffsetDateTime.now().plusDays(1), + Collections.emptyList()); // when - testInstance.checkFullCertificateValidity(certificate); + CertificateNotYetValidException result = assertThrows(CertificateNotYetValidException.class, () -> + testInstance.checkFullCertificateValidity(certificate)); + //then + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("certificate not valid till")); } @Test public void testCheckFullCertificateValidityExpired() throws Exception { // given String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; - Calendar from = Calendar.getInstance(); - Calendar to = Calendar.getInstance(); - to.add(Calendar.DAY_OF_YEAR, -1); - from.add(Calendar.DAY_OF_YEAR, -2); + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( - "10af", certSubject, certSubject, from.getTime(), to.getTime(), Collections.emptyList()); + "10af", certSubject, certSubject, + OffsetDateTime.now().minusDays(2), + OffsetDateTime.now().minusDays(1), + Collections.emptyList()); - //then - expectedEx.expect(CertificateExpiredException.class); // when - testInstance.checkFullCertificateValidity(certificate); + CertificateExpiredException result = assertThrows(CertificateExpiredException.class, () -> + testInstance.checkFullCertificateValidity(certificate)); + //then + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("certificate expired")); } @Test @@ -306,11 +300,16 @@ public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrati to.add(Calendar.DAY_OF_YEAR, 1); from.add(Calendar.DAY_OF_YEAR, -2); X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( - revokedSerialFromList, S_SUBJECT_PEPPOL_NOT_TRUSTED, S_SUBJECT_PEPPOL_NOT_TRUSTED, from.getTime(), to.getTime(), Collections.singletonList(crlUrl)); - //then - expectedEx.expect(CertificateNotTrustedException.class); + revokedSerialFromList, S_SUBJECT_PEPPOL_NOT_TRUSTED, S_SUBJECT_PEPPOL_NOT_TRUSTED, + OffsetDateTime.now().minusDays(2), + OffsetDateTime.now().plusYears(1), + Collections.singletonList(crlUrl)); + // when - testInstance.checkFullCertificateValidity(certificate); + CertificateNotTrustedException result = assertThrows(CertificateNotTrustedException.class, () -> + testInstance.checkFullCertificateValidity(certificate)); + //then + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Certificate is not trusted!")); } @@ -325,20 +324,40 @@ public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrati Mockito.doReturn(crl).when(crlVerifierService).downloadCRL(ArgumentMatchers.eq(crlUrl), ArgumentMatchers.anyBoolean()); String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; - Calendar from = Calendar.getInstance(); - Calendar to = Calendar.getInstance(); - to.add(Calendar.DAY_OF_YEAR, 1); - from.add(Calendar.DAY_OF_YEAR, -2); X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( - revokedSerialFromList, certSubject, certSubject, from.getTime(), to.getTime(), Collections.singletonList(crlUrl)); + revokedSerialFromList, certSubject, certSubject, + OffsetDateTime.now().minusDays(2), + OffsetDateTime.now().plusYears(1), + Collections.singletonList(crlUrl)); // add as trusted certificate testInstance.addCertificate(UUID.randomUUID().toString(), certificate); + // when + CertificateRevokedException result = assertThrows(CertificateRevokedException.class, () -> + testInstance.checkFullCertificateValidity(certificate)); + //then + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Certificate has been revoked")); + } + + @Test + public void testCheckFullCertificateValidityInvalidKey() throws Exception { + // given + String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( + null, certSubject, certSubject, + OffsetDateTime.now().minusDays(2), + OffsetDateTime.now().plusYears(1), + Collections.emptyList() + ); + Mockito.doReturn(Arrays.asList("InvalidKeyTest")).when(configurationService).getAllowedCertificateKeyTypes(); + // add as trusted certificate + testInstance.addCertificate(UUID.randomUUID().toString(), certificate); + + CertificateException result = assertThrows(CertificateException.class, () -> + testInstance.checkFullCertificateValidity(certificate)); //then - expectedEx.expect(CertificateRevokedException.class); - // when - testInstance.checkFullCertificateValidity(certificate); + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Certificate does not have allowed key algorithm type!")); } @Test @@ -352,12 +371,11 @@ public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrati Mockito.doThrow(new SMPRuntimeException(ErrorCode.CERTIFICATE_ERROR, "Error occurred while downloading CRL:" + crlUrl, "")).when(crlVerifierService).downloadURL(crlUrl); String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; - Calendar from = Calendar.getInstance(); - Calendar to = Calendar.getInstance(); - to.add(Calendar.DAY_OF_YEAR, 1); - from.add(Calendar.DAY_OF_YEAR, -2); X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( - revokedSerialFromList, certSubject, certSubject, from.getTime(), to.getTime(), Collections.singletonList(crlUrl)); + revokedSerialFromList, certSubject, certSubject, + OffsetDateTime.now().minusDays(2), + OffsetDateTime.now().plusYears(1), + Collections.singletonList(crlUrl)); // add as trusted certificate testInstance.addCertificate(UUID.randomUUID().toString(), certificate); @@ -371,19 +389,13 @@ public class UITruststoreServiceIntegrationTest extends AbstractServiceIntegrati public void testCheckFullCertificateValidityOK() throws Exception { // given String crlUrl = "https://localhost/crl"; - String serialNotInList = "20011FF"; CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509CRL crl = (X509CRL) cf.generateCRL(getClass().getResourceAsStream("/certificates/smp-crl-test.crl")); Mockito.doReturn(crl).when(crlVerifierService).downloadCRL(crlUrl, true); String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; - Calendar from = Calendar.getInstance(); - Calendar to = Calendar.getInstance(); - to.add(Calendar.DAY_OF_YEAR, 1); - from.add(Calendar.DAY_OF_YEAR, -2); - X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest( - serialNotInList, certSubject, certSubject, from.getTime(), to.getTime(), Collections.singletonList(crlUrl)); + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest(certSubject); // add as trusted certificate testInstance.addCertificate(UUID.randomUUID().toString(), certificate); diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java index f027304a457fee8416314387732e283199041384..45cf76ac640e52a64b0cf86188931a02d822da76 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java @@ -62,7 +62,7 @@ public class TestConstants { public static final String SIMPLE_EXTENSION_XML ="<Extension xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ex:dummynode xmlns:ex=\"http://test.eu\">Sample not mandatory extension: %s</ex:dummynode></Extension>"; //5 parameters: ParticipantScheme, ParticipantIdentifier, DocumentScheme, DocumentIdentifier, custom value public static final String SIMPLE_DOCUMENT_XML = "<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ServiceInformation><ParticipantIdentifier scheme=\"%s\">%s</ParticipantIdentifier><DocumentIdentifier scheme=\"%s\">%s</DocumentIdentifier><ProcessList><Process><ProcessIdentifier scheme=\"cenbii-procid-ubl\">urn:www.cenbii.eu:profile:bii04:ver1.0</ProcessIdentifier><ServiceEndpointList><Endpoint transportProfile=\"bdxr-transport-ebms3-as4-v1p0\"><EndpointURI>http://localhost:8080/domibus-weblogic/services/msh</EndpointURI><RequireBusinessLevelSignature>true</RequireBusinessLevelSignature><ServiceActivationDate>2003-01-01T00:00:00</ServiceActivationDate><ServiceExpirationDate>2099-05-01T00:00:00</ServiceExpirationDate>" + - "<Certificate>VGhpcyBpcyB0ZXN0IGNlcnRpZmljYXRlIGlzIHlvdSBiZWxpZXZlIG9yIG5vdC4=</Certificate><ServiceDescription>Sample description of %s</ServiceDescription><TechnicalContactUrl>https://example.com</TechnicalContactUrl></Endpoint></ServiceEndpointList></Process></ProcessList></ServiceInformation></ServiceMetadata>"; + "<Certificate>MIID7jCCA1egAwIBAgICA+YwDQYJKoZIhvcNAQENBQAwOjELMAkGA1UEBhMCRlIxEzARBgNVBAoMCklIRSBFdXJvcGUxFjAUBgNVBAMMDUlIRSBFdXJvcGUgQ0EwHhcNMTYwNjAxMTQzNTUzWhcNMjYwNjAxMTQzNTUzWjCBgzELMAkGA1UEBhMCUFQxDDAKBgNVBAoMA01vSDENMAsGA1UECwwEU1BNUzENMAsGA1UEKgwESm9hbzEOMAwGA1UEBRMFQ3VuaGExHTAbBgNVBAMMFHFhZXBzb3MubWluLXNhdWRlLnB0MRkwFwYDVQQMDBBTZXJ2aWNlIFByb3ZpZGVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1eN4qPSSRZqjVFG9TlcPlxf2WiSimQK9L1nf9Z/s0ezeGQjCukDeDq/Wzqd9fpHhaMMq+XSSOtyEtIr5K/As4kFrViONUUkG12J6UllSWogp0NYFwA4wIqKSFiTnQS5/nRTs05oONCCGILCyJNNeO53JzPlaq3/QbPLssuSAr6XucPE8wBBGM8b/TsB2G/zjG8yuSTgGbhaZekq/Vnf9ftj1fr/vJDDAQgH6Yvzd88Z0DACJPHfW1p4F/OWLI386Bq7g/bo1DUPAyEwlf+CkLgJWRKki3yJlOCIZ9enMA5O7rfeG3rXdgYGmWS7tNEgKXxgC+heiYvi7ZWd7M+/SUwIDAQABo4IBMzCCAS8wPgYDVR0fBDcwNTAzoDGgL4YtaHR0cHM6Ly9nYXplbGxlLmloZS5uZXQvcGtpL2NybC82NDMvY2FjcmwuY3JsMDwGCWCGSAGG+EIBBAQvFi1odHRwczovL2dhemVsbGUuaWhlLm5ldC9wa2kvY3JsLzY0My9jYWNybC5jcmwwPAYJYIZIAYb4QgEDBC8WLWh0dHBzOi8vZ2F6ZWxsZS5paGUubmV0L3BraS9jcmwvNjQzL2NhY3JsLmNybDAfBgNVHSMEGDAWgBTsMw4TyCJeouFrr0N7el3Sd3MdfjAdBgNVHQ4EFgQU1GQ/K1ykIwWFgiONzWJLQzufF/8wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBSAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQENBQADgYEAZ7t1Qkr9wz3q6+WcF6p/YX7Jr0CzVe7w58FvJFk2AsHeYkSlOyO5hxNpQbs1L1v6JrcqziNFrh2QKGT2v6iPdWtdCT8HBLjmuvVWxxnfzYjdQ0J+kdKMAEV6EtWU78OqL60CCtUZKXE/NKJUq7TTUCFP2fwiARy/t1dTD2NZo8c=</Certificate><ServiceDescription>Sample description of %s</ServiceDescription><TechnicalContactUrl>https://example.com</TechnicalContactUrl></Endpoint></ServiceEndpointList></Process></ProcessList></ServiceInformation></ServiceMetadata>"; public static final String SIMPLE_REDIRECT_DOCUMENT_XML ="<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\">" + " <Redirect href=\"%s\">" + diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java index a10bc9d5895cd2a28b7a8ab3a1319c457145e179..afb35fca9b2bed1bbf48e1da93e1470e4e256f79 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java @@ -1,6 +1,5 @@ package eu.europa.ec.edelivery.smp.testutil; -import com.sun.org.apache.bcel.internal.generic.ARETURN; import eu.europa.ec.edelivery.smp.data.model.*; import eu.europa.ec.edelivery.smp.data.ui.enums.AlertLevelEnum; import eu.europa.ec.edelivery.smp.data.ui.enums.AlertStatusEnum; @@ -26,7 +25,7 @@ public class TestDBUtils { } public static DBAlert createDBAlert(String username) { - return createDBAlert(username, "mail-subject", "mail.to@test.eu",AlertLevelEnum.MEDIUM, AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION); + return createDBAlert(username, "mail-subject", "mail.to@test.eu", AlertLevelEnum.MEDIUM, AlertTypeEnum.CREDENTIAL_IMMINENT_EXPIRATION); } public static DBAlert createDBAlert(String username, String mailSubject, diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java index f02a0a01ab44bb3bf332bc77491fb983c53923a1..3a0a21a385939ad92080517fe47329ad3e60c188 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/X509CertificateTestUtils.java @@ -1,95 +1,47 @@ package eu.europa.ec.edelivery.smp.testutil; +import eu.europa.ec.edelivery.security.utils.CertificateKeyType; import eu.europa.ec.edelivery.security.utils.X509CertificateUtils; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.*; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.asn1.x509.KeyUsage; -import java.io.FileInputStream; import java.math.BigInteger; import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.time.OffsetDateTime; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Collections; +import java.util.List; public class X509CertificateTestUtils { - public static X509Certificate createX509CertificateForTest( String subject) throws Exception { - Calendar from = Calendar.getInstance(); - Calendar to = Calendar.getInstance(); - to.add(Calendar.DAY_OF_YEAR, 1); - from.add(Calendar.DAY_OF_YEAR, -1); - return createX509CertificateForTest("1234321", subject, subject, from.getTime(), to.getTime(), Collections.emptyList()); + public static X509Certificate createX509CertificateForTest(String subject) throws Exception { + return createX509CertificateForTest(null, subject, subject, + OffsetDateTime.now().minusDays(1), + OffsetDateTime.now().plusYears(1), Collections.emptyList()); } - public static X509Certificate createX509CertificateForTest(String serialNumber, String issuer, String subject, Date startDate, Date expiryDate, List<String> distributionList) throws Exception { + public static X509Certificate createX509CertificateForTest(String serialNumber, + String issuer, String subject, + OffsetDateTime startDate, OffsetDateTime expiryDate, + List<String> distributionList) throws Exception { - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(1024); - KeyPair key = keyGen.generateKeyPair(); - X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(new X500Name(issuer), new BigInteger(serialNumber, 16), startDate, expiryDate, new X500Name(subject), SubjectPublicKeyInfo.getInstance(key.getPublic().getEncoded())); - if (!distributionList.isEmpty()) { - - List<DistributionPoint> distributionPoints = distributionList.stream().map(url -> { - DistributionPointName distPointOne = new DistributionPointName(new GeneralNames( - new GeneralName(GeneralName.uniformResourceIdentifier, url))); - - return new DistributionPoint(distPointOne, null, null); - }).collect(Collectors.toList()); - - certBuilder.addExtension(Extension.cRLDistributionPoints, false, new CRLDistPoint(distributionPoints.toArray(new DistributionPoint[]{}))); - } - - ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider("BC").build(key.getPrivate()); - return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(sigGen)); - } - - public static X509Certificate[] createCertificateChain(String[] subjects, Date startDate, Date expiryDate) throws Exception { - - String issuer = null; - PrivateKey issuerKey = null; - long iSerial = 10000; - X509Certificate[] certs = new X509Certificate[subjects.length]; - - int index = subjects.length; - for (String sbj: subjects){ - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(1024); - KeyPair key = keyGen.generateKeyPair(); - - X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(new X500Name(issuer ==null? sbj:issuer), - BigInteger.valueOf(iSerial++), startDate, expiryDate, new X500Name(sbj), - SubjectPublicKeyInfo.getInstance(key.getPublic().getEncoded())); - - ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WITHRSA") - .setProvider("BC").build(issuerKey ==null?key.getPrivate():issuerKey); - - certs[--index] = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(sigGen)); - issuer= sbj; - issuerKey = key.getPrivate(); - - } - return certs; + KeyPair key = X509CertificateUtils.generateKeyPair(CertificateKeyType.RSA_2048); + return X509CertificateUtils.generateCertificate( + serialNumber == null ? BigInteger.TEN : new BigInteger(serialNumber, 16), key.getPublic(), subject, startDate, expiryDate, issuer, + key.getPrivate(), false, -1, null, + distributionList, Collections.emptyList(), Collections.emptyList()); } + public static X509Certificate createX509CertificateForTest(String subject, BigInteger serial, List<String> listOfPolicyOIDs) throws Exception { - public static X509Certificate createX509CertificateForTest( String subject, BigInteger serial, List<String> listOfPolicyOIDs) throws Exception { - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(2048); - KeyPair key = keyGen.generateKeyPair(); + KeyPair key = X509CertificateUtils.generateKeyPair(CertificateKeyType.RSA_2048); KeyUsage usage = new KeyUsage(244); - X509Certificate cert = X509CertificateUtils.createCertificate(serial, + X509Certificate cert = X509CertificateUtils.generateCertificate(serial, key.getPublic(), subject, OffsetDateTime.now().minusDays(1L), - OffsetDateTime.now().plusYears(5L), (String)null, - key.getPrivate(), false, -1, usage, "SHA256withRSA",listOfPolicyOIDs); + OffsetDateTime.now().plusYears(5L), (String) null, + key.getPrivate(), false, -1, usage, + Collections.emptyList(), Collections.emptyList(), + listOfPolicyOIDs); return cert; } diff --git a/smp-server-library/src/test/resources/examples/services/ServiceMetadataDifferentCertificatesTypes.xml b/smp-server-library/src/test/resources/examples/services/ServiceMetadataDifferentCertificatesTypes.xml new file mode 100644 index 0000000000000000000000000000000000000000..d582d81beb9cbbba0d7a5a910184b5091c74cd7b --- /dev/null +++ b/smp-server-library/src/test/resources/examples/services/ServiceMetadataDifferentCertificatesTypes.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<ServiceMetadata xmlns="http://docs.oasis-open.org/bdxr/ns/SMP/2016/05"> + <ServiceInformation> + <ParticipantIdentifier scheme="eHealth-participantId-qns">urn:Poland:ncpb</ParticipantIdentifier> + <DocumentIdentifier scheme="eHealth-resId-qns">DocId.007</DocumentIdentifier> + <ProcessList> + <Process> + <ProcessIdentifier scheme="ehealth-procid-qns">urn:epsosPatientService::List</ProcessIdentifier> + <ServiceEndpointList> + <Endpoint transportProfile="urn:rsa"> + <EndpointURI>http://poland.pl/ncp/patient/list</EndpointURI> + <RequireBusinessLevelSignature>false</RequireBusinessLevelSignature> + <MinimumAuthenticationLevel>urn:epSOS:loa:1</MinimumAuthenticationLevel> + <ServiceActivationDate>2016-06-06T11:06:02.000+02:00</ServiceActivationDate> + <ServiceExpirationDate>2126-06-06T11:06:02+02:00</ServiceExpirationDate> + <Certificate>MIIFMTCCAxmgAwIBAgICEBAwDQYJKoZIhvcNAQELBQAwgbwxCzAJBgNVBAYTAkJFMRAwDgYDVQQIDAdCZWxnaXVtMRowGAYDVQQKDBFDb25uZWN0aXZpdHkgVGVzdDEjMCEGA1UECwwaQ29ubmVjdGluZyBFdXJvcGUgRmFjaWxpdHkxJzAlBgNVBAMMHkNvbm5lY3Rpdml0eSBUZXN0IENvbXBvbmVudCBDQTExMC8GCSqGSIb3DQEJARYiQ0VGLUVERUxJVkVSWS1TVVBQT1JUQGVjLmV1cm9wYS5ldTAeFw0xNzEwMTIxMjU3NDJaFw0yODAxMTgxMjU3NDJaMIG1MQswCQYDVQQGEwJQTDEsMCoGA1UECgwjREXhup7Dn8OEw6RQTMW8w7PFgsSHTk/DhsOmw5jDuMOFw6UxeDB2BgNVBAMMb3NsYXNoL2JhY2tzbGFzaFxxdW90ZSJjb2xvbjpfcmZjMjI1M3NwZWNpYWxfYW1wZXJzYW5kJmNvbW1hLGVxdWFscz1wbHVzK2xlc3N0aGFuPGdyZWF0ZXJ0aGFuPmhhc2gjc2VtaWNvbG9uO2VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAudajaE8sHeL7qWied2Nf0dEreOLu+cDIluWBczKF7hxmRJ4VJ3y/TN/SilBN1gqBCJtsiGhsf66w5dIPJFNHj68YL5Evi5lkfLqMNRbKN08oLN6T2aIEcg+/T4OLyonNLrUMtOkpAi3swKTanOLwOqp/cu53Vgi94FfvCzCtkgkCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRpZmljYXRlMB0GA1UdDgQWBBR3wx7TpvKZzhO3cWBTSkXrcJVPfjAfBgNVHSMEGDAWgBS96Nd21/ujY1YLoaLGA7dspLBPLTAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQAoVlGu/1u1HSmPDnn1dJalBG2yfBpcmiu163FSCiF4o5PDZfSEMbIMVkw1HsA3b78uhfduP/yaGICzqqCEKBA4dYeFiFCkkuJZD/c3MeFp8h646BzwFrAOWXOEhtg+Afl5fRAJQ64zJ8igGybP4GsrHt1282waKkfE+DRWTvU81tyA98GpG/gRJY8VvCyu3Is9za2xr9RtGjXWI1cdwIkTXk6GoLjUaH6QIb9ewuYGEVNPZmV6qFqqfCU54z7lPw5G7wvE86ggIszixbpUK2IGKLNonpyKe0UFUB9uhRbcynCYbJWpVykZLQ1noRna4XMkfEvmknzA7bJd6WBX82yDXYE6omFqJ5JB6iNt/yswF7cZ2sRKwbsl6P1Z3Lhj2qYYdEt73TQwztY9ZBwpriG5E4RaZzolpTzZ3GkzLPv1kww+MFCW4H7M6M1sMpOYDq+hCw8EGzTn2QTuqtzPJr9n3tlTkKif78h1mooxHlyDjuky4Fhh3tzjblLf+e9lZh8H8XTBCHvG7nilKwhY93RipP2av6hw1l+l1vqj/1KM9DFWuWZhp3koyBw4RuyH5OPgHBBczft/XmLeuFjw+bv7Qle5ObxcLbaJzusgKgl5D1982YejA8Tnw4bbMXk0WmFiaEA39keusEjKG4JGAy1RZdJuDISR6pANGDENYsFSPw==</Certificate> + <ServiceDescription>Standard RSA Certificate</ServiceDescription> + <TechnicalContactUrl>http://poland.pl/contact</TechnicalContactUrl> + <TechnicalInformationUrl>http://poland.pl/contact</TechnicalInformationUrl> + </Endpoint> + </ServiceEndpointList> + </Process> + <Process> + <ProcessIdentifier scheme="ehealth-procid-qns">urn:epsosPatientService::with new EC cryptography</ProcessIdentifier> + <ServiceEndpointList> + <Endpoint transportProfile="urn:Ed25519"> + <EndpointURI>http://poland.pl/ncp/patient/list</EndpointURI> + <RequireBusinessLevelSignature>false</RequireBusinessLevelSignature> + <MinimumAuthenticationLevel>urn:epSOS:loa:1</MinimumAuthenticationLevel> + <ServiceActivationDate>2016-06-06T11:06:02.000+02:00</ServiceActivationDate> + <ServiceExpirationDate>2126-06-06T11:06:02+02:00</ServiceExpirationDate> + <Certificate>MIIBDzCBwqADAgECAgInEDAFBgMrZXAwMTESMBAGA1UEAwwJRWQyNTUxOU9VMQ4wDAYDVQQKDAVESUdJVDELMAkGA1UEBhMCRVUwHhcNMjIxMTEwMDY0MDU2WhcNMzIxMTA4MDY0MDU2WjAxMRIwEAYDVQQDDAlFZDI1NTE5T1UxDjAMBgNVBAoMBURJR0lUMQswCQYDVQQGEwJFVTAqMAUGAytlcAMhACV5KjHOUQNfSDrRH2jYaWLDRenGEwPw3LfuNTeX9MeKMAUGAytlcANBAIey/CoiU7vLRy//4n8yyQK5nNKQjZIvMrMlP+m1gjEaPat0JK7REji2+dx9IKpfPQbGNsfERQGe6rKO09mbwgQ=</Certificate> + <ServiceDescription>Ed25519 Certificate</ServiceDescription> + <TechnicalContactUrl>http://poland.pl/contact</TechnicalContactUrl> + <TechnicalInformationUrl>http://poland.pl/contact</TechnicalInformationUrl> + </Endpoint> + <Endpoint transportProfile="urn:Ed448"> + <EndpointURI>http://poland.pl/ncp/patient/list</EndpointURI> + <RequireBusinessLevelSignature>false</RequireBusinessLevelSignature> + <MinimumAuthenticationLevel>urn:epSOS:loa:1</MinimumAuthenticationLevel> + <ServiceActivationDate>2016-06-06T11:06:02.000+02:00</ServiceActivationDate> + <ServiceExpirationDate>2126-06-06T11:06:02+02:00</ServiceExpirationDate> + <Certificate>MIIBVjCB16ADAgECAgInEDAFBgMrZXEwLzEQMA4GA1UEAwwHRWQ0NDhPVTEOMAwGA1UECgwFRElHSVQxCzAJBgNVBAYTAkVVMB4XDTIyMTExMDA2NDA1NVoXDTMyMTEwODA2NDA1NVowLzEQMA4GA1UEAwwHRWQ0NDhPVTEOMAwGA1UECgwFRElHSVQxCzAJBgNVBAYTAkVVMEMwBQYDK2VxAzoAwI2wUoTacfINA2X1SFc0tGGaWuXKOAHmAqkChKvvP4uoSKUh+gr/FThAFCWwh06IozLIr7MI924AMAUGAytlcQNzAJqlqdSgE/6w4YxKFnJsbYdTkTTTVZ+uudr976NsInRNJdOo8KdUBq0JSQ5OFMYqWB0gDn2ha55kgE+531iLljpGBUezKTpW6x7S/Crx3fTtX3T0v2+785Zc0ShsuIYR0atOFldA9VJbh3osnRlAJ/E5AA==</Certificate> + <ServiceDescription>Ed25519 Certificate</ServiceDescription> + <TechnicalContactUrl>http://poland.pl/contact</TechnicalContactUrl> + <TechnicalInformationUrl>http://poland.pl/contact</TechnicalInformationUrl> + </Endpoint> + </ServiceEndpointList> + </Process> + </ProcessList> + </ServiceInformation> +</ServiceMetadata> \ No newline at end of file diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl index 4ef6624f6504c2e945a9a964e26e8b350717398a..c486d9b35b617885d38f8e04d235da948a247a99 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl @@ -122,7 +122,7 @@ SML_BLUE_COAT_AUTH bit not null comment 'Flag for SML authentication type - use ClientCert header or HTTPS ClientCertificate (key)', SML_CLIENT_CERT_HEADER varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin comment 'Client-Cert header used behind RP - ClientCertHeader for SML integration', SML_CLIENT_KEY_ALIAS varchar(256) CHARACTER SET utf8 COLLATE utf8_bin comment 'Client key alias used for SML integration', - SML_PARTC_IDENT_REGEXP varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin comment 'Reqular expresion for participant ids', + SML_PARTC_IDENT_REGEXP varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin comment 'Regular expresion for participant ids', SML_REGISTERED bit not null comment 'Flag for: Is domain registered in SML', SML_SMP_ID varchar(256) CHARACTER SET utf8 COLLATE utf8_bin comment 'SMP ID used for SML integration', SML_SUBDOMAIN varchar(256) CHARACTER SET utf8 COLLATE utf8_bin comment 'SML subdomain', diff --git a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl index c87600879d218d6f87009ef2c55203d047e55e27..55ff05abe62c6e1412cc5efef0010f4f3dfb9320 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl @@ -213,7 +213,7 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; 'Client key alias used for SML integration'; comment on column SMP_DOMAIN.SML_PARTC_IDENT_REGEXP is - 'Reqular expresion for participant ids'; + 'Regular expresion for participant ids'; comment on column SMP_DOMAIN.SML_REGISTERED is 'Flag for: Is domain registered in SML';