diff --git a/codestyle/checkstyle.xml b/codestyle/checkstyle.xml index f50e861..9bca361 100644 --- a/codestyle/checkstyle.xml +++ b/codestyle/checkstyle.xml @@ -44,6 +44,7 @@ + @@ -315,4 +316,4 @@ - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index a9f068f..44644fd 100644 --- a/pom.xml +++ b/pom.xml @@ -32,10 +32,9 @@ UTF-8 8.3.1 - 2.1.0 1.5.5.Final 5.12.0 - 1.77 + 1.78.1 3.3.0 0.8.10 @@ -72,45 +71,6 @@ https://github.com/WorldHealthOrganization/tng-key-distribution - - - docker - - docker - jar - - - - - org.springframework.boot - spring-boot-maven-plugin - - ${project.build.directory}/docker - ddccg - - - - maven-assembly-plugin - - - make-zip-ACC - none - - - make-zip-test - none - - - make-zip-PRD - none - - - - - - - - who-github @@ -137,23 +97,10 @@ - - org.springframework - spring-web - 6.1.6 - - - org.springframework.boot - spring-boot-starter-web - org.springframework.boot spring-boot-starter-data-jpa - - org.springframework.boot - spring-boot-starter-validation - org.springframework.boot spring-boot-starter-actuator @@ -164,13 +111,23 @@ test - org.springdoc - springdoc-openapi-starter-webmvc-ui - ${springdoc.version} + org.springframework.boot + spring-boot-starter-web org.springframework.cloud spring-cloud-starter-openfeign + + + org.springframework + spring-web + + + + + org.springframework + spring-web + 6.1.6 @@ -226,6 +183,11 @@ + + com.github.ben-manes.caffeine + caffeine + 3.1.8 + org.eclipse.jgit org.eclipse.jgit @@ -252,14 +214,6 @@ org.springframework.boot spring-boot-maven-plugin - - - - repackage - build-info - - - org.apache.maven.plugins @@ -351,22 +305,6 @@ - - org.springdoc - springdoc-openapi-maven-plugin - 1.3 - - http://localhost:8080/api/docs - - - - integration-test - - generate - - - - diff --git a/src/main/java/tng/trustnetwork/keydistribution/KeyDistributionServiceApplication.java b/src/main/java/tng/trustnetwork/keydistribution/KeyDistributionServiceApplication.java index dd4b75e..ec29444 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/KeyDistributionServiceApplication.java +++ b/src/main/java/tng/trustnetwork/keydistribution/KeyDistributionServiceApplication.java @@ -33,7 +33,7 @@ @SpringBootApplication @EnableConfigurationProperties(KdsConfigProperties.class) @EnableFeignClients -public class KeyDistributionServiceApplication extends SpringBootServletInitializer { +public class KeyDistributionServiceApplication { /** * The main Method. diff --git a/src/main/java/tng/trustnetwork/keydistribution/config/ErrorHandler.java b/src/main/java/tng/trustnetwork/keydistribution/config/ErrorHandler.java deleted file mode 100644 index 9f19f45..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/config/ErrorHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.config; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.server.ResponseStatusException; -import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import tng.trustnetwork.keydistribution.exception.BadRequestException; -import tng.trustnetwork.keydistribution.restapi.dto.ProblemReportDto; - -@ControllerAdvice -@Configuration -@RequiredArgsConstructor -@Slf4j -public class ErrorHandler extends ResponseEntityExceptionHandler { - - /** - * Handles {@link BadRequestException} when a validation failed. - * - * @param e the thrown {@link BadRequestException} - * @return A ResponseEntity with a ErrorMessage inside. - */ - @ExceptionHandler(BadRequestException.class) - public ResponseEntity handleException(BadRequestException e) { - return ResponseEntity - .status(e.getStatus()) - .body(e.getMessage()); - } - - - /** - * Global Exception Handler to wrap exceptions into a readable JSON Object. - * - * @param e the thrown exception - * @return ResponseEntity with readable data. - */ - @ExceptionHandler(Exception.class) - public ResponseEntity handleException(Exception e) { - if (e instanceof ResponseStatusException) { - return ResponseEntity - .status(((ResponseStatusException) e).getStatusCode()) - .contentType(MediaType.APPLICATION_JSON) - .body(new ProblemReportDto("co", "prob", "val", "det")); - } else { - log.error("Uncatched exception", e); - return ResponseEntity - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .contentType(MediaType.APPLICATION_JSON) - .body(new ProblemReportDto("0x500", "Internal Server Error", "", "")); - } - } - - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java b/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java index 6d4b939..f4c3e11 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java +++ b/src/main/java/tng/trustnetwork/keydistribution/config/KdsConfigProperties.java @@ -43,8 +43,6 @@ public class KdsConfigProperties { private final DidConfig did = new DidConfig(); - private String context = ""; - /** * Http-Proxy Configuration. */ @@ -100,12 +98,14 @@ public static class DidConfig { private String didId; private String didController; + private String trustListPath; + private String trustListRefPath; + private String trustListIdPrefix; private String trustListControllerPrefix; private String ldProofVerificationMethod; private String ldProofDomain; - private String ldProofNonce; private String didSigningProvider; private String didUploadProvider; @@ -118,6 +118,9 @@ public static class DidConfig { private DgcGatewayConnectorConfigProperties.KeyStoreWithAlias localKeyStore = new DgcGatewayConnectorConfigProperties.KeyStoreWithAlias(); + + private List groupDenyList = new ArrayList<>(); + private Map groupNameMapping = new HashMap<>(); @Getter @Setter diff --git a/src/main/java/tng/trustnetwork/keydistribution/config/OpenApiConfig.java b/src/main/java/tng/trustnetwork/keydistribution/config/OpenApiConfig.java deleted file mode 100644 index f371ec8..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/config/OpenApiConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.config; - -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.info.Info; -import io.swagger.v3.oas.models.info.License; -import lombok.Generated; -import lombok.RequiredArgsConstructor; -import org.springframework.boot.info.BuildProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Generated -@Configuration -@RequiredArgsConstructor -public class OpenApiConfig { - - private final BuildProperties buildProperties; - - /** - * Configure the OpenApi bean with title and version. - * - * @return the OpenApi bean. - */ - @Bean - public OpenAPI openApi() { - return new OpenAPI() - .info(new Info() - .title("TNG Key Distribution Service") - .description("The API defines the key distribution service for digital green certificates.") - .version(buildProperties.getVersion()) - .license(new License() - .name("Apache 2.0") - .url("https://www.apache.org/licenses/LICENSE-2.0"))); - } -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/dto/TrustedIssuerDto.java b/src/main/java/tng/trustnetwork/keydistribution/dto/TrustedIssuerDto.java deleted file mode 100644 index 42e9cdf..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/dto/TrustedIssuerDto.java +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.dto; - -import java.time.ZonedDateTime; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class TrustedIssuerDto { - - private String url; - - private UrlTypeDto type; - - private String country; - - private String thumbprint; - - private String sslPublicKey; - - private String keyStorageType; - - private String signature; - - private ZonedDateTime timestamp; - - private String name; - - public enum UrlTypeDto { - HTTP, - DID - } -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/entity/InfoEntity.java b/src/main/java/tng/trustnetwork/keydistribution/entity/InfoEntity.java deleted file mode 100644 index 3a190f1..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/entity/InfoEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.entity; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "vs_info") -public class InfoEntity { - - /** - * The KID of the Key used to sign the CMS. - */ - @Id - @Column(name = "identifier_key") - private String identifierKey; - - /** - * Type of Revocation Hashes. - */ - @Column(name = "property_value") - private String value; - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/entity/SignerInformationEntity.java b/src/main/java/tng/trustnetwork/keydistribution/entity/SignerInformationEntity.java index 3e3a028..05bcfc2 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/entity/SignerInformationEntity.java +++ b/src/main/java/tng/trustnetwork/keydistribution/entity/SignerInformationEntity.java @@ -65,7 +65,7 @@ public class SignerInformationEntity { * Base64 encoded certificate raw data. */ @Column(name = "raw_data", nullable = false, length = 4096) - String rawData; + private String rawData; /** * The country code of the cert. @@ -80,17 +80,15 @@ public class SignerInformationEntity { private String domain; /** - * Timestamp of the last record update. + * The group of the cert. */ - @Column(name = "updated_at", nullable = false) - private ZonedDateTime updatedAt = ZonedDateTime.now(); + @Column(name = "groupx") + private String group; /** - * Marks the record as deleted. + * SHA-256 Hash-Value of Certificate Subject (hex). */ - @Column(name = "deleted") - private boolean deleted = false; - - + @Column(name = "subject_hash") + private String subjectHash; } diff --git a/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedIssuerEntity.java b/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedIssuerEntity.java index 5eb8ca0..57a37d0 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedIssuerEntity.java +++ b/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedIssuerEntity.java @@ -50,12 +50,6 @@ public class TrustedIssuerEntity { @Column(name = "id") private Long id; - /** - * The revoked hash. - */ - @Column(name = "etag", nullable = false, length = 36) - private String etag; - /** * Timestamp of the Record. */ diff --git a/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedPartyEntity.java b/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedPartyEntity.java deleted file mode 100644 index 3bb70cc..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/entity/TrustedPartyEntity.java +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.entity; - - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Data -@Getter -@Setter -@Entity -@Table(name = "trusted_party") -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class TrustedPartyEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - /** - * Base64 encoded certificate raw data. - */ - @Column(name = "raw_data", nullable = false, length = 4096) - String rawData; - - /** - * The country code of the cert. - */ - @Column(name = "country") - private String country; - - /** - * Type of the TrustedParty (CSCA, UPLOAD, Authentication - currently only CSCA are supported). - */ - @Column(name = "type") - @Enumerated(EnumType.STRING) - private Type type; - - - public enum Type { - CSCA - } - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/exception/BadRequestException.java b/src/main/java/tng/trustnetwork/keydistribution/exception/BadRequestException.java deleted file mode 100644 index a3fb5b2..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/exception/BadRequestException.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.exception; - -public class BadRequestException extends RuntimeException { - public int getStatus() { - return STATUS; - } - - private static final int STATUS = 400; - - - /** - * Constructor for BadRequestException. - * - * @param message Massage of the exception. - */ - public BadRequestException(String message) { - - super(message); - } - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/mapper/IssuerMapper.java b/src/main/java/tng/trustnetwork/keydistribution/mapper/IssuerMapper.java index 7b23f61..b0a6ae2 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/mapper/IssuerMapper.java +++ b/src/main/java/tng/trustnetwork/keydistribution/mapper/IssuerMapper.java @@ -24,7 +24,6 @@ import java.util.List; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import tng.trustnetwork.keydistribution.dto.TrustedIssuerDto; import tng.trustnetwork.keydistribution.entity.TrustedIssuerEntity; @Mapper(componentModel = "spring") @@ -32,18 +31,9 @@ public interface IssuerMapper { @Mapping(source = "type", target = "urlType") @Mapping(target = "id", ignore = true) - @Mapping(target = "etag", ignore = true) @Mapping(target = "createdAt", ignore = true) TrustedIssuerEntity trustedIssuerToTrustedIssuerEntity(TrustedIssuer trustedIssuer); - List trustedIssuerToTrustedIssuerEntity(List trustedIssuer); - @Mapping(source = "urlType", target = "type") - @Mapping(source = "createdAt", target = "timestamp") - TrustedIssuerDto trustedIssuerEntityToTrustedIssuerDto(TrustedIssuerEntity trustedIssuerEntity); - - @Mapping(source = "createdAt", target = "timestamp") - List trustedIssuerEntityToTrustedIssuerDto(List trustedIssuerEntities); - } diff --git a/src/main/java/tng/trustnetwork/keydistribution/repository/InfoRepository.java b/src/main/java/tng/trustnetwork/keydistribution/repository/InfoRepository.java deleted file mode 100644 index 5aa2c8d..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/repository/InfoRepository.java +++ /dev/null @@ -1,28 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import tng.trustnetwork.keydistribution.entity.InfoEntity; - -public interface InfoRepository extends JpaRepository { - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java b/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java index b4cb4be..627ad7e 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java +++ b/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java @@ -20,50 +20,36 @@ package tng.trustnetwork.keydistribution.repository; -import java.time.ZonedDateTime; import java.util.List; -import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import tng.trustnetwork.keydistribution.entity.SignerInformationEntity; public interface SignerInformationRepository extends JpaRepository { - Optional findFirstByIdIsNotNullOrderByIdAsc(); + List getByCountryIs(String country); - Optional findFirstByIdGreaterThanOrderByIdAsc(Long id); + List getByDomainIs(String domain); - List findAllByOrderByIdAsc(); + List getByDomainIsAndCountryIs(String domain, String country); - @Modifying - @Query("UPDATE SignerInformationEntity s SET s.deleted = true WHERE s.kid not in :kids") - void setDeletedByKidsNotIn(@Param("kids") List kids); + List getByCountryIsAndGroupIs(String country, String group); - @Modifying - @Query("UPDATE SignerInformationEntity s SET s.deleted = true") - void setAllDeleted(); + List getByDomainIsAndGroupIs(String domain, String group); - void deleteByKidNotIn(List kids); + List getByGroupIs(String group); + List getByDomainIsAndCountryIsAndGroupIs(String domain, String country, String group); - List findAllByDeletedOrderByIdAsc(boolean deleted); + List getBySubjectHashIsAndCountryIsAndDomainIs( + String subjectHash, String country, String domain); - void deleteByKidIn(List kids); - - List findAllByUpdatedAtAfterOrderByIdAsc(ZonedDateTime ifModifiedDateTime); - - List findAllByKidIn(List kids); - - Optional findFirstByIdIsNotNullAndDeletedOrderByIdAsc(boolean deleted); - - Optional findFirstByIdGreaterThanAndDeletedOrderByIdAsc(Long resumeToken, boolean deleted); - - @Query("SELECT DISTINCT s.country FROM SignerInformationEntity s WHERE s.deleted = false") + @Query("SELECT DISTINCT s.country FROM SignerInformationEntity s") List getCountryList(); - List getAllByDeletedIs(boolean deleted); + @Query("SELECT DISTINCT s.domain FROM SignerInformationEntity s") + List getDomainsList(); - List getAllByDeletedIsAndCountryIsIn(boolean deleted, List countries); + @Query("SELECT DISTINCT s.group FROM SignerInformationEntity s") + List getGroupList(); } diff --git a/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedIssuerRepository.java b/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedIssuerRepository.java index 18a95c8..f78e6b5 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedIssuerRepository.java +++ b/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedIssuerRepository.java @@ -26,9 +26,5 @@ public interface TrustedIssuerRepository extends JpaRepository { - void deleteAllByEtag(String etag); - - List findAllByEtag(String etag); - List findAllByUrlTypeIs(TrustedIssuerEntity.UrlType urlType); } diff --git a/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedPartyRepository.java b/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedPartyRepository.java deleted file mode 100644 index e5542f4..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/repository/TrustedPartyRepository.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.repository; - -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import tng.trustnetwork.keydistribution.entity.TrustedPartyEntity; - -public interface TrustedPartyRepository extends JpaRepository { - - @Modifying - void deleteAllByType(TrustedPartyEntity.Type type); - - List findAllByCountryIsAndTypeIs(String country, TrustedPartyEntity.Type type); - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/ContextController.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/ContextController.java deleted file mode 100644 index de3db4d..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/ContextController.java +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import tng.trustnetwork.keydistribution.config.KdsConfigProperties; - -@RestController -@RequestMapping("/context") -@Slf4j -@RequiredArgsConstructor -public class ContextController { - - private final KdsConfigProperties properties; - - /** - * Http Method for getting the current context. - */ - @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) - @Operation( - summary = "Provide configuration information for the verifier app", - tags = {"Configuration"}, - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns the current context for the verifier app.", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = String.class), - examples = {@ExampleObject(value = "{\"origin\":\"DE\",\"versions\":{\"default\":{\"privacyUrl\":" - + "\"https://publications.europa.eu/en/web/about-us/legal-notices/eu-mobile-apps\"," - + "\"context\":{\"url\":\"https://dgca-verifier-service.example.com/context\",\"pubKeys\":" - + "[\"lKdU1EbQubxyDDm2q3N8KclZ2C94+3eI=\"," - + "\"r/mIkG3eEpVdm+u/ko/cwxzOMo1bkA5E=\"]},\"endpoints\":{\"status\":{\"url\":" - + "\"https://dgca-verifier-service.example.com/signercertificateStatus\",\"pubKeys\":" - + "[\"lKdU1EbQubxyDDm2q3N8KclZ2C94+3eI=\"," - + "\"r/mIkG3eEpVdm+u/ko/cwxzOMo1bkA5E=\"]},\"update\":{\"url\":" - + "\"https://dgca-verifier-service.example.com/signercertificateUpdate\",\"pubKeys\":" - + "[\"lKdU1EbQubxyDDm2q3N8KclZ2C94+3eI=\"," - + "\"r/mIkG3eEpVdm+u/ko/cwxzOMo1bkA5E=\"]}}},\"0.1.0\":{\"outdated\":true}}}")})) - } - ) - public ResponseEntity getContext() { - try { - - String context = null; - - if (properties.getContext().isEmpty()) { - Resource resource = new ClassPathResource("/static/context.json");//TODO: cleanup EU context information - context = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8); - } else { - context = properties.getContext(); - } - - return ResponseEntity.ok(context); - } catch (IOException e) { - log.error("Could not read context file"); - } - return ResponseEntity.ok(""); - } - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/SignerInformationController.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/SignerInformationController.java deleted file mode 100644 index 9c0fa11..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/SignerInformationController.java +++ /dev/null @@ -1,248 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import jakarta.validation.Valid; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.util.List; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import tng.trustnetwork.keydistribution.entity.SignerInformationEntity; -import tng.trustnetwork.keydistribution.exception.BadRequestException; -import tng.trustnetwork.keydistribution.restapi.dto.CertificatesLookupResponseItemDto; -import tng.trustnetwork.keydistribution.restapi.dto.DeltaListDto; -import tng.trustnetwork.keydistribution.service.SignerInformationService; - -@RestController -@RequestMapping("/") -@Slf4j -@RequiredArgsConstructor -public class SignerInformationController { - - private static final String X_RESUME_TOKEN_HEADER = "X-RESUME-TOKEN"; - private static final String X_KID_HEADER = "X-KID"; - - private final SignerInformationService signerInformationService; - - - /** - * Http Method for getting signer certificate. - */ - @GetMapping(path = "/signercertificateUpdate", produces = MediaType.TEXT_PLAIN_VALUE) - @Operation( - summary = "Gets one signer certificate and a resume token.", - description = "This method return one signer certificate and a corresponding resume token. In order to " - + "download all available certificates, start calling this method without the resume token set. Then repeat" - + " to call this method, with the resume token parameter set to the value of the last response. When you " - + "receive a 204 response you have downloaded all available certificates.", - tags = {"Signer Information" }, - parameters = { - @Parameter( - in = ParameterIn.HEADER, - name = "X-RESUME-TOKEN", - description = "Defines where to resume the download of the certificates", - schema = @Schema(implementation = Long.class)) - }, - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns one signer certificate and as header parameter a resume token and the kid. " - + "There might be more certificates available to download. Repeat the request with the resume " - + "token parameter set to the actual value, until you get a 204 response.", - headers = { - @Header( - name = "X-RESUME-TOKEN", - description = "Token can be used to resume the download of the certificates."), - @Header( - name = "X-KID", - description = "The kid of the returned certificate.") - }, - content = @Content( - mediaType = MediaType.TEXT_PLAIN_VALUE, - schema = @Schema(implementation = String.class), - examples = {@ExampleObject(value = - "MIIBGzCBwqADAgECAgRggUObMAoGCCqGSM49BAMCMBYxFDASBgNVBAMMC2VkZ2Nf" - + "ZGV2X2VjMB4XDTIxMDQyMjA5MzYyN1oXDTIyMDQyMjA5MzYyN1owFjEUMBIGA1UE" - + "AwwLZWRnY19kZXZfZWMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQVQc9JY190" - + "s/Jn0CBSq/AWuxmqUzRVu+AsCe6gfbqk3s0e4jonzp5v/5IMW/9t7v5Fu2ITMmOT" - + "VfKL1TuM+aixMAoGCCqGSM49BAMCA0gAMEUCIQCGWIk6ZET3afRxdpFVuXdrEYtF" - + "iR1MGDx4HweZfspjSgIgBdCJsT746/FI3euIbzKDoeY65m+Qx2/4Cd/vOayNbuw=")})), - @ApiResponse( - responseCode = "204", - description = "No Content available. All certificates already downloaded.", - content = @Content(schema = @Schema(hidden = true))) - } - ) - public ResponseEntity getSignerCertificateUpdate( - @RequestHeader(value = X_RESUME_TOKEN_HEADER, required = false) Long resumeToken - ) { - HttpHeaders responseHeaders = new HttpHeaders(); - SignerInformationEntity signerInformation = signerInformationService.getCertificate(resumeToken).orElse(null); - - if (signerInformation == null) { - return ResponseEntity.noContent().build(); - } - - responseHeaders.set(X_RESUME_TOKEN_HEADER, signerInformation.getId().toString()); - responseHeaders.set(X_KID_HEADER, signerInformation.getKid()); - - return ResponseEntity.ok() - .headers(responseHeaders) - .body(signerInformation.getRawData()); - } - - - /** - * Http Method for getting list of valid certificates ids. - */ - @GetMapping(path = "/signercertificateStatus", produces = MediaType.APPLICATION_JSON_VALUE) - @Operation( - summary = "Gets a list of kids from all valid certificates.", - tags = {"Signer Information" }, - description = "Gets a list of kids from all valid certificates. This list can be used to verify, that the " - + "downloaded certificates are still valid. If a kid of a downloaded certificate is not part of the list, " - + "the certificate is not valid any more.", - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns a list of kids of all valid certificates.", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - array = @ArraySchema(schema = @Schema(implementation = String.class)), - examples = {@ExampleObject(value = "[\"8xYtW2837bc=\",\"zoQi+KT68LM=\"]")})) - }) - public ResponseEntity> getSignerCertificateStatus() { - - return ResponseEntity.ok(signerInformationService.getListOfValidKids()); - } - - - /** - * Http Method for getting delta list of certificates changes. - */ - @GetMapping(path = "/signercertificateStatus/delta", produces = MediaType.APPLICATION_JSON_VALUE) - @Operation( - summary = "Gets a list of kids from all valid certificates.", - tags = {"Signer Information" }, - description = "Gets a list of kids from all valid certificates. This list can be used to verify, that the " - + "downloaded certificates are still valid. If a kid of a downloaded certificate is not part of the list, " - + "the certificate is not valid any more.", - parameters = { - @Parameter( - in = ParameterIn.HEADER, - name = "If-Modified-Since", - description = "Returns only the objects which are modified behind the given date.", - required = false, - schema = @Schema(implementation = String.class))}, - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns a list of kids of all valid certificates.", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = DeltaListDto.class) - )) - }) - public ResponseEntity getDeltaList( - @RequestHeader(value = HttpHeaders.IF_MODIFIED_SINCE, required = false) String ifModifiedSince) { - - DeltaListDto result; - - if (ifModifiedSince != null) { - ZonedDateTime ifModifiedDateTime = parseIfModifiedSinceHeader(ifModifiedSince); - result = signerInformationService.getDeltaList(ifModifiedDateTime); - } else { - result = signerInformationService.getDeltaList(); - } - - return ResponseEntity.ok(result); - } - - private ZonedDateTime parseIfModifiedSinceHeader(String ifModifiedSince) throws BadRequestException { - ZonedDateTime ifModifiedDateTime; - try { - ifModifiedDateTime = ZonedDateTime.parse(ifModifiedSince); - } catch (DateTimeParseException e) { - try { - ifModifiedDateTime = ZonedDateTime.parse(ifModifiedSince, DateTimeFormatter.RFC_1123_DATE_TIME); - } catch (DateTimeParseException ex) { - throw new BadRequestException("Can not parse if-modified-since header"); - } - } - return ifModifiedDateTime; - } - - /** - * Http Method for looking up certificate data. - * - * @param requestedCertList list of kids, for which the data should be returned - * @return the requested certificate data. - */ - @PostMapping(path = "signercertificateUpdate", - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @Operation( - summary = "Returns the data for the requested certificates.", - description = "Returns the certificate data for all kids in the request body.", - tags = {"Signer Information" }, - requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody( - required = true, - content = @Content(array = @ArraySchema( - schema = @Schema(implementation = String.class, name = "kid"))) - ), - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns the certificate data.", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - examples = {@ExampleObject(value = "{ \n “DE”: [“MII….”,”MII…”],\n “NL”: [“MII…”,”MII…”]\n}\n")})) - } - ) - public ResponseEntity>> lookupCertificateData( - @Valid @RequestBody(required = true) List requestedCertList) { - - return ResponseEntity.ok(signerInformationService.getCertificatesData(requestedCertList)); - - } - - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/TrustedIssuerController.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/TrustedIssuerController.java deleted file mode 100644 index 9acafc4..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/controller/TrustedIssuerController.java +++ /dev/null @@ -1,101 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.headers.Header; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import tng.trustnetwork.keydistribution.dto.TrustedIssuerDto; -import tng.trustnetwork.keydistribution.mapper.IssuerMapper; -import tng.trustnetwork.keydistribution.service.TrustedIssuerService; - -@RestController -@RequestMapping("/") -@Slf4j -@RequiredArgsConstructor -public class TrustedIssuerController { - - - private final TrustedIssuerService trustedIssuerService; - - private final IssuerMapper issuerMapper; - - - /** - * Http Method for getting trusted issuers. - */ - @GetMapping(path = "/trustedissuers", produces = MediaType.APPLICATION_JSON_VALUE) - @Operation( - summary = "Gets one trusted issuers", - description = "This method return a list of trusted issuers.", - tags = {"Trusted Issuers"}, - parameters = { - @Parameter( - in = ParameterIn.HEADER, - name = "IF-NONE-MATCH", - description = "When the eTag matches the current Tag, there is a 304 response.", - required = false, - schema = @Schema(implementation = String.class)) - }, - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns the the trusted issuers list.", - headers = @Header(name = HttpHeaders.ETAG, description = "ETAG of the current data set"), - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - array = @ArraySchema(schema = - @Schema(implementation = TrustedIssuerDto.class)))), - @ApiResponse( - responseCode = "304", - description = "Not modified.") - } - ) - public ResponseEntity> getTrustedIssuers( - @RequestHeader(value = HttpHeaders.IF_NONE_MATCH, defaultValue = "") String ifNoneMatch) { - - String currentEtag = trustedIssuerService.getEtag(); - - if (ifNoneMatch.equals(currentEtag)) { - return ResponseEntity.status(HttpStatus.NOT_MODIFIED).build(); - } - - return ResponseEntity.ok().eTag(currentEtag).body(issuerMapper.trustedIssuerEntityToTrustedIssuerDto( - trustedIssuerService.getAllIssuers(currentEtag))); - } - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/CertificatesLookupResponseItemDto.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/CertificatesLookupResponseItemDto.java deleted file mode 100644 index 518392a..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/CertificatesLookupResponseItemDto.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Schema( - name = "DeltaList", - type = "object", - example = "{\n" - + "\"updated\": [\"33333d=\",\"333311=\",\"55554=\"],\n" - + "\"deleted\":[\"3115adf=\"]\n" - + "}" -) - -@Getter -@AllArgsConstructor -public class CertificatesLookupResponseItemDto { - String kid; - String rawData; -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/DeltaListDto.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/DeltaListDto.java deleted file mode 100644 index 31bc48a..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/DeltaListDto.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Schema( - name = "DeltaList", - type = "object", - example = "{\n" - + "\"updated\": [\"33333d=\",\"333311=\",\"55554=\"],\n" - + "\"deleted\":[\"3115adf=\"]\n" - + "}" -) - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class DeltaListDto { - List updated; - List deleted; -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/KidDto.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/KidDto.java deleted file mode 100644 index c894fcd..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/KidDto.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Value; - -@Schema( - name = "kid", - type = "string", - example = "8xYtW2837fc=" -) - -@Value -public class KidDto { - String kid; -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/ProblemReportDto.java b/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/ProblemReportDto.java deleted file mode 100644 index c47e3a7..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/restapi/dto/ProblemReportDto.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Schema( - name = "ProblemReport", - type = "object", - example = "{\n" - + "\"code\":\"0x001\",\n" - + "\"problem\":\"[PROBLEM]\",\n" - + "\"sent value\":\"[Sent Value]\",\n" - + "\"details\":\"...\"\n" - + "}" -) - -@Data -@AllArgsConstructor -public class ProblemReportDto { - - private String code; - - private String problem; - - private String sendValue; - - private String details; - -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/InfoService.java b/src/main/java/tng/trustnetwork/keydistribution/service/InfoService.java deleted file mode 100644 index cb09ce2..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/service/InfoService.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.service; - -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import tng.trustnetwork.keydistribution.entity.InfoEntity; -import tng.trustnetwork.keydistribution.repository.InfoRepository; - -@Slf4j -@RequiredArgsConstructor -@Service -public class InfoService { - - public static final String CURRENT_ETAG = "CURRENTETAG"; - - private final InfoRepository infoRepository; - - /** - * Gets a value for the given key from the db. - * - * @param key the key, for which the value should be returned - * @return the value or null if not found in db - */ - public String getValueForKey(String key) { - Optional optionalValue = infoRepository.findById(key); - - return optionalValue.map(InfoEntity::getValue).orElse(null); - } - - /** - * Saves the value for a given key in the db. - * - * @param key key of the value to save. - * @param value the value to save - */ - public void setValueForKey(String key, String value) { - InfoEntity infoEntity = new InfoEntity(key, value); - infoRepository.save(infoEntity); - } -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/KdsCertUtils.java b/src/main/java/tng/trustnetwork/keydistribution/service/KdsCertUtils.java new file mode 100644 index 0000000..f1fb954 --- /dev/null +++ b/src/main/java/tng/trustnetwork/keydistribution/service/KdsCertUtils.java @@ -0,0 +1,34 @@ +package tng.trustnetwork.keydistribution.service; + +import eu.europa.ec.dgc.utils.CertificateUtils; +import java.io.IOException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Base64; +import lombok.RequiredArgsConstructor; +import org.bouncycastle.cert.X509CertificateHolder; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class KdsCertUtils { + + private final CertificateUtils certificateUtils; + + /** + * Parse Base64 Encoded Certificate. + * + * @param raw Base64 encoded certificate in DER format + * @return parsed Certificate instance + */ + public X509Certificate parseCertificate(String raw) { + + try { + byte[] rawDataBytes = Base64.getDecoder().decode(raw); + X509CertificateHolder certificateHolder = new X509CertificateHolder(rawDataBytes); + return certificateUtils.convertCertificate(certificateHolder); + } catch (CertificateException | IOException e) { + return null; + } + } +} diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadService.java b/src/main/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadService.java index 9d9bf8e..11e9229 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadService.java +++ b/src/main/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadService.java @@ -42,8 +42,6 @@ public class SignerCertificateDownloadService { private final SignerInformationService signerInformationService; - private final TrustedPartyService trustedPartyService; - /** * Download TrustedCertificates from Gateway. */ @@ -57,9 +55,6 @@ public void downloadCertificates() { List trustedCerts = dgcGatewayConnector.getDdccTrustedCertificates(); signerInformationService.updateTrustedCertsList(trustedCerts); - List trustedCsca = dgcGatewayConnector.getTrustedCscaCertificates(); - trustedPartyService.updateCscaFromTrustList(trustedCsca); - log.info("Certificates download finished"); } } diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java b/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java index 626227a..26ffe98 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java +++ b/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java @@ -21,20 +21,17 @@ package tng.trustnetwork.keydistribution.service; import eu.europa.ec.dgc.gateway.connector.model.TrustedCertificateTrustListItem; +import eu.europa.ec.dgc.utils.CertificateUtils; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; import java.time.ZonedDateTime; -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import tng.trustnetwork.keydistribution.entity.SignerInformationEntity; import tng.trustnetwork.keydistribution.repository.SignerInformationRepository; -import tng.trustnetwork.keydistribution.restapi.dto.CertificatesLookupResponseItemDto; -import tng.trustnetwork.keydistribution.restapi.dto.DeltaListDto; @Slf4j @Component @@ -42,67 +39,22 @@ public class SignerInformationService { private final SignerInformationRepository signerInformationRepository; + private final CertificateUtils certificateUtils; + private final KdsCertUtils kdsCertUtils; /** - * Method to query the db for a certificate with a resume token. - * - * @param resumeToken defines which certificate should be returned. - * @return Optional holding the certificate if found. - */ - public Optional getCertificate(Long resumeToken) { - - if (resumeToken == null) { - return signerInformationRepository.findFirstByIdIsNotNullAndDeletedOrderByIdAsc(false); - } else { - return signerInformationRepository.findFirstByIdGreaterThanAndDeletedOrderByIdAsc(resumeToken, false); - } - } - - /** - * Method to query the db for a list of kid from all certificates. - * - * @return A list of kids of all certificates found. If no certificate was found an empty list is returned. - */ - public List getListOfValidKids() { - - List certsList = signerInformationRepository.findAllByDeletedOrderByIdAsc(false); - - return certsList.stream().map(SignerInformationEntity::getKid).collect(Collectors.toList()); - - } - - /** - * Method to synchronise the certificates in the db with the given List of trusted certificates. + * Update stored certificates with given list of new certificates. * * @param trustedCerts defines the list of trusted certificates. */ @Transactional public void updateTrustedCertsList(List trustedCerts) { - List trustedCertsKids = trustedCerts.stream().map( - TrustedCertificateTrustListItem::getKid).collect(Collectors.toList()); - List alreadyStoredCerts = getListOfValidKids(); - List certsToDelete = new ArrayList<>(); + signerInformationRepository.deleteAll(); - if (trustedCertsKids.isEmpty()) { - signerInformationRepository.setAllDeleted(); - return; - } else { - signerInformationRepository.setDeletedByKidsNotIn(trustedCertsKids); - } - - List signerInformationEntities = new ArrayList<>(); - - for (TrustedCertificateTrustListItem cert : trustedCerts) { - if (!alreadyStoredCerts.contains(cert.getKid())) { - signerInformationEntities.add(getSignerInformationEntity(cert)); - certsToDelete.add(cert.getKid()); - } - } - - //Delete all certificates that got updated, so that they get a new id. - signerInformationRepository.deleteByKidIn(certsToDelete); - signerInformationRepository.saveAllAndFlush(signerInformationEntities); + trustedCerts.stream() + .map(this::getSignerInformationEntity) + .forEach(signerInformationRepository::save); } private SignerInformationEntity getSignerInformationEntity(TrustedCertificateTrustListItem cert) { @@ -113,95 +65,153 @@ private SignerInformationEntity getSignerInformationEntity(TrustedCertificateTru signerEntity.setCountry(cert.getCountry()); signerEntity.setRawData(cert.getCertificate()); signerEntity.setDomain(cert.getDomain()); + signerEntity.setGroup(cert.getGroup()); + + try { + X509Certificate parsedCertificate = kdsCertUtils.parseCertificate(cert.getCertificate()); + byte[] subjectBytes = parsedCertificate.getSubjectX500Principal().getEncoded(); + signerEntity.setSubjectHash(certificateUtils.calculateHash(subjectBytes)); + } catch (NoSuchAlgorithmException e) { + log.error("Failed to calculate Hash for certificate {}", cert.getKid()); + } return signerEntity; } /** - * Gets the deleted/updated state of the certificates. + * Returns a list of 2-Digit Country-Codes which have at least one signing certificates present in DB. * - * @return state of the certificates represented by their kids + * @return Distinct list of Country-Codes */ - public DeltaListDto getDeltaList() { + public List getCountryList() { + + return signerInformationRepository.getCountryList(); + } - List certs = - signerInformationRepository.findAllByOrderByIdAsc(); + /** + * Returns a list of groups for which certificates are imported. + * + * @return list of groups + */ + public List getGroupList() { - Map> partitioned = - certs.stream().collect(Collectors.partitioningBy(SignerInformationEntity::isDeleted, - Collectors.mapping(SignerInformationEntity::getKid, - Collectors.toList()))); + return signerInformationRepository.getGroupList(); + } - return new DeltaListDto(partitioned.get(Boolean.FALSE), partitioned.get(Boolean.TRUE)); + /** + * Returns a list of domains for which certificates are imported. + * + * @return list of domains + */ + public List getDomainsList() { + return signerInformationRepository.getDomainsList(); } /** - * Gets the deleted/updated state of the certificates after the given value. + * Returns a list of all certificates. * - * @return state of the certificates represented by their kids + * @return List of SignerInformationEntity */ - public DeltaListDto getDeltaList(ZonedDateTime ifModifiedDateTime) { + public List getAllCertificates() { - List certs = - signerInformationRepository.findAllByUpdatedAtAfterOrderByIdAsc(ifModifiedDateTime); + return signerInformationRepository.findAll(); + } - Map> partitioned = - certs.stream().collect(Collectors.partitioningBy(SignerInformationEntity::isDeleted, - Collectors.mapping(SignerInformationEntity::getKid, - Collectors.toList()))); + /** + * Returns signer information that are active filtered by domain, participant and group. + * + * @param domain a domain name used as filter + * @param participant a participant aka country code, used as filter + * @param group group name, used as filter + * @return matching SignerInformationEntities + */ + public List getCertificatesByDomainParticipantGroup( + String domain, String participant, String group) { - return new DeltaListDto(partitioned.get(Boolean.FALSE), partitioned.get(Boolean.TRUE)); + return signerInformationRepository.getByDomainIsAndCountryIsAndGroupIs(domain, participant, group); + } + /** + * Returns signer information that are filtered by participant. + * + * @param country a participant aka country code, used as filter + * @return matching SignerInformationEntities + */ + public List getCertificatesByCountry(String country) { + + return signerInformationRepository.getByCountryIs(country); } /** - * Gets the raw data of the certificates for a given kid list. + * Returns signer information that are filtered by domain and participant. * - * @param requestedCertList list of kids - * @return raw data of certificates + * @param domain a domain name used as filter + * @param country a participant aka country code, used as filter + * @return matching SignerInformationEntities */ - public Map> getCertificatesData(List requestedCertList) { + public List getCertificatesByCountryDomain(String country, String domain) { - List certs = - signerInformationRepository.findAllByKidIn(requestedCertList); + return signerInformationRepository.getByDomainIsAndCountryIs(domain, country); + } - return certs.stream().collect(Collectors.groupingBy(SignerInformationEntity::getCountry, - Collectors.mapping(this::map, Collectors.toList()))); + /** + * Returns signer information that are filtered by domain. + * + * @param domain a domain name used as filter + * @return matching SignerInformationEntities + */ + public List getCertificatesByDomain(String domain) { + + return signerInformationRepository.getByDomainIs(domain); } /** - * Returns a list of 2-Digit Country-Codes which have at least one signing certificates present in DB which is not - * marked for deletion. + * Returns signer information that are filtered by participant and group. * - * @return Distinct list of Country-Codes + * @param group group name, used as filter + * @param country a participant aka country code, used as filter + * @return matching SignerInformationEntities */ - public List getCountryList() { + public List getCertificatesByGroupCountry(String group, String country) { - return signerInformationRepository.getCountryList(); + return signerInformationRepository.getByCountryIsAndGroupIs(country, group); } /** - * Returns a list of all active certificates. + * Returns signer information that are filtered by domain and group. * - * @return List of SignerInformationEntity + * @param domain a domain name used as filter + * @param group group name, used as filter + * @return matching SignerInformationEntities */ - public List getActiveCertificates() { - return signerInformationRepository.getAllByDeletedIs(false); + public List getCertificatesByDomainGroup(String domain, String group) { + + return signerInformationRepository.getByDomainIsAndGroupIs(domain, group); } /** - * Returns a list of active certificates for given list of countries. + * Returns signer information that are filtered by group. * - * @param countries List of Country Codes to filter for. * - * @return List of SignerInformationEntity + * @param group group name, used as filter + * @return matching SignerInformationEntities */ - public List getActiveCertificatesForCountries(List countries) { - return signerInformationRepository.getAllByDeletedIsAndCountryIsIn(false, countries); + public List getCertificatesByGroup(String group) { + + return signerInformationRepository.getByGroupIs(group); } - private CertificatesLookupResponseItemDto map(SignerInformationEntity entity) { + /** + * Returns signer information that are filtered by subjectHash, country, and domain. + * + * @param subjectHash SHA256 hash of certificate subject to filter + * @param country CountryCode/Participant code to filter + * @param domain Domain value to filter for + * @return matching SignerInformationEntities + */ + public List getCertificatesBySubjectHashCountryDomain(String subjectHash, String country, + String domain) { - return new CertificatesLookupResponseItemDto(entity.getKid(), entity.getRawData()); + return signerInformationRepository.getBySubjectHashIsAndCountryIsAndDomainIs(subjectHash, country, domain); } } diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/TrustedIssuerService.java b/src/main/java/tng/trustnetwork/keydistribution/service/TrustedIssuerService.java index 1219d3e..1a786c4 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/service/TrustedIssuerService.java +++ b/src/main/java/tng/trustnetwork/keydistribution/service/TrustedIssuerService.java @@ -21,6 +21,7 @@ package tng.trustnetwork.keydistribution.service; import com.fasterxml.jackson.core.JsonProcessingException; +import eu.europa.ec.dgc.gateway.connector.mapper.TrustedIssuerMapper; import eu.europa.ec.dgc.gateway.connector.model.TrustedIssuer; import java.util.ArrayList; import java.util.List; @@ -39,8 +40,6 @@ @RequiredArgsConstructor public class TrustedIssuerService { - private final InfoService infoService; - private final IssuerMapper issuerMapper; private final TrustedIssuerRepository trustedIssuerRepository; @@ -51,31 +50,6 @@ public class TrustedIssuerService { private final KdsConfigProperties configProperties; - /** - * Get the current etag. - * - * @return the current etag - */ - - public String getEtag() { - - String etag = infoService.getValueForKey(InfoService.CURRENT_ETAG); - if (etag == null) { - etag = ""; - } - return etag; - } - - /** - * Method to query the db for all trusted issuers. - * - * @return List holding the found trusted issuers. - */ - public List getAllIssuers(String etag) { - - return trustedIssuerRepository.findAllByEtag(etag); - } - /** * Method to query the db for DID documents. * @@ -94,47 +68,33 @@ public List getAllDid() { @Transactional public void updateTrustedIssuersList(List trustedIssuers) { - String newEtag = UUID.randomUUID().toString(); + trustedIssuerRepository.deleteAll(); - List trustedIssuerEntities = new ArrayList<>(); for (TrustedIssuer trustedIssuer : trustedIssuers) { - trustedIssuerEntities.add(getTrustedIssuerEntity(newEtag, trustedIssuer)); + trustedIssuerRepository.save(issuerMapper.trustedIssuerToTrustedIssuerEntity(trustedIssuer)); - if (TrustedIssuer.UrlType.DID == trustedIssuer.getType() - && configProperties.getTrustedIssuerDownloader().isEnableTrustedIssuerResolving()) { - try { - UniversalResolverService.DidDocumentWithRawResponse didDocument = - urService.universalResolverApiCall(trustedIssuer.getUrl()); - - decentralizedIdentifierService.updateDecentralizedIdentifierList(didDocument.didDocument(), - didDocument.raw()); - } catch (JsonProcessingException e) { - log.error("Failed to download/parse DID {}", trustedIssuer.getUrl()); - } + if (trustedIssuer.getType() == TrustedIssuer.UrlType.DID) { + resolveDid(trustedIssuer); } } - - trustedIssuerRepository.saveAll(trustedIssuerEntities); - - String oldEtag = getEtag(); - infoService.setValueForKey(InfoService.CURRENT_ETAG, newEtag); - - cleanupData(oldEtag); - } - private TrustedIssuerEntity getTrustedIssuerEntity(String etag, TrustedIssuer trustedIssuer) { + private void resolveDid(TrustedIssuer trustedIssuer) { - TrustedIssuerEntity entity = issuerMapper.trustedIssuerToTrustedIssuerEntity(trustedIssuer); - entity.setEtag(etag); - return entity; - } + if (!configProperties.getTrustedIssuerDownloader().isEnableTrustedIssuerResolving()) { + return; + } - private void cleanupData(String etag) { + try { + UniversalResolverService.DidDocumentWithRawResponse didDocument = + urService.universalResolverApiCall(trustedIssuer.getUrl()); - trustedIssuerRepository.deleteAllByEtag(etag); + decentralizedIdentifierService.updateDecentralizedIdentifierList(didDocument.didDocument(), + didDocument.raw()); + } catch (JsonProcessingException e) { + log.error("Failed to download/parse DID {}", trustedIssuer.getUrl()); + } } - } diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/TrustedPartyService.java b/src/main/java/tng/trustnetwork/keydistribution/service/TrustedPartyService.java deleted file mode 100644 index aa63cf2..0000000 --- a/src/main/java/tng/trustnetwork/keydistribution/service/TrustedPartyService.java +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.service; - -import eu.europa.ec.dgc.gateway.connector.model.TrustListItem; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; -import tng.trustnetwork.keydistribution.entity.TrustedPartyEntity; -import tng.trustnetwork.keydistribution.repository.TrustedPartyRepository; - -@Slf4j -@Component -@RequiredArgsConstructor -public class TrustedPartyService { - - - private final TrustedPartyRepository trustedPartyRepository; - - /** - * Insert given list of TrustListItems as CSCA into TrustedParty Table. - * Table will be cleaned up previously. - * - * @param trustList List of trusted CSCA. - */ - @Transactional - public void updateCscaFromTrustList(List trustList) { - - trustedPartyRepository.deleteAllByType(TrustedPartyEntity.Type.CSCA); - - trustList.stream() - .map(this::getCscaEntity) - .forEach(trustedPartyRepository::save); - } - - public List getCscaByCountry(String countryCode) { - - return trustedPartyRepository.findAllByCountryIsAndTypeIs(countryCode, TrustedPartyEntity.Type.CSCA); - } - - private TrustedPartyEntity getCscaEntity(TrustListItem trustListItem) { - - return TrustedPartyEntity.builder() - .country(trustListItem.getCountry()) - .rawData(trustListItem.getRawData()) - .type(TrustedPartyEntity.Type.CSCA) - .build(); - } -} diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java b/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java index cf6ce8d..d9187a0 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java +++ b/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java @@ -20,47 +20,49 @@ package tng.trustnetwork.keydistribution.service.did; -import com.apicatalog.jsonld.document.JsonDocument; +import static tng.trustnetwork.keydistribution.service.did.KdsDidContextDocumentLoaderConfig.DID_CONTEXTS; + +import com.apicatalog.jsonld.loader.DocumentLoader; import com.danubetech.keyformats.crypto.ByteSigner; import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.dgc.utils.CertificateUtils; -import foundation.identity.jsonld.ConfigurableDocumentLoader; +import foundation.identity.jsonld.JsonLDException; import foundation.identity.jsonld.JsonLDObject; import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; import info.weboftrust.ldsignatures.signer.JsonWebSignature2020LdSigner; import java.io.IOException; -import java.io.InputStream; import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; import java.security.PublicKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; -import java.util.Base64; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; -import java.util.Objects; -import java.util.Optional; +import java.util.function.Supplier; +import lombok.AccessLevel; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; -import org.bouncycastle.cert.X509CertificateHolder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import tng.trustnetwork.keydistribution.config.KdsConfigProperties; import tng.trustnetwork.keydistribution.entity.SignerInformationEntity; +import tng.trustnetwork.keydistribution.entity.TrustedIssuerEntity; +import tng.trustnetwork.keydistribution.service.KdsCertUtils; import tng.trustnetwork.keydistribution.service.SignerInformationService; import tng.trustnetwork.keydistribution.service.TrustedIssuerService; -import tng.trustnetwork.keydistribution.service.TrustedPartyService; import tng.trustnetwork.keydistribution.service.did.entity.DidTrustList; import tng.trustnetwork.keydistribution.service.did.entity.DidTrustListEntry; @@ -70,15 +72,11 @@ @ConditionalOnProperty("dgc.did.enableDidGeneration") public class DidTrustListService { - private static final String SEPARATOR_COLON = ":"; - - private static final String SEPARATOR_FRAGMENT = "#"; + private static final String WILDCARD_CHAR = "-"; - private static final List DID_CONTEXTS = List.of( - "https://www.w3.org/ns/did/v1", - "https://w3id.org/security/suites/jws-2020/v1"); + private static final String SEPARATOR_DID_PATH = ":"; - private final TrustedPartyService trustedPartyService; + private static final String SEPARATOR_DID_ID = "#"; private final SignerInformationService signerInformationService; @@ -93,217 +91,349 @@ public class DidTrustListService { private final CertificateUtils certificateUtils; private final TrustedIssuerService trustedIssuerService; - + private final GitProvider gitProvider; - /** - * Create and upload DID Document holding Uploaded DSC and Trusted Issuer. - */ - @Scheduled(cron = "${dgc.did.cron}") - @SchedulerLock(name = "didTrustListGenerator") - public void job() { + private final DocumentLoader documentLoader; - String trustList; + private final KdsConfigProperties kdsConfigProperties; - try { - trustList = generateTrustList(null); - } catch (Exception e) { - log.error("Failed to generate DID-TrustList: {}", e.getMessage()); - return; - } + private final KdsCertUtils kdsCertUtils; - try { - didUploader.uploadDid(trustList.getBytes(StandardCharsets.UTF_8)); - } catch (Exception e) { - log.error("Failed to Upload DID-TrustList: {}", e.getMessage()); - return; + @RequiredArgsConstructor + @Getter + private class DidSpecification { + + @Getter(AccessLevel.PRIVATE) + private final List path; + + private final Supplier> certSupplier; + + private final Supplier> issuerSupplier; + + public List getPath(boolean ref) { + ArrayList path = new ArrayList<>(this.path); + path.add(0, getListPathElement(ref)); + return path; } - List countries = signerInformationService.getCountryList(); + public String getDocumentId(boolean ref) { + //Example: did:web:tng-cdn-dev.who.int:trustlist:v.2.0.0:DDCC:XXA:DSC + return configProperties.getDid().getDidId() + + SEPARATOR_DID_PATH + getListPathElement(ref) + + (path.isEmpty() ? "" : SEPARATOR_DID_PATH + + String.join(SEPARATOR_DID_PATH, path)); + } - for (String country : countries) { - String countryTrustList; + public String getEntryId(String kid) { + //Example: did:web:tng-cdn-dev.who.int:trustlist:v.2.0.0:DDCC:XXA:DSC#kidkidkid + return getDocumentId(false) + SEPARATOR_DID_ID + kid; + } - String countryAsSubcontainer = getCountryAsLowerCaseAlpha3(country); - if (countryAsSubcontainer != null) { - try { - countryTrustList = generateTrustList(List.of(country)); - } catch (Exception e) { - log.error("Failed to generate DID-TrustList for country {} : {}", country, e.getMessage()); - continue; - } + private String getListPathElement(boolean ref) { + if (ref && configProperties.getDid().getTrustListRefPath() != null + && !configProperties.getDid().getTrustListRefPath().isEmpty()) { + return configProperties.getDid().getTrustListRefPath(); - try { - didUploader.uploadDid(countryAsSubcontainer, countryTrustList.getBytes(StandardCharsets.UTF_8)); - } catch (Exception e) { - log.error("Failed to Upload DID-TrustList for country {} : {}", country, e.getMessage()); - } + } else if (!ref && configProperties.getDid().getTrustListPath() != null + && !configProperties.getDid().getTrustListPath().isEmpty()) { + return configProperties.getDid().getTrustListPath(); + } else { + return ""; } } + } - log.info("Finished DID Export Process"); + /** + * Create and upload DID Document holding Uploaded DSC and Trusted Issuer. + */ + @Scheduled(cron = "${dgc.did.cron}") + @SchedulerLock(name = "didTrustListGenerator") + public void job() { + + List didSpecifications = new ArrayList<>(); + List domains = signerInformationService.getDomainsList(); + List countries = signerInformationService.getCountryList(); + + //CHECKSTYLE:OFF + List groups = signerInformationService.getGroupList(); + //CHECKSTYLE:ON + + // Add overall DID + didSpecifications.add(new DidSpecification( + Collections.emptyList(), + signerInformationService::getAllCertificates, + trustedIssuerService::getAllDid)); + + // Add all Domain DID + domains.forEach( + domain -> didSpecifications.add(new DidSpecification( + List.of(domain), + () -> signerInformationService.getCertificatesByDomain(domain), + trustedIssuerService::getAllDid))); + + // Add all Country and Domain specific DID + domains.forEach( + domain -> countries.forEach( + country -> didSpecifications.add(new DidSpecification( + List.of(domain, getParticipantCode(country)), + () -> signerInformationService.getCertificatesByCountryDomain(country, domain), + trustedIssuerService::getAllDid) + ))); + + // Add all Domain independent and country specific DID + countries.forEach( + country -> didSpecifications.add(new DidSpecification( + List.of(WILDCARD_CHAR, getParticipantCode(country)), + () -> signerInformationService.getCertificatesByCountry(country), + trustedIssuerService::getAllDid))); + + // Add all domain, country and group specific did + domains.forEach( + domain -> countries.forEach( + country -> groups.forEach( + group -> didSpecifications.add(new DidSpecification( + List.of(domain, getParticipantCode(country), getMappedGroupName(group)), + () -> signerInformationService.getCertificatesByDomainParticipantGroup(domain, country, group), + trustedIssuerService::getAllDid))))); + + // Add all country and group specific did + countries.forEach( + country -> groups.forEach( + group -> didSpecifications.add(new DidSpecification( + List.of(WILDCARD_CHAR, getParticipantCode(country), getMappedGroupName(group)), + () -> signerInformationService.getCertificatesByGroupCountry(group, country), + trustedIssuerService::getAllDid)))); + + // Add all domain and group specific did + domains.forEach( + domain -> groups.forEach( + group -> didSpecifications.add(new DidSpecification( + List.of(domain, WILDCARD_CHAR, getMappedGroupName(group)), + () -> signerInformationService.getCertificatesByDomainGroup(domain, group), + trustedIssuerService::getAllDid)))); + + // Add all group specific did + groups.forEach( + group -> didSpecifications.add(new DidSpecification( + List.of(WILDCARD_CHAR, WILDCARD_CHAR, getMappedGroupName(group)), + () -> signerInformationService.getCertificatesByGroup(group), + trustedIssuerService::getAllDid))); + + Map didDocuments = new HashMap<>(); + didSpecifications.forEach(specification -> didDocuments + .put(specification, this.generateTrustList(specification, false))); + + Map didRefDocuments = new HashMap<>(); + didSpecifications.forEach(specification -> didRefDocuments + .put(specification, this.generateTrustList(specification, true))); + + didDocuments.forEach((specification, document) -> + saveDid(String.join("/", specification.getPath(false)), document)); + + didRefDocuments.forEach((specification, document) -> + saveDid(String.join("/", specification.getPath(true)), document)); + + log.info("Finished DID Export Process: {} documents", didDocuments.size()); gitProvider.upload(configProperties.getDid().getLocalFile().getDirectory()); + } - private String getCountryAsLowerCaseAlpha3(String country) { + private void saveDid(String containerPath, String didDocument) { - if (country == null || country.length() != 2 && country.length() != 3) { - return null; - } else if (country.length() == 3) { - return country; + try { + didUploader.uploadDid(containerPath, + didDocument == null ? null : didDocument.getBytes(StandardCharsets.UTF_8)); + } catch (Exception e) { + log.error("Failed to Upload DID-TrustList: {}", e.getMessage()); } - - return configProperties.getDid().getVirtualCountries().computeIfAbsent(country, (c) -> { - try { - return new Locale("en", c).getISO3Country().toLowerCase(); - } catch (MissingResourceException e) { - log.error("Country Code to alpha 3 conversion issue for country {} : {}", - c, e.getMessage()); - return c; - } - }); } - private String generateTrustList(List countries) throws Exception { + private String generateTrustList(DidSpecification specification, boolean onlyReferences) { + + List signerInformationEntities = filterEntities(specification.getCertSupplier().get()); + List trustedIssuerEntities = specification.getIssuerSupplier().get(); + + if (signerInformationEntities.isEmpty() || trustedIssuerEntities.isEmpty()) { + log.info("Empty DID for path {}", specification.getPath()); + return null; + } DidTrustList trustList = new DidTrustList(); trustList.setContext(DID_CONTEXTS); - trustList.setId(configProperties.getDid().getDidId()); - trustList.setController(configProperties.getDid().getDidController()); + trustList.setId(specification.getDocumentId(onlyReferences)); + trustList.setController(specification.getDocumentId(onlyReferences)); trustList.setVerificationMethod(new ArrayList<>()); - if (countries != null && !countries.isEmpty()) { - trustList.setId(configProperties.getDid().getDidId() - + SEPARATOR_COLON - + getCountryAsLowerCaseAlpha3(countries.get(0))); - } - - // Add DSC - List signerInformationEntities = countries == null - ? signerInformationService.getActiveCertificates() - : signerInformationService.getActiveCertificatesForCountries(countries); + // Add Certificates for (SignerInformationEntity signerInformationEntity : signerInformationEntities) { - X509Certificate parsedCertificate = parseCertificate(signerInformationEntity.getRawData()); - PublicKey publicKey = parsedCertificate.getPublicKey(); + if (onlyReferences) { + trustList.getVerificationMethod().add(specification.getEntryId( + URLEncoder.encode(signerInformationEntity.getKid(), StandardCharsets.UTF_8))); - if (publicKey instanceof RSAPublicKey rsaPublicKey) { - addTrustListEntry(trustList, signerInformationEntity, - new DidTrustListEntry.RsaPublicKeyJwk( - rsaPublicKey, List.of(signerInformationEntity.getRawData())), parsedCertificate); + } else { + X509Certificate parsedCertificate = kdsCertUtils.parseCertificate(signerInformationEntity.getRawData()); + if (parsedCertificate == null) { + log.error("Could not parse cert {} of country {}", + signerInformationEntity.getKid(), + signerInformationEntity.getCountry()); + return null; + } - } else if (publicKey instanceof ECPublicKey ecPublicKey) { - addTrustListEntry(trustList, signerInformationEntity, - new DidTrustListEntry.EcPublicKeyJwk( - ecPublicKey, List.of(signerInformationEntity.getRawData())), parsedCertificate); + PublicKey publicKey = parsedCertificate.getPublicKey(); + DidTrustListEntry.PublicKeyJwk publicKeyJwk = null; + if (publicKey instanceof RSAPublicKey rsaPublicKey) { + publicKeyJwk = new DidTrustListEntry.RsaPublicKeyJwk( + rsaPublicKey, List.of(signerInformationEntity.getRawData())); - } else { - log.error("Public Key is not RSA or EC Public Key for cert {} of country {}", - signerInformationEntity.getKid(), - signerInformationEntity.getCountry()); + } else if (publicKey instanceof ECPublicKey ecPublicKey) { + publicKeyJwk = new DidTrustListEntry.EcPublicKeyJwk( + ecPublicKey, List.of(signerInformationEntity.getRawData())); + + } else { + log.error("Public Key is not RSA or EC Public Key for cert {} of country {}", + signerInformationEntity.getKid(), + signerInformationEntity.getCountry()); + } + + addTrustListEntry(trustList, specification, signerInformationEntity, publicKeyJwk); } } - // Add DID References - trustedIssuerService.getAllDid() - .forEach(did -> trustList.getVerificationMethod().add(did.getUrl())); + // Add Trusted Issuer (DID References) + // TODO: Add filtering for TrustedIssuers + trustedIssuerEntities.forEach(did -> trustList.getVerificationMethod().add(did.getUrl())); - // Create LD-Proof Document + // Sign Document JsonWebSignature2020LdSigner signer = new JsonWebSignature2020LdSigner(byteSigner); signer.setCreated(new Date()); signer.setProofPurpose(LDSecurityKeywords.JSONLD_TERM_ASSERTIONMETHOD); signer.setVerificationMethod(URI.create(configProperties.getDid().getLdProofVerificationMethod())); signer.setDomain(configProperties.getDid().getLdProofDomain()); - signer.setNonce(configProperties.getDid().getLdProofNonce()); + signer.setNonce(generateNonce()); - // Load DID-Contexts - Map contextMap = new HashMap<>(); - for (String didContext : DID_CONTEXTS) { - String didContextFile = configProperties.getDid().getContextMapping().get(didContext); - - if (didContextFile == null) { - log.error("Failed to load DID-Context Document for {}: No Mapping to local JSON-File.", didContext); - } - try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream( - "did_contexts/" + didContextFile)) { - if (inputStream != null) { - contextMap.put(URI.create(didContext), JsonDocument.of(inputStream)); - } - } catch (Exception e) { - log.error("Failed to load DID-Context Document {}: {}", didContextFile, e.getMessage()); - throw e; - } + try { + JsonLDObject jsonLdObject = JsonLDObject.fromJson(objectMapper.writeValueAsString(trustList)); + jsonLdObject.setDocumentLoader(documentLoader); + signer.sign(jsonLdObject); + return jsonLdObject.toJson(); + } catch (IOException | GeneralSecurityException | JsonLDException e) { + log.error("Failed to sign DID-TrustList: {}", e.getMessage()); + return null; } - JsonLDObject jsonLdObject = JsonLDObject.fromJson(objectMapper.writeValueAsString(trustList)); - jsonLdObject.setDocumentLoader(new ConfigurableDocumentLoader(contextMap)); - - signer.sign(jsonLdObject); - - return jsonLdObject.toJson(); } - private X509Certificate parseCertificate(String raw) { + private String getParticipantCode(String country) { - try { - byte[] rawDataBytes = Base64.getDecoder().decode(raw); - X509CertificateHolder certificateHolder = new X509CertificateHolder(rawDataBytes); - return certificateUtils.convertCertificate(certificateHolder); - } catch (CertificateException | IOException e) { + if (country == null || country.length() != 2 && country.length() != 3) { return null; + } else if (country.length() == 3) { + return country.toUpperCase(); } + + return configProperties.getDid().getVirtualCountries().computeIfAbsent(country, (c) -> { + try { + return new Locale("en", c).getISO3Country().toUpperCase(); + } catch (MissingResourceException e) { + log.error("Country Code to alpha 3 conversion issue for country {} : {}", + c, e.getMessage()); + return c.toUpperCase(); + } + }); } private void addTrustListEntry(DidTrustList trustList, + DidSpecification specification, SignerInformationEntity signerInformationEntity, - DidTrustListEntry.PublicKeyJwk publicKeyJwk, - X509Certificate dsc) { + DidTrustListEntry.PublicKeyJwk publicKeyJwk) { - Optional csca = searchCsca(dsc, signerInformationEntity.getCountry()); + List issuers = new ArrayList<>(); + searchIssuer(issuers, signerInformationEntity); - if (csca.isPresent()) { - - try { - String encodedCsca = Base64.getEncoder().encodeToString(csca.get().getEncoded()); - publicKeyJwk.getEncodedX509Certificates() - .add(encodedCsca); - } catch (CertificateEncodingException e) { - throw new RuntimeException(e); - } - } + issuers.forEach(issuer -> publicKeyJwk.getEncodedX509Certificates().add(issuer.getRawData())); DidTrustListEntry trustListEntry = new DidTrustListEntry(); trustListEntry.setType("JsonWebKey2020"); - trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() - + SEPARATOR_COLON - + getCountryAsLowerCaseAlpha3(signerInformationEntity.getCountry()) - + SEPARATOR_FRAGMENT - + URLEncoder.encode(signerInformationEntity.getKid(), StandardCharsets.UTF_8)); - trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix() - + SEPARATOR_COLON - + getCountryAsLowerCaseAlpha3(signerInformationEntity.getCountry())); + trustListEntry.setId(specification.getEntryId( + URLEncoder.encode(signerInformationEntity.getKid(), StandardCharsets.UTF_8))); + trustListEntry.setController(specification.getDocumentId(false)); trustListEntry.setPublicKeyJwk(publicKeyJwk); trustList.getVerificationMethod().add(trustListEntry); } + + private List filterEntities(List entities) { + + return entities.stream() + .filter(entity -> kdsConfigProperties.getDid().getGroupDenyList().stream() + .noneMatch(e -> entity.getGroup().equalsIgnoreCase(e))) + .toList(); + } + + private String getMappedGroupName(String groupName) { + + return kdsConfigProperties.getDid().getGroupNameMapping() + .computeIfAbsent(groupName, g -> g); + } + /** - * Search for CSCA for DSC. + * Recursively resolve certificate chains based on current database. + * Resolving is done country-code and domain aware. * - * @param dsc DSC to search CSCA for. - * @return Optional holding the CSCA if found. + * @param issuers List of SignerInformationEntity will be filled with found certs. + * Provide an empty List for initial call. + * @param cert SignerInformationEntity to search issuers for. */ - private Optional searchCsca(X509Certificate dsc, String country) { - - return trustedPartyService.getCscaByCountry(country) - .stream() - .map(csca -> parseCertificate(csca.getRawData())) - .filter(Objects::nonNull) - .filter(csca -> csca.getSubjectX500Principal() - .equals(dsc.getIssuerX500Principal())) - .findFirst(); + private void searchIssuer(List issuers, SignerInformationEntity cert) { + + try { + X509Certificate parsedCertificate = kdsCertUtils.parseCertificate(cert.getRawData()); + String issuerSubjectHash = certificateUtils.calculateHash(parsedCertificate.getIssuerX500Principal() + .getEncoded()); + + List possibleIssuers = signerInformationService + .getCertificatesBySubjectHashCountryDomain(issuerSubjectHash, cert.getCountry(), cert.getDomain()); + + possibleIssuers.forEach(possibleIssuer -> { + X509Certificate parsedPossibleIssuer = kdsCertUtils.parseCertificate(possibleIssuer.getRawData()); + + if (parsedPossibleIssuer.equals(parsedCertificate)) { + // Self-signed Certificate detected --> Stopping Cert Chain resolving + return; + } + + try { + parsedCertificate.verify(parsedPossibleIssuer.getPublicKey()); + // Signature check passed --> Adding issuer to chain + issuers.add(possibleIssuer); + // Also try to resolve issuer cert + searchIssuer(issuers, possibleIssuer); + + } catch (Exception ignored) { + // Signature Check failed -> Do not add this issuer to chain + } + }); + } catch (NoSuchAlgorithmException ignored) { + log.error("Failed to calculate Hash for Certificate Subject"); + } + } + + private String generateNonce() { + + final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; + final int nonceLength = 32; + StringBuilder nonce = new StringBuilder(); + + while (nonce.length() < nonceLength) { + nonce.append(chars.charAt((int) (Math.random() * chars.length()))); + } + + return nonce.toString(); } } diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/did/KdsDidContextDocumentLoaderConfig.java b/src/main/java/tng/trustnetwork/keydistribution/service/did/KdsDidContextDocumentLoaderConfig.java new file mode 100644 index 0000000..58e2e37 --- /dev/null +++ b/src/main/java/tng/trustnetwork/keydistribution/service/did/KdsDidContextDocumentLoaderConfig.java @@ -0,0 +1,51 @@ +package tng.trustnetwork.keydistribution.service.did; + + +import com.apicatalog.jsonld.document.JsonDocument; +import com.apicatalog.jsonld.loader.DocumentLoader; +import foundation.identity.jsonld.ConfigurableDocumentLoader; +import java.io.InputStream; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import tng.trustnetwork.keydistribution.config.KdsConfigProperties; + +@Slf4j +@Configuration +public class KdsDidContextDocumentLoaderConfig { + + public static final List DID_CONTEXTS = List.of( + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/suites/jws-2020/v1"); + + private static final String DID_CONTEXT_PATH = "did_contexts/"; + + @Bean + DocumentLoader kdsContextLoader(KdsConfigProperties configProperties) { + + Map contextMap = new HashMap<>(); + for (String didContext : DID_CONTEXTS) { + String didContextFile = configProperties.getDid().getContextMapping().get(didContext); + + if (didContextFile == null) { + throw new BeanInitializationException("Failed to load DID-Context Document for " + didContext + + " : No Mapping to local JSON-File."); + } + + try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream( + DID_CONTEXT_PATH + didContextFile)) { + if (inputStream != null) { + contextMap.put(URI.create(didContext), JsonDocument.of(inputStream)); + } + } catch (Exception e) { + throw new BeanInitializationException("Failed to load DID-Context Document", e); + } + } + return new ConfigurableDocumentLoader(contextMap); + } +} diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/did/LocalFileDidUploader.java b/src/main/java/tng/trustnetwork/keydistribution/service/did/LocalFileDidUploader.java index 8c734af..b1c6d97 100644 --- a/src/main/java/tng/trustnetwork/keydistribution/service/did/LocalFileDidUploader.java +++ b/src/main/java/tng/trustnetwork/keydistribution/service/did/LocalFileDidUploader.java @@ -62,13 +62,18 @@ public void uploadDid(String subContainer, byte[] content) { ).toFile(); } - log.info("Storing {} bytes to {}", content.length, targetFile.getAbsolutePath()); - if (targetFile.exists() && !targetFile.delete()) { log.error("Failed to delete existing file."); return; } + if (content == null) { + log.info("Requested to store file with null content - only deleting existing file"); + return; + } + + log.info("Storing {} bytes to {}", content.length, targetFile.getAbsolutePath()); + if (targetFile.getParentFile().mkdirs()) { log.info("Created required directory {}", targetFile.getParentFile().getAbsolutePath()); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 02fed8c..f3b634c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -42,12 +42,6 @@ management: info: name: ${spring.application.name} profiles: ${spring.profiles.active} -springdoc: - api-docs: - path: /api/docs - enabled: true - swagger-ui: - path: /swagger universal: resolver: "https://dev.uniresolver.io/1.0/identifiers" dgc: @@ -103,8 +97,9 @@ dgc: pat: didSigningProvider: dummy ld-proof-verification-method: did:web:dummy.net - ld-proof-nonce: n0nc3 did-id: did:web:abc + trust-list-path: trustlist + trust-list-ref-path: trustlist-ref did-controller: did:web:def trust-list-id-prefix: did:web:abc trust-list-controller-prefix: did:web:abc @@ -116,3 +111,8 @@ dgc: XB: XXB XO: XXO XL: XCL + group-deny-list: + - AUTHENTICATION + - UPLOAD + group-name-mapping: + CSCA: CSA diff --git a/src/main/resources/db/changelog.yaml b/src/main/resources/db/changelog.yaml index ae62c5a..a359c29 100644 --- a/src/main/resources/db/changelog.yaml +++ b/src/main/resources/db/changelog.yaml @@ -1,10 +1,8 @@ databaseChangeLog: - include: - file: db/changelog/init-tables.yaml + file: db/changelog/create-shedlock-tables.yaml - include: - file: db/changelog/alter-signer-information.yaml - - include: - file: db/changelog/create-info-table.yaml + file: db/changelog/create-signer-information-table.yaml - include: file: db/changelog/create-trusted-issuer-table.yaml - include: @@ -13,5 +11,3 @@ databaseChangeLog: file: db/changelog/create-public-key-jwk-table.yaml - include: file: db/changelog/create-verification-method-table.yaml - - include: - file: db/changelog/add-trusted-party-table.yaml diff --git a/src/main/resources/db/changelog/alter-signer-information.yaml b/src/main/resources/db/changelog/alter-signer-information.yaml deleted file mode 100644 index 740fbe2..0000000 --- a/src/main/resources/db/changelog/alter-signer-information.yaml +++ /dev/null @@ -1,29 +0,0 @@ -databaseChangeLog: - - objectQuotingStrategy: QUOTE_ONLY_RESERVED_WORDS - - changeSet: - id: delete old data - author: admin - changes: - - delete: - tableName: signer_information - - changeSet: - id: alter-signer-information - author: admin - changes: - - addColumn: - tableName: signer_information - columns: - - column: - name: country - type: varchar(2) - - column: - name: domain - type: varchar(512) - - column: - name: updated_at - type: timestamp with time zone - constraints: - nullable: false - - column: - name: deleted - type: boolean diff --git a/src/main/resources/db/changelog/create-info-table.yaml b/src/main/resources/db/changelog/create-info-table.yaml deleted file mode 100644 index 5a6ad82..0000000 --- a/src/main/resources/db/changelog/create-info-table.yaml +++ /dev/null @@ -1,18 +0,0 @@ -databaseChangeLog: - - changeSet: - id: create-info-table - author: admin - changes: - - createTable: - tableName: vs_info - columns: - - column: - name: identifier_key - type: varchar(255) - constraints: - primaryKey: true - primaryKeyName: pk_vs_info - nullable: false - - column: - name: property_value - type: varchar(255) diff --git a/src/main/resources/db/changelog/create-shedlock-tables.yaml b/src/main/resources/db/changelog/create-shedlock-tables.yaml new file mode 100644 index 0000000..207bf92 --- /dev/null +++ b/src/main/resources/db/changelog/create-shedlock-tables.yaml @@ -0,0 +1,38 @@ +databaseChangeLog: + - objectQuotingStrategy: QUOTE_ONLY_RESERVED_WORDS + - changeSet: + id: shedlock-create + author: admin + changes: + - createTable: + tableName: shedlock + columns: + - column: + name: id + type: bigint + autoIncrement: true + constraints: + primaryKey: true + primaryKeyName: pk_shedlock + nullable: false + - column: + name: name + type: varchar(64) + constraints: + nullable: false + unique: true + - column: + name: lock_until + type: datetime + constraints: + nullable: false + - column: + name: locked_at + type: datetime + constraints: + nullable: false + - column: + name: locked_by + type: varchar(255) + constraints: + nullable: false diff --git a/src/main/resources/db/changelog/add-trusted-party-table.yaml b/src/main/resources/db/changelog/create-signer-information-table.yaml similarity index 55% rename from src/main/resources/db/changelog/add-trusted-party-table.yaml rename to src/main/resources/db/changelog/create-signer-information-table.yaml index bccf7ca..be4acfb 100644 --- a/src/main/resources/db/changelog/add-trusted-party-table.yaml +++ b/src/main/resources/db/changelog/create-signer-information-table.yaml @@ -1,10 +1,10 @@ databaseChangeLog: - changeSet: - id: create-trusted-party-table - author: f11h + id: signer-information-create + author: admin changes: - createTable: - tableName: trusted_party + tableName: signer_information columns: - column: name: id @@ -12,19 +12,32 @@ databaseChangeLog: autoIncrement: true constraints: primaryKey: true + primaryKeyName: pk_signer_information nullable: false - column: - name: raw_data - type: varchar(4096) + name: kid + type: varchar(50) constraints: nullable: false - column: - name: country - type: varchar(2) + name: created_at + type: datetime constraints: nullable: false - column: - name: type - type: varchar(10) + name: raw_data + type: varchar(4096) constraints: nullable: false + - column: + name: country + type: varchar(2) + - column: + name: domain + type: varchar(50) + - column: + name: groupx + type: varchar(50) + - column: + name: subject_hash + type: varchar(64) diff --git a/src/main/resources/db/changelog/create-trusted-issuer-table.yaml b/src/main/resources/db/changelog/create-trusted-issuer-table.yaml index d6aa352..76bedec 100644 --- a/src/main/resources/db/changelog/create-trusted-issuer-table.yaml +++ b/src/main/resources/db/changelog/create-trusted-issuer-table.yaml @@ -14,11 +14,6 @@ databaseChangeLog: primaryKey: true primaryKeyName: pk_trusted_issuer nullable: false - - column: - name: etag - type: varchar(36) - constraints: - nullable: false - column: name: created_at type: timestamp with time zone diff --git a/src/main/resources/db/changelog/init-tables.yaml b/src/main/resources/db/changelog/init-tables.yaml deleted file mode 100644 index 938821a..0000000 --- a/src/main/resources/db/changelog/init-tables.yaml +++ /dev/null @@ -1,86 +0,0 @@ -databaseChangeLog: - - objectQuotingStrategy: QUOTE_ONLY_RESERVED_WORDS - - changeSet: - id: shedlock-create - author: admin - changes: - - createTable: - tableName: shedlock - columns: - - column: - name: id - type: bigint - constraints: - primaryKey: true - primaryKeyName: pk_shedlock - nullable: false - - column: - name: name - type: varchar(64) - constraints: - nullable: false - unique: true - - column: - name: lock_until - type: datetime - constraints: - nullable: false - - column: - name: locked_at - type: datetime - constraints: - nullable: false - - column: - name: locked_by - type: varchar(255) - constraints: - nullable: false - - changeSet: - id: shedlock-sequence - author: admin - changes: - - addAutoIncrement: - tableName: shedlock - columnName: id - columnDataType: bigint - startWith: 1 - incrementBy: 1 - - changeSet: - id: signer-information-create - author: admin - changes: - - createTable: - tableName: signer_information - columns: - - column: - name: id - type: bigint - constraints: - primaryKey: true - primaryKeyName: pk_signer_information - nullable: false - - column: - name: kid - type: varchar(50) - constraints: - nullable: false - - column: - name: created_at - type: datetime - constraints: - nullable: false - - column: - name: raw_data - type: varchar(4096) - constraints: - nullable: false - - changeSet: - id: signer-information-sequence - author: admin - changes: - - addAutoIncrement: - tableName: signer_information - columnName: id - columnDataType: bigint - startWith: 1 - incrementBy: 1 diff --git a/src/main/resources/static/context.json b/src/main/resources/static/context.json deleted file mode 100644 index 0034c4f..0000000 --- a/src/main/resources/static/context.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "origin": "DE", - "versions": { - "default": { - "privacyUrl": "https://publications.europa.eu/en/web/about-us/legal-notices/eu-mobile-apps", - "context": { - "url": "https://dgca-verifier-service.cfapps.eu10.hana.ondemand.com/context", - "pubKeys": [ - "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", - "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" - ] - }, - "endpoints": { - "status": { - "url": "https://dgca-verifier-service.cfapps.eu10.hana.ondemand.com/signercertificateStatus", - "pubKeys": [ - "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", - "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" - ] - }, - "update": { - "url": "https://dgca-verifier-service.cfapps.eu10.hana.ondemand.com/signercertificateUpdate", - "pubKeys": [ - "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", - "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" - ] - }, - "countryList": { - "url": "https://dgca-businessrule-service.cfapps.eu10.hana.ondemand.com/countrylist", - "pubKeys": [ - "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", - "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" - ] - }, - "rules": { - "url": "https://dgca-businessrule-service.cfapps.eu10.hana.ondemand.com/rules", - "pubKeys": [ - "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", - "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" - ] - }, - "valuesets": { - "url": "https://dgca-businessrule-service.cfapps.eu10.hana.ondemand.com/valuesets", - "pubKeys": [ - "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", - "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" - ] - } - } - }, - "0.1.0": { - "outdated": true - } - } -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/OpenApiTest.java b/src/test/java/tng/trustnetwork/keydistribution/OpenApiTest.java deleted file mode 100644 index 7b96ef4..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/OpenApiTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution; - -import eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector; -import java.io.BufferedInputStream; -import java.io.FileOutputStream; -import java.net.URL; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; - -@Slf4j -@SpringBootTest( - properties = { - "server.port=8080", - "springdoc.api-docs.enabled=true", - "springdoc.api-docs.path=/openapi" - }, - webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT -) -class OpenApiTest { - - @MockBean - private DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Test - void apiDocs() { - try (BufferedInputStream in = new BufferedInputStream(new URL("http://localhost:8080/openapi").openStream()); - FileOutputStream out = new FileOutputStream("target/openapi.json")) { - byte[] buffer = new byte[1024]; - int read; - while ((read = in.read(buffer, 0, buffer.length)) != -1) { - out.write(buffer, 0, read); - } - } catch (Exception e) { - log.error("Failed to download openapi specification.", e); - Assertions.fail(); - } - } - -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/ContextControllerIntegrationTest.java b/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/ContextControllerIntegrationTest.java deleted file mode 100644 index 23c4245..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/ContextControllerIntegrationTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - -@SpringBootTest -@AutoConfigureMockMvc -class ContextControllerIntegrationTest { - - @org.springframework.boot.test.mock.mockito.MockBean - eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Autowired - private MockMvc mockMvc; - - @Test - void requestContext() throws Exception { - mockMvc.perform(get("/context")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(result -> assertContextStrEqualFile(result)); - } - - private void assertContextStrEqualFile(MvcResult result) throws UnsupportedEncodingException { - String resultContext = result.getResponse().getContentAsString(); - Resource resource = new ClassPathResource("/static/context.json"); - String fileContext = null; - try { - fileContext = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8); - } catch (IOException e) { - Assertions.fail(e); - } - Assertions.assertEquals(resultContext, fileContext); - } - -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/ContextControllerWithEnvironmentIntegrationTest.java b/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/ContextControllerWithEnvironmentIntegrationTest.java deleted file mode 100644 index e3b0ec7..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/ContextControllerWithEnvironmentIntegrationTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; - -@SpringBootTest -@AutoConfigureMockMvc -@TestPropertySource(properties = {"dgc.context={\"testContext\": true}"}) -class ContextControllerWithEnvironmentIntegrationTest { - - @MockBean - eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Autowired - private MockMvc mockMvc; - - @Test - void requestContext() throws Exception { - mockMvc.perform(get("/context")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("{\"testContext\": true}")); - } -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/SignerInformationIntegrationTest.java b/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/SignerInformationIntegrationTest.java deleted file mode 100644 index 7f79e08..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/SignerInformationIntegrationTest.java +++ /dev/null @@ -1,365 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.io.UnsupportedEncodingException; -import java.time.ZonedDateTime; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import tng.trustnetwork.keydistribution.repository.SignerInformationRepository; -import tng.trustnetwork.keydistribution.testdata.SignerInformationTestHelper; - -@SpringBootTest -@AutoConfigureMockMvc -class SignerInformationIntegrationTest { - - - private static final String X_RESUME_TOKEN_HEADER = "X-RESUME-TOKEN"; - private static final String X_KID_HEADER = "X-KID"; - - @org.springframework.boot.test.mock.mockito.MockBean - eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Autowired - SignerInformationRepository signerInformationRepository; - - @Autowired - SignerInformationTestHelper signerInformationTestHelper; - - @Autowired - private MockMvc mockMvc; - - @BeforeEach - void clearRepositoryData() { - signerInformationRepository.deleteAll(); - } - - @Test - void requestCertificatesFromEmptyCertificateList() throws Exception { - mockMvc.perform(get("/signercertificateUpdate")) - .andExpect(status().isNoContent()); - - } - - @Test - void requestValidIdListFromEmptyCertificatesList() throws Exception { - mockMvc.perform(get("/signercertificateStatus")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("[]")); - } - - @Test - void requestOneCertificate() throws Exception { - Long certId_1 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - - mockMvc.perform(get("/signercertificateUpdate")) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(header().stringValues(X_KID_HEADER, "8xYtW2837ac=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_1_STR)); - - Long certId_2 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - - mockMvc.perform(get("/signercertificateUpdate")) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(header().stringValues(X_KID_HEADER, "8xYtW2837ac=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_1_STR)); - - } - - @Test - void requestValidIdList() throws Exception { - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - mockMvc.perform(get("/signercertificateStatus")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("[\"8xYtW2837ac=\"]")); - - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - mockMvc.perform(get("/signercertificateStatus")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("[\"8xYtW2837ac=\",\"EzVuT0kOpJc=\"]")); - - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_3_STR); - mockMvc.perform(get("/signercertificateStatus")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("[\"8xYtW2837ac=\",\"EzVuT0kOpJc=\",\"zoQi+KTb8LM=\"]")); - } - - @Test - void requestCertificatesWithResumeToken() throws Exception { - Long certId_1 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - - mockMvc.perform(get("/signercertificateUpdate")) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(header().stringValues(X_KID_HEADER, "8xYtW2837ac=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_1_STR)); - - mockMvc.perform(get("/signercertificateUpdate").header(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(status().isNoContent()); - - Long certId_2 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - Long certId_3 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_3_STR); - - mockMvc.perform(get("/signercertificateUpdate").header(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_2)) - .andExpect(header().stringValues(X_KID_HEADER, "EzVuT0kOpJc=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_2_STR)); - - mockMvc.perform(get("/signercertificateUpdate").header(X_RESUME_TOKEN_HEADER, certId_2)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_3)) - .andExpect(header().stringValues(X_KID_HEADER, "zoQi+KTb8LM=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_3_STR)); - - mockMvc.perform(get("/signercertificateUpdate").header(X_RESUME_TOKEN_HEADER, certId_3)) - .andExpect(status().isNoContent()); - - } - - @Test - void requestCertificatesFromCertListWithRevokedCerts() throws Exception { - Long certId_1 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - Long certId_2 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - Long certId_3 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_3_STR); - - mockMvc.perform(get("/signercertificateUpdate").header(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_2)) - .andExpect(header().stringValues(X_KID_HEADER, "EzVuT0kOpJc=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_2_STR)); - - signerInformationRepository.deleteById(certId_2); - - mockMvc.perform(get("/signercertificateUpdate").header(X_RESUME_TOKEN_HEADER, certId_1)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) - .andExpect(header().exists(X_KID_HEADER)) - .andExpect(header().exists(X_RESUME_TOKEN_HEADER)) - .andExpect(header().longValue(X_RESUME_TOKEN_HEADER, certId_3)) - .andExpect(header().stringValues(X_KID_HEADER, "zoQi+KTb8LM=")) - .andExpect(c -> assertCertStrEqual(c, SignerInformationTestHelper.TEST_CERT_3_STR)); - } - - @Test - void requestValidIdListFromCertListWithRevokedCert() throws Exception { - Long certId_1 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - Long certId_2 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - Long certId_3 = signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_3_STR); - - mockMvc.perform(get("/signercertificateStatus")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("[\"8xYtW2837ac=\",\"EzVuT0kOpJc=\",\"zoQi+KTb8LM=\"]")); - - signerInformationRepository.deleteById(certId_2); - - mockMvc.perform(get("/signercertificateStatus")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("[\"8xYtW2837ac=\",\"zoQi+KTb8LM=\"]")); - - } - - @Test - void requestDeltaNoHeader() throws Exception { - ZonedDateTime date1 = ZonedDateTime.parse("2022-04-13T02:21:00Z"); - Long certId_1 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_1_STR, - "de", "thumbp1", date1, false); - - Long certId_2 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_2_STR, - "de", "thumbp2", date1, true); - - mockMvc.perform(get("/signercertificateStatus/delta")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("{\"updated\":[\"8xYtW2837ac=\"],\"deleted\":[\"EzVuT0kOpJc=\"]}")); - - } - - @Test - void requestDeltaWithHeader() throws Exception { - ZonedDateTime date1 = ZonedDateTime.parse("2022-04-04T02:21:00Z"); - ZonedDateTime date2 = ZonedDateTime.parse("2022-04-13T02:21:00Z"); - Long certId_1 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_1_STR, - "de", "thumbp1", date1, false); - - Long certId_2 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_2_STR, - "de", "thumbp2", date2, false); - - Long certId_3 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_3_STR, - "de", "thumbp3", date2, true); - - mockMvc.perform(get("/signercertificateStatus/delta")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content(). - json("{\"updated\":[\"8xYtW2837ac=\",\"EzVuT0kOpJc=\"],\"deleted\":[\"zoQi+KTb8LM=\"]}")); - - mockMvc.perform(get("/signercertificateStatus/delta") - .header("if-modified-since","2022-04-04T02:20:00Z")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content(). - json("{\"updated\":[\"8xYtW2837ac=\",\"EzVuT0kOpJc=\"],\"deleted\":[\"zoQi+KTb8LM=\"]}")); - - mockMvc.perform(get("/signercertificateStatus/delta") - .header("if-modified-since","2022-04-04T02:21:00Z")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content(). - json("{\"updated\":[\"EzVuT0kOpJc=\"],\"deleted\":[\"zoQi+KTb8LM=\"]}")); - - mockMvc.perform(get("/signercertificateStatus/delta") - .header("if-modified-since","2022-04-13T02:21:00Z")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content(). - json("{\"updated\":[],\"deleted\":[]}")); - - mockMvc.perform(get("/signercertificateStatus/delta") - .header("if-modified-since","Mon, 04 Apr 2022 02:21:00 GMT")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content(). - json("{\"updated\":[\"EzVuT0kOpJc=\"],\"deleted\":[\"zoQi+KTb8LM=\"]}")); - - } - - @Test - void requestDeltaBadRequest() throws Exception { - - mockMvc.perform(get("/signercertificateStatus/delta") - .header("if-modified-since","NotValid")) - .andExpect(status().isBadRequest()) - .andExpect(content().string("Can not parse if-modified-since header")); - - } - - @Test - void requestCertificateData() throws Exception { - ZonedDateTime date1 = ZonedDateTime.parse("2022-04-13T02:21:00Z"); - Long certId_1 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_1_STR, - "de", "thumbp1", date1, false); - - Long certId_2 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_2_STR, - "de", "thumbp2", date1, true); - - mockMvc.perform(post("/signercertificateUpdate") - .contentType(MediaType.APPLICATION_JSON) - .content("[\"8xYtW2837ac=\",\"EzVuT0kOpJc=\"]") - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("{\"de\":[{\"kid\":\"8xYtW2837ac=\"," - + "\"rawData\":\"MIICrDCCAZSgAwIBAgIEYH+7ujANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1lZGdjX2Rldl90ZXN0MB4XDT" - + "IxMDQyMTA1NDQyNloXDTIyMDQyMTA1NDQyNlowGDEWMBQGA1UEAwwNZWRnY19kZXZfdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADgg" - + "EPADCCAQoCggEBAOAlpphOE0TH2m+jU6prmP1W6N0ajaExs5X+sxxG58hIGnZchxFkLkeYSZqyC2bPQtPiYIDgVFcPJPgfRO4r5e" - + "x3W7OxQCFS0TJmYhRkLiVQHQDNHeXFmOpu834x2ErPJ8AK2D9KhVyFKl5OX1euU25IXzXs67vQf30eStArvWFlZGX4E+JUy8yIwr" - + "R6WLRe+kgtBdFmJZJywbnnffg/5WT+TEcky8ugBlsEcyTxI5rt6iW5ptNUphui8ZGaE2KtjcnZVaPCvn1IjEv6sdWS/DNDlFySuJ" - + "6LQD1OnKsjCXrNVZFVZS5ae9snPu4Y/gapzdgeSDioRk6BWwZ02E9BE+8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEApE8H9uGtB6" - + "DuDL3LEqGslyJKyc6EBqJ+4hDlFtPe+13xEDomJsNwq1Uk3p9F1aHgqqXc1MjJfDWn0l7ZDGh02tfi+EgHyV2vrfqZwXm6vuK/P7" - + "fzdb5blLJpKt0NoMCzY+lHhkCxcRGX1R8QOGuuGtnepDrtyeTuoQqsh0mdcMuFgKuTr3c3kKpoQwBWquG/eZ0PhKSkqXy5aEaFAz" - + "dXBLq/dh4zn8FVx+STSpKK1WNmoqjtL7EEFcNgxLTjWJFjusTEZL0Yxa4Ot4Gb6+VK7P34olH7pFcBFYfh6DyOESV9uglrE4kdOQ" - + "7+x+yS5zR/UTeEfM4mW4I2QIEreUN8Jg==\"}," - + "{\"kid\":\"EzVuT0kOpJc=\",\"rawData\":\"MIIBGzCBwqADAgECAgRggU" - + "ObMAoGCCqGSM49BAMCMBYxFDASBgNVBAMMC2VkZ2NfZGV2X2VjMB4XDTIxMDQyMjA5MzYyN1oXDTIyMDQyMjA5MzYyN1owFjEUMB" - + "IGA1UEAwwLZWRnY19kZXZfZWMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQVQc9JY190s/Jn0CBSq/AWuxmqUzRVu+AsCe6gfb" - + "qk3s0e4jonzp5v/5IMW/9t7v5Fu2ITMmOTVfKL1TuM+aixMAoGCCqGSM49BAMCA0gAMEUCIQCGWIk6ZET3afRxdpFVuXdrEYtFiR" - + "1MGDx4HweZfspjSgIgBdCJsT746/FI3euIbzKDoeY65m+Qx2/4Cd/vOayNbuw=\"}]}")); - - } - - @Test - void requestCertificateDataNotExist() throws Exception { - ZonedDateTime date1 = ZonedDateTime.parse("2022-04-13T02:21:00Z"); - Long certId_1 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_1_STR, - "de", "thumbp1", date1, false); - - Long certId_2 = signerInformationTestHelper.insertCertString( - SignerInformationTestHelper.TEST_CERT_2_STR, - "de", "thumbp2", date1, true); - - mockMvc.perform(post("/signercertificateUpdate") - .contentType(MediaType.APPLICATION_JSON) - .content("[\"NotAvailable=\"]") - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().json("{}")); - - } - - - - - private void assertCertStrEqual(MvcResult result, String certStr) throws UnsupportedEncodingException { - String resultCert = result.getResponse().getContentAsString(); - - Assertions.assertEquals(certStr, resultCert); - - } -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/TrustedIssuerIntegrationTest.java b/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/TrustedIssuerIntegrationTest.java deleted file mode 100644 index a7e2fbb..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/restapi/controller/TrustedIssuerIntegrationTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.restapi.controller; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.HttpHeaders; -import org.springframework.test.web.servlet.MockMvc; -import tng.trustnetwork.keydistribution.repository.TrustedIssuerRepository; -import tng.trustnetwork.keydistribution.service.InfoService; -import tng.trustnetwork.keydistribution.testdata.TrustedIssuerTestHelper; - -@SpringBootTest -@AutoConfigureMockMvc -class TrustedIssuerIntegrationTest { - - @org.springframework.boot.test.mock.mockito.MockBean - eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Autowired - TrustedIssuerTestHelper trustedIssuerTestHelper; - - @Autowired - TrustedIssuerRepository trustedIssuerRepository; - - @Autowired - InfoService infoService; - - @Autowired - private MockMvc mockMvc; - - @BeforeEach - void clearRepositoryData() { - - trustedIssuerRepository.deleteAll(); - infoService.setValueForKey(InfoService.CURRENT_ETAG,"TestEtag"); - } - - @Test - void requestTrustedIssuersIsEmpty() throws Exception { - mockMvc.perform(get("/trustedissuers")) - .andExpect(status().isOk()) - .andExpect(content().json("[]")); - - } - - - @Test - void requestTrustedIssuers() throws Exception { - trustedIssuerTestHelper.insertTrustedIssuer(trustedIssuerTestHelper.getIssuer(1)); - - - mockMvc.perform(get("/trustedissuers")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].url").value("https://TestUrl.de")) - .andExpect(jsonPath("$[0].type").value("HTTP")) - .andExpect(jsonPath("$[0].country").value("DE")) - .andExpect(jsonPath("$[0].thumbprint").value("thumbprint1")) - .andExpect(jsonPath("$[0].sslPublicKey").value("PublicKey1")) - .andExpect(jsonPath("$[0].keyStorageType").value("JWKS")) - .andExpect(jsonPath("$[0].signature").value("Signature1")) - .andExpect(jsonPath("$[0].name").value("example1.de")); - - } - - @Test - void requestTrustedIssuersWithHeader() throws Exception { - trustedIssuerTestHelper.insertTrustedIssuer(trustedIssuerTestHelper.getIssuer(1)); - - - mockMvc.perform(get("/trustedissuers").header(HttpHeaders.IF_NONE_MATCH, "NoMatchEtag")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].url").value("https://TestUrl.de")) - .andExpect(jsonPath("$[0].type").value("HTTP")) - .andExpect(jsonPath("$[0].country").value("DE")) - .andExpect(jsonPath("$[0].thumbprint").value("thumbprint1")) - .andExpect(jsonPath("$[0].sslPublicKey").value("PublicKey1")) - .andExpect(jsonPath("$[0].keyStorageType").value("JWKS")) - .andExpect(jsonPath("$[0].signature").value("Signature1")) - .andExpect(jsonPath("$[0].name").value("example1.de")); - - } - - @Test - void requestTrustedIssuersWithHeaderMatchEtag() throws Exception { - trustedIssuerTestHelper.insertTrustedIssuer(trustedIssuerTestHelper.getIssuer(1)); - trustedIssuerTestHelper.insertTrustedIssuer(trustedIssuerTestHelper.getIssuer(2)); - - mockMvc.perform(get("/trustedissuers").header(HttpHeaders.IF_NONE_MATCH, "TestEtag")) - .andExpect(status().isNotModified()); - - } - -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java b/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java index 24de8de..6aa61c6 100644 --- a/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java +++ b/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java @@ -20,8 +20,10 @@ package tng.trustnetwork.keydistribution.service; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector; import eu.europa.ec.dgc.utils.CertificateUtils; @@ -53,10 +55,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import tng.trustnetwork.keydistribution.entity.SignerInformationEntity; -import tng.trustnetwork.keydistribution.entity.TrustedPartyEntity; import tng.trustnetwork.keydistribution.repository.SignerInformationRepository; import tng.trustnetwork.keydistribution.repository.TrustedIssuerRepository; -import tng.trustnetwork.keydistribution.repository.TrustedPartyRepository; import tng.trustnetwork.keydistribution.service.did.DidTrustListService; import tng.trustnetwork.keydistribution.service.did.DidUploader; import tng.trustnetwork.keydistribution.service.did.entity.DidTrustList; @@ -75,9 +75,6 @@ public class DidTrustListServiceTest { @Autowired SignerInformationRepository signerInformationRepository; - @Autowired - TrustedPartyRepository trustedPartyRepository; - @Autowired CertificateUtils certificateUtils; @@ -93,49 +90,68 @@ public class DidTrustListServiceTest { @MockBean DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - X509Certificate certCscaDe, certCscaEu, certDscDe, certDscEu; + X509Certificate certCscaDe, certCscaEu, certDscDe, certDscEu, certUploadDe; - String certDscDeKid, certDscEuKid; + String certDscDeKid, certDscEuKid, certCscaDeKid, certCscaEuKid, certUploadDeKid; @AfterEach public void cleanUp() { - trustedPartyRepository.deleteAll(); signerInformationRepository.deleteAll(); trustedIssuerRepository.deleteAll(); } void testData(CertificateTestUtils.SignerType signerType) throws Exception { + cleanUp(); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(signerType.getSigningAlgorithm()); + keyPairGenerator.initialize(signerType.getSigningAlgorithmSpec()); KeyPair cscaDeKeyPair = keyPairGenerator.generateKeyPair(); certCscaDe = CertificateTestUtils.generateCertificate(cscaDeKeyPair, "DE", "Test", signerType); + certCscaDeKid = certificateUtils.getCertKid(certCscaDe); + KeyPair cscaEuKeyPair = keyPairGenerator.generateKeyPair(); certCscaEu = CertificateTestUtils.generateCertificate(cscaEuKeyPair, "EU", "Test", signerType); + certCscaEuKid = certificateUtils.getCertKid(certCscaEu); certDscDe = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "DE", - "Test", certCscaDe, cscaDeKeyPair.getPrivate(), signerType); + "Test", certCscaDe, cscaDeKeyPair.getPrivate(), + signerType); certDscDeKid = certificateUtils.getCertKid(certDscDe); certDscEu = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EU", - "Test", certCscaEu, cscaEuKeyPair.getPrivate(), signerType); + "Test", certCscaEu, cscaEuKeyPair.getPrivate(), + signerType); certDscEuKid = certificateUtils.getCertKid(certDscEu); - trustedPartyRepository.save(new TrustedPartyEntity( + certUploadDe = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "DE", + "Upload Test", certCscaDe, cscaDeKeyPair.getPrivate(), + signerType); + certUploadDeKid = certificateUtils.getCertKid(certUploadDe); + + signerInformationRepository.save(new SignerInformationEntity( null, + certCscaDeKid, + ZonedDateTime.now(), Base64.getEncoder().encodeToString(certCscaDe.getEncoded()), "DE", - TrustedPartyEntity.Type.CSCA + "DCC", + "CSCA", + certificateUtils.calculateHash(certCscaDe.getSubjectX500Principal().getEncoded()) )); - trustedPartyRepository.save(new TrustedPartyEntity( + signerInformationRepository.save(new SignerInformationEntity( null, + certCscaEuKid, + ZonedDateTime.now(), Base64.getEncoder().encodeToString(certCscaEu.getEncoded()), "EU", - TrustedPartyEntity.Type.CSCA + "DCC", + "CSCA", + certificateUtils.calculateHash(certCscaEu.getSubjectX500Principal().getEncoded()) )); signerInformationRepository.save(new SignerInformationEntity( @@ -144,9 +160,9 @@ void testData(CertificateTestUtils.SignerType signerType) throws Exception { ZonedDateTime.now(), Base64.getEncoder().encodeToString(certDscDe.getEncoded()), "DE", - certificateUtils.getCertThumbprint(certDscDe), - ZonedDateTime.now(), - false + "DCC", + "DSC", + certificateUtils.calculateHash(certDscDe.getSubjectX500Principal().getEncoded()) )); signerInformationRepository.save(new SignerInformationEntity( @@ -155,9 +171,21 @@ void testData(CertificateTestUtils.SignerType signerType) throws Exception { ZonedDateTime.now(), Base64.getEncoder().encodeToString(certDscEu.getEncoded()), "EU", - certificateUtils.getCertThumbprint(certDscEu), + "DCC", + "DSC", + certificateUtils.calculateHash(certDscEu.getSubjectX500Principal().getEncoded()) + )); + + // Add Upload cert which should not be added to did + signerInformationRepository.save(new SignerInformationEntity( + null, + certUploadDeKid, ZonedDateTime.now(), - false + Base64.getEncoder().encodeToString(certUploadDe.getEncoded()), + "DE", + "DCC", + "UPLOAD", + certificateUtils.calculateHash(certUploadDe.getSubjectX500Principal().getEncoded()) )); trustedIssuerRepository.save(trustedIssuerTestHelper.createTrustedIssuer("DE")); @@ -168,37 +196,205 @@ void testData(CertificateTestUtils.SignerType signerType) throws Exception { @ParameterizedTest @ValueSource(booleans = {true, false}) void testTrustList(boolean isEcAlgorithm) throws Exception { + if (isEcAlgorithm) { testData(CertificateTestUtils.SignerType.EC); } else { testData(CertificateTestUtils.SignerType.RSA); } ArgumentCaptor uploadArgumentCaptor = ArgumentCaptor.forClass(byte[].class); - doNothing().when(didUploaderMock).uploadDid(uploadArgumentCaptor.capture()); + doNothing().when(didUploaderMock).uploadDid(anyString(), uploadArgumentCaptor.capture()); didTrustListService.job(); - SignedDidTrustList parsed = - objectMapper.readValue(uploadArgumentCaptor.getValue(), SignedDidTrustList.class); - - Assertions.assertEquals("did:web:abc", parsed.getId()); - Assertions.assertEquals("did:web:def", parsed.getController()); - Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + Assertions.assertEquals(48, uploadArgumentCaptor.getAllValues().size()); + + int expectedNullDid = 12; + + for (byte[] uploadedDid : uploadArgumentCaptor.getAllValues()) { + + if (uploadedDid == null) { + expectedNullDid--; + + Assertions.assertTrue(expectedNullDid >= 0, "DID Collection contains more empty documents than expected. (" + expectedNullDid * -1 + " too much)"); + continue; + } + + SignedDidTrustList parsed = objectMapper.readValue(uploadedDid, SignedDidTrustList.class); + + checkJsonDocument(parsed); + + switch (parsed.getId()) { + case "did:web:abc:trustlist": + Assertions.assertEquals("did:web:abc:trustlist", parsed.getController()); + Assertions.assertEquals(7, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist"); + break; + case "did:web:abc:trustlist:DCC:XEU:DSC": + Assertions.assertEquals("did:web:abc:trustlist:DCC:XEU:DSC", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:XEU:DSC#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:DCC:XEU:DSC"); + break; + case "did:web:abc:trustlist:DCC": + Assertions.assertEquals("did:web:abc:trustlist:DCC", parsed.getController()); + Assertions.assertEquals(7, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:DCC"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:DCC"); + break; + case "did:web:abc:trustlist:-:XEU": + Assertions.assertEquals("did:web:abc:trustlist:-:XEU", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:XEU#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:-:XEU"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:XEU#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:-:XEU"); + break; + case "did:web:abc:trustlist:-:DEU": + Assertions.assertEquals("did:web:abc:trustlist:-:DEU", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:DEU#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:-:DEU"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:DEU#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:-:DEU"); + break; + case "did:web:abc:trustlist:DCC:XEU:CSA": + Assertions.assertEquals("did:web:abc:trustlist:DCC:XEU:CSA", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:XEU:CSA#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:DCC:XEU:CSA"); + break; + case "did:web:abc:trustlist:DCC:DEU:DSC": + Assertions.assertEquals("did:web:abc:trustlist:DCC:DEU:DSC", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:DEU:DSC#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:DCC:DEU:DSC"); + break; + case "did:web:abc:trustlist:DCC:DEU:CSA": + Assertions.assertEquals("did:web:abc:trustlist:DCC:DEU:CSA", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:DEU:CSA#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:DCC:DEU:CSA"); + break; + case "did:web:abc:trustlist:DCC:DEU": + Assertions.assertEquals("did:web:abc:trustlist:DCC:DEU", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:DEU#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:DCC:DEU"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:DEU#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:DCC:DEU"); + break; + case "did:web:abc:trustlist:DCC:XEU": + Assertions.assertEquals("did:web:abc:trustlist:DCC:XEU", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:XEU#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:DCC:XEU"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:XEU#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:DCC:XEU"); + break; + case "did:web:abc:trustlist:-:XEU:DSC": + Assertions.assertEquals("did:web:abc:trustlist:-:XEU:DSC", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:XEU:DSC#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:-:XEU:DSC"); + break; + case "did:web:abc:trustlist:-:DEU:DSC": + Assertions.assertEquals("did:web:abc:trustlist:-:DEU:DSC", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:DEU:DSC#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:-:DEU:DSC"); + break; + case "did:web:abc:trustlist:-:DEU:CSA": + Assertions.assertEquals("did:web:abc:trustlist:-:DEU:CSA", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:DEU:CSA#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:-:DEU:CSA"); + break; + case "did:web:abc:trustlist:-:-:CSA": + Assertions.assertEquals("did:web:abc:trustlist:-:-:CSA", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:-:CSA#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:-:-:CSA"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:-:CSA#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:-:-:CSA"); + break; + case "did:web:abc:trustlist:-:-:DSC": + Assertions.assertEquals("did:web:abc:trustlist:-:-:DSC", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:-:DSC#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:-:-:DSC"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:-:DSC#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:-:-:DSC"); + break; + case "did:web:abc:trustlist:-:XEU:CSA": + Assertions.assertEquals("did:web:abc:trustlist:-:XEU:CSA", parsed.getController()); + Assertions.assertEquals(4, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:XEU:CSA#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:-:XEU:CSA"); + break; + case "did:web:abc:trustlist:DCC:-:DSC": + Assertions.assertEquals("did:web:abc:trustlist:DCC:-:DSC", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:-:DSC#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:DCC:-:DSC"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:-:DSC#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), + certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:DCC:-:DSC"); + break; + case "did:web:abc:trustlist:DCC:-:CSA": + Assertions.assertEquals("did:web:abc:trustlist:DCC:-:CSA", parsed.getController()); + Assertions.assertEquals(5, parsed.getVerificationMethod().size()); + + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:-:CSA#" + URLEncoder.encode(certCscaDeKid, StandardCharsets.UTF_8)), + certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:DCC:-:CSA"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:-:CSA#" + URLEncoder.encode(certCscaEuKid, StandardCharsets.UTF_8)), + certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:DCC:-:CSA"); + break; + default: + if (!parsed.getId().contains("trustlist-ref")) { + Assertions.fail("Unexpected Document in DID Collection! (" + parsed.getId() + ")"); + } + } + } + } - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "did:web:abc:deu#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), - certDscDeKid, certDscDe, certCscaDe, "deu"); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "did:web:abc:xeu#" + URLEncoder.encode(certDscEuKid, StandardCharsets.UTF_8)), - certDscEuKid, certDscEu, certCscaEu, "xeu"); + private void checkJsonDocument(SignedDidTrustList parsed) throws JsonProcessingException { Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:DE:issuer")); Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:EU:issuer")); Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:XY:issuer")); + Assertions.assertEquals(2, parsed.getContext().size()); Assertions.assertEquals("JsonWebSignature2020", parsed.getProof().getType()); Assertions.assertTrue( Instant.now().toEpochMilli() - parsed.getProof().getCreated().toInstant().toEpochMilli() < 10000); Assertions.assertEquals("d0m4in", parsed.getProof().getDomain()); - Assertions.assertEquals("n0nc3", parsed.getProof().getNonce()); + Assertions.assertEquals(32, parsed.getProof().getNonce().length()); Assertions.assertEquals("assertionMethod", parsed.getProof().getProofPurpose()); Assertions.assertEquals("did:web:dummy.net", parsed.getProof().getVerificationMethod()); Assertions.assertNotNull(parsed.getProof().getJws()); @@ -212,38 +408,43 @@ void testTrustList(boolean isEcAlgorithm) throws Exception { private Object getVerificationMethodByKid(List verificationMethods, String kid) { + return verificationMethods.stream() - .filter(entry -> entry instanceof LinkedHashMap) - .map(entry -> (LinkedHashMap) entry) - .filter(entry -> entry.get("id").equals(kid)) - .findFirst() - .orElseGet(() -> Assertions.fail("Could not find VerificationMethod with KID " + kid)); + .filter(entry -> entry instanceof LinkedHashMap) + .map(entry -> (LinkedHashMap) entry) + .filter(entry -> entry.get("id").equals(kid)) + .findFirst() + .orElseGet( + () -> Assertions.fail("Could not find VerificationMethod with KID " + kid)); } - private void assertVerificationMethod(Object in, String kid, X509Certificate dsc, X509Certificate csca, String country) - throws CertificateEncodingException { + private void assertVerificationMethod(Object in, String kid, X509Certificate dsc, X509Certificate csca, + String parentDidId) + throws CertificateEncodingException { + LinkedHashMap jsonNode = (LinkedHashMap) in; Assertions.assertEquals("JsonWebKey2020", jsonNode.get("type")); - Assertions.assertEquals("did:web:abc:" + country, jsonNode.get("controller")); - Assertions.assertEquals("did:web:abc:" + country + "#" + URLEncoder.encode(kid, StandardCharsets.UTF_8), jsonNode.get("id")); + Assertions.assertEquals(parentDidId, jsonNode.get("controller")); + Assertions.assertEquals(parentDidId + "#" + URLEncoder.encode(kid, StandardCharsets.UTF_8), + jsonNode.get("id")); LinkedHashMap publicKeyJwk = (LinkedHashMap) jsonNode.get("publicKeyJwk"); if (dsc.getPublicKey().getAlgorithm().equals(CertificateTestUtils.SignerType.EC.getSigningAlgorithm())) { Assertions.assertEquals(((ECPublicKey) dsc.getPublicKey()).getW().getAffineX(), - new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("x").toString()))); + new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("x").toString()))); Assertions.assertEquals(((ECPublicKey) dsc.getPublicKey()).getW().getAffineY(), - new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("y").toString()))); + new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("y").toString()))); Assertions.assertEquals(CertificateTestUtils.SignerType.EC.getSigningAlgorithm(), - publicKeyJwk.get("kty").toString()); + publicKeyJwk.get("kty").toString()); Assertions.assertEquals("P-256", publicKeyJwk.get("crv").toString()); } else { Assertions.assertEquals(((RSAPublicKey) dsc.getPublicKey()).getPublicExponent(), - new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("e").toString()))); + new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("e").toString()))); Assertions.assertEquals(((RSAPublicKey) dsc.getPublicKey()).getModulus(), - new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("n").toString()))); + new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("n").toString()))); Assertions.assertEquals(CertificateTestUtils.SignerType.RSA.getSigningAlgorithm(), - publicKeyJwk.get("kty").toString()); + publicKeyJwk.get("kty").toString()); } ArrayList x5c = ((ArrayList) publicKeyJwk.get("x5c")); Assertions.assertEquals(Base64.getEncoder().encodeToString(dsc.getEncoded()), x5c.get(0)); diff --git a/src/test/java/tng/trustnetwork/keydistribution/service/InfoServiceTest.java b/src/test/java/tng/trustnetwork/keydistribution/service/InfoServiceTest.java deleted file mode 100644 index b7a07ba..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/service/InfoServiceTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.service; - -import eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector; -import java.util.List; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import tng.trustnetwork.keydistribution.entity.InfoEntity; -import tng.trustnetwork.keydistribution.repository.InfoRepository; - -@SpringBootTest -class InfoServiceTest { - - @MockBean - DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Autowired - InfoRepository infoRepository; - - @Autowired - InfoService infoService; - - - - @BeforeEach - void clearRepositoryData() { - infoRepository.deleteAll(); - } - - - @Test - void saveInfo() throws Exception { - - infoService.setValueForKey("TestKey", "TestValue"); - - List entities = infoRepository.findAll(); - - Assertions.assertEquals(1, entities.size()); - Assertions.assertEquals("TestKey", entities.get(0).getIdentifierKey()); - Assertions.assertEquals("TestValue", entities.get(0).getValue()); - - } - - @Test - void getInfo() throws Exception { - - InfoEntity entity = new InfoEntity("TestKey", "TestValue"); - infoRepository.save(entity); - - Assertions.assertEquals("TestValue", infoService.getValueForKey("TestKey")); - } -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadServiceTest.java b/src/test/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadServiceTest.java index d2a2cbe..0828d20 100644 --- a/src/test/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadServiceTest.java +++ b/src/test/java/tng/trustnetwork/keydistribution/service/SignerCertificateDownloadServiceTest.java @@ -52,13 +52,13 @@ class SignerCertificateDownloadServiceTest { @Test void downloadEmptyCertificatesList() { - ArrayList trustList = new ArrayList<>(); - Mockito.when(dgcGatewayDownloadConnector.getTrustedCertificates()).thenReturn(trustList); + ArrayList trustList = new ArrayList<>(); + Mockito.when(dgcGatewayDownloadConnector.getDdccTrustedCertificates()).thenReturn(trustList); signerCertificateDownloadService.downloadCertificates(); - List repositoryItems = signerInformationRepository.findAllByDeletedOrderByIdAsc(false); - Assertions.assertEquals(0, repositoryItems.size()); + List repositoryItems = signerInformationRepository.findAll(); + Assertions.assertTrue(repositoryItems.isEmpty()); } @Test diff --git a/src/test/java/tng/trustnetwork/keydistribution/service/SignerInformationServiceTest.java b/src/test/java/tng/trustnetwork/keydistribution/service/SignerInformationServiceTest.java index 8c9a5fc..d02052f 100644 --- a/src/test/java/tng/trustnetwork/keydistribution/service/SignerInformationServiceTest.java +++ b/src/test/java/tng/trustnetwork/keydistribution/service/SignerInformationServiceTest.java @@ -21,20 +21,11 @@ package tng.trustnetwork.keydistribution.service; import eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.List; -import eu.europa.ec.dgc.gateway.connector.model.TrustedCertificateTrustListItem; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import tng.trustnetwork.keydistribution.dto.TrustedIssuerDto; -import tng.trustnetwork.keydistribution.entity.SignerInformationEntity; import tng.trustnetwork.keydistribution.repository.SignerInformationRepository; -import tng.trustnetwork.keydistribution.restapi.dto.DeltaListDto; import tng.trustnetwork.keydistribution.testdata.SignerInformationTestHelper; @SpringBootTest @@ -57,157 +48,4 @@ void clearRepositoryData() { signerInformationRepository.deleteAll(); } - - @Test - void updateEmptyRepositoryWithEmptyCertList() { - ArrayList trustList = new ArrayList<>(); - - signerInformationService.updateTrustedCertsList(trustList); - - List repositoryItems = signerInformationRepository.findAll(); - - Assertions.assertEquals(0, repositoryItems.size()); - - } - - @Test - void updateEmptyRepositoryWithOneCert() { - ArrayList trustList = new ArrayList<>(); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_1_STR)); - - signerInformationService.updateTrustedCertsList(trustList); - - List repositoryItems = signerInformationRepository.findAll(); - - Assertions.assertEquals(1, repositoryItems.size()); - - SignerInformationEntity repositoryItem = repositoryItems.get(0); - - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_1_KID, repositoryItem.getKid()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_1_STR, repositoryItem.getRawData()); - - } - - @Test - void updateEmptyRepositoryWithCerts() { - ArrayList trustList = new ArrayList<>(); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_1_STR)); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_2_STR)); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_3_STR)); - - signerInformationService.updateTrustedCertsList(trustList); - - List repositoryItems = signerInformationRepository.findAll(); - - Assertions.assertEquals(3, repositoryItems.size()); - - SignerInformationEntity repositoryItem = repositoryItems.get(0); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_1_KID, repositoryItem.getKid()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_1_STR, repositoryItem.getRawData()); - repositoryItem = repositoryItems.get(1); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_2_KID, repositoryItem.getKid()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_2_STR, repositoryItem.getRawData()); - repositoryItem = repositoryItems.get(2); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_3_KID, repositoryItem.getKid()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_3_STR, repositoryItem.getRawData()); - - } - - @Test - void updateEmptyRepositoryWithSameCertsTwice() { - ArrayList trustList = new ArrayList<>(); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_1_STR)); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_2_STR)); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_3_STR)); - - signerInformationService.updateTrustedCertsList(trustList); - - List repositoryItems = signerInformationRepository.findAll(); - - Assertions.assertEquals(3, repositoryItems.size()); - - SignerInformationEntity repositoryItem0 = repositoryItems.get(0); - SignerInformationEntity repositoryItem1 = repositoryItems.get(1); - SignerInformationEntity repositoryItem2 = repositoryItems.get(2); - - signerInformationService.updateTrustedCertsList(trustList); - - repositoryItems = signerInformationRepository.findAll(); - - Assertions.assertEquals(3, repositoryItems.size()); - - SignerInformationEntity repositoryItem = repositoryItems.get(0); - Assertions.assertEquals(repositoryItem0, repositoryItem); - repositoryItem = repositoryItems.get(1); - Assertions.assertEquals(repositoryItem1, repositoryItem); - repositoryItem = repositoryItems.get(2); - Assertions.assertEquals(repositoryItem2, repositoryItem); - } - - @Test - void updateRepositoryWithOneNewCertAndOneRevoked() { - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - - - ArrayList trustList = new ArrayList<>(); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_2_STR)); - trustList.add(signerInformationTestHelper.createTrustedCertificateTrustListItem(SignerInformationTestHelper.TEST_CERT_3_STR)); - - signerInformationService.updateTrustedCertsList(trustList); - - List repositoryItems = signerInformationRepository.findAllByDeletedOrderByIdAsc(false); - - Assertions.assertEquals(2, repositoryItems.size()); - - SignerInformationEntity repositoryItem0 = repositoryItems.get(0); - SignerInformationEntity repositoryItem1 = repositoryItems.get(1); - - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_2_KID, repositoryItem0.getKid()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_2_STR, repositoryItem0.getRawData()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_3_KID, repositoryItem1.getKid()); - Assertions.assertEquals(SignerInformationTestHelper.TEST_CERT_3_STR, repositoryItem1.getRawData()); - - } - - @Test - void updateRepositoryWithEmptyCertList() { - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_1_STR); - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_2_STR); - signerInformationTestHelper.insertCertString(SignerInformationTestHelper.TEST_CERT_3_STR); - - ArrayList trustList = new ArrayList<>(); - - signerInformationService.updateTrustedCertsList(trustList); - - List repositoryItems = signerInformationRepository.findAllByDeletedOrderByIdAsc(false); - - Assertions.assertEquals(0, repositoryItems.size()); - - } - - @Test - void dataTypeTests() { - - List updated = new ArrayList<>(); - updated.add("updated"); - List deleted = new ArrayList<>(); - deleted.add("deleted"); - DeltaListDto deltaListDto = new DeltaListDto(updated, deleted); - Assertions.assertEquals("updated",deltaListDto.getUpdated().get(0)); - Assertions.assertEquals("deleted",deltaListDto.getDeleted().get(0)); - deltaListDto.setDeleted(updated); - deltaListDto.setUpdated(deleted); - Assertions.assertEquals("deleted",deltaListDto.getUpdated().get(0)); - Assertions.assertEquals("updated",deltaListDto.getDeleted().get(0)); - - - TrustedIssuerDto issuer = new - TrustedIssuerDto("url", TrustedIssuerDto.UrlTypeDto.HTTP,"DE","TP1","PK1", - "JWKM","signature1", ZonedDateTime.now(),"name"); - Assertions.assertEquals("url",issuer.getUrl()); - issuer.setUrl("newUrl"); - Assertions.assertEquals("newUrl",issuer.getUrl()); - } - } diff --git a/src/test/java/tng/trustnetwork/keydistribution/service/TrustedPartyServiceTest.java b/src/test/java/tng/trustnetwork/keydistribution/service/TrustedPartyServiceTest.java deleted file mode 100644 index bbd8962..0000000 --- a/src/test/java/tng/trustnetwork/keydistribution/service/TrustedPartyServiceTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * ---license-start - * WorldHealthOrganization / tng-key-distribution - * --- - * Copyright (C) 2021 - 2024 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - */ - -package tng.trustnetwork.keydistribution.service; - -import eu.europa.ec.dgc.gateway.connector.DgcGatewayDownloadConnector; -import eu.europa.ec.dgc.gateway.connector.model.TrustListItem; -import java.util.List; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import tng.trustnetwork.keydistribution.entity.TrustedPartyEntity; -import tng.trustnetwork.keydistribution.repository.TrustedPartyRepository; - -@SpringBootTest -class TrustedPartyServiceTest { - - @MockBean - DgcGatewayDownloadConnector dgcGatewayDownloadConnector; - - @Autowired - TrustedPartyRepository trustedPartyRepository; - - @Autowired - TrustedPartyService trustedPartyService; - - @BeforeEach - void clearRepositoryData() { - trustedPartyRepository.deleteAll(); - } - - @Test - void testUpdateCsca() { - - trustedPartyRepository.save(TrustedPartyEntity.builder() - .country("CO") - .rawData("raw_data_old") - .type(TrustedPartyEntity.Type.CSCA) - .build()); - - // Build Test-Data - TrustListItem trustListItem1 = new TrustListItem(); - trustListItem1.setCountry("XX"); - trustListItem1.setSignature("sig1"); - trustListItem1.setRawData("raw1"); - - TrustListItem trustListItem2 = new TrustListItem(); - trustListItem2.setCountry("YY"); - trustListItem2.setSignature("sig2"); - trustListItem2.setRawData("raw2"); - List trustlist = List.of(trustListItem1, trustListItem2); - - // Pass Testdata to Service - trustedPartyService.updateCscaFromTrustList(trustlist); - - // Existing TrustedParty should be deleted and the 2 new ones from testdata should be inserted - Assertions.assertEquals(2, trustedPartyRepository.count()); - List persistedTrustedParties = trustedPartyRepository.findAll(); - - Assertions.assertEquals(TrustedPartyEntity.Type.CSCA, persistedTrustedParties.get(0).getType()); - Assertions.assertEquals(trustListItem1.getCountry(), persistedTrustedParties.get(0).getCountry()); - Assertions.assertEquals(trustListItem1.getRawData(), persistedTrustedParties.get(0).getRawData()); - - Assertions.assertEquals(TrustedPartyEntity.Type.CSCA, persistedTrustedParties.get(1).getType()); - Assertions.assertEquals(trustListItem2.getCountry(), persistedTrustedParties.get(1).getCountry()); - Assertions.assertEquals(trustListItem2.getRawData(), persistedTrustedParties.get(1).getRawData()); - - } - - @Test - void testGetCscaByCountry() { - - TrustedPartyEntity tp1 = trustedPartyRepository.save(new TrustedPartyEntity(null, "", "C1", TrustedPartyEntity.Type.CSCA)); - TrustedPartyEntity tp2 = trustedPartyRepository.save(new TrustedPartyEntity(null, "", "C1", TrustedPartyEntity.Type.CSCA)); - TrustedPartyEntity tp3 = trustedPartyRepository.save(new TrustedPartyEntity(null, "", "C2", TrustedPartyEntity.Type.CSCA)); - TrustedPartyEntity tp4 = trustedPartyRepository.save(new TrustedPartyEntity(null, "", "C2", TrustedPartyEntity.Type.CSCA)); - - trustedPartyRepository.saveAll(List.of(tp1, tp2, tp3, tp4)); - - TrustedPartyEntity[] c1tp = trustedPartyService.getCscaByCountry("C1").toArray(new TrustedPartyEntity[2]); - TrustedPartyEntity[] c2tp = trustedPartyService.getCscaByCountry("C2").toArray(new TrustedPartyEntity[2]); - - Assertions.assertArrayEquals(c1tp, new TrustedPartyEntity[] { tp1, tp2 }); - Assertions.assertArrayEquals(c2tp, new TrustedPartyEntity[] { tp3, tp4 }); - - } - -} diff --git a/src/test/java/tng/trustnetwork/keydistribution/testdata/CertificateTestUtils.java b/src/test/java/tng/trustnetwork/keydistribution/testdata/CertificateTestUtils.java index 5673394..c33cf75 100644 --- a/src/test/java/tng/trustnetwork/keydistribution/testdata/CertificateTestUtils.java +++ b/src/test/java/tng/trustnetwork/keydistribution/testdata/CertificateTestUtils.java @@ -20,17 +20,16 @@ package tng.trustnetwork.keydistribution.testdata; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import eu.europa.ec.dgc.gateway.connector.model.ValidationRule; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.RSAKeyGenParameterSpec; import java.time.Instant; -import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.Date; -import java.util.List; import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -44,41 +43,9 @@ import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.junit.jupiter.api.Assertions; public class CertificateTestUtils { - public static ValidationRule getDummyValidationRule() { - ValidationRule validationRule = new ValidationRule(); - - JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; - - validationRule.setLogic(jsonNodeFactory.objectNode().set("field1", jsonNodeFactory.textNode("value1"))); - validationRule.setValidTo(ZonedDateTime.now().plus(1, ChronoUnit.WEEKS)); - validationRule.setValidFrom(ZonedDateTime.now().plus(3, ChronoUnit.DAYS)); - validationRule.setCertificateType("General"); - validationRule.setDescription(List.of(new ValidationRule.DescriptionItem("en", "de".repeat(10)))); - validationRule.setEngine("CERTLOGIC"); - validationRule.setEngineVersion("1.0.0"); - validationRule.setVersion("1.0.0"); - validationRule.setAffectedFields(List.of("AB", "DE")); - validationRule.setRegion("BW"); - validationRule.setSchemaVersion("1.0.0"); - validationRule.setType("Acceptance"); - validationRule.setIdentifier("GR-EU-0001"); - validationRule.setCountry("EU"); - - return validationRule; - } - - public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName) - throws Exception { - Date validFrom = Date.from(Instant.now().minus(1, ChronoUnit.DAYS)); - Date validTo = Date.from(Instant.now().plus(365, ChronoUnit.DAYS)); - - return generateCertificate(keyPair, country, commonName, validFrom, validTo, SignerType.EC); - } - public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName, SignerType signerType) throws Exception { Date validFrom = Date.from(Instant.now().minus(1, ChronoUnit.DAYS)); @@ -87,14 +54,6 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr return generateCertificate(keyPair, country, commonName, validFrom, validTo, signerType); } - public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName, - X509Certificate ca, PrivateKey caKey) throws Exception { - Date validFrom = Date.from(Instant.now().minus(1, ChronoUnit.DAYS)); - Date validTo = Date.from(Instant.now().plus(365, ChronoUnit.DAYS)); - - return generateCertificate(keyPair, country, commonName, validFrom, validTo, ca, caKey, SignerType.EC); - } - public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName, X509Certificate ca, PrivateKey caKey, SignerType signerType) throws Exception { @@ -148,31 +107,15 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr return new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner)); } - public static void assertEquals(ValidationRule v1, ValidationRule v2) { - Assertions.assertEquals(v1.getIdentifier(), v2.getIdentifier()); - Assertions.assertEquals(v1.getType(), v2.getType()); - Assertions.assertEquals(v1.getCountry(), v2.getCountry()); - Assertions.assertEquals(v1.getRegion(), v2.getRegion()); - Assertions.assertEquals(v1.getVersion(), v2.getVersion()); - Assertions.assertEquals(v1.getSchemaVersion(), v2.getSchemaVersion()); - Assertions.assertEquals(v1.getEngine(), v2.getEngine()); - Assertions.assertEquals(v1.getEngineVersion(), v2.getEngineVersion()); - Assertions.assertEquals(v1.getCertificateType(), v2.getCertificateType()); - Assertions.assertEquals(v1.getDescription(), v2.getDescription()); - Assertions.assertEquals(v1.getValidFrom().toEpochSecond(), v2.getValidFrom().toEpochSecond()); - Assertions.assertEquals(v1.getValidTo().toEpochSecond(), v2.getValidTo().toEpochSecond()); - Assertions.assertEquals(v1.getAffectedFields(), v2.getAffectedFields()); - Assertions.assertEquals(v1.getLogic(), v2.getLogic()); - } - @RequiredArgsConstructor(access = AccessLevel.PRIVATE) @Getter public static class SignerType { private final String signingMethod; private final String signingAlgorithm; + private final AlgorithmParameterSpec signingAlgorithmSpec; - public static SignerType RSA = new SignerType("SHA256withRSA", "RSA"); - public static SignerType EC = new SignerType("SHA256withECDSA", "EC"); + public static SignerType RSA = new SignerType("SHA256withRSA", "RSA", new RSAKeyGenParameterSpec(2048, BigInteger.valueOf(65537L))); + public static SignerType EC = new SignerType("SHA256withECDSA", "EC", new ECGenParameterSpec("secp256r1")); } } diff --git a/src/test/java/tng/trustnetwork/keydistribution/testdata/SignerInformationTestHelper.java b/src/test/java/tng/trustnetwork/keydistribution/testdata/SignerInformationTestHelper.java index 8d132cc..c85cb81 100644 --- a/src/test/java/tng/trustnetwork/keydistribution/testdata/SignerInformationTestHelper.java +++ b/src/test/java/tng/trustnetwork/keydistribution/testdata/SignerInformationTestHelper.java @@ -39,7 +39,6 @@ @RequiredArgsConstructor public class SignerInformationTestHelper { - public static final String TEST_CERT_1_STR = "MIICrDCCAZSgAwIBAgIEYH+7ujANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1l" + "ZGdjX2Rldl90ZXN0MB4XDTIxMDQyMTA1NDQyNloXDTIyMDQyMTA1NDQyNlowGDEW" @@ -59,41 +58,6 @@ public class SignerInformationTestHelper { public static final String TEST_CERT_1_KID = "8xYtW2837ac="; - public static final String TEST_CERT_2_STR = - "MIIBGzCBwqADAgECAgRggUObMAoGCCqGSM49BAMCMBYxFDASBgNVBAMMC2VkZ2Nf" - + "ZGV2X2VjMB4XDTIxMDQyMjA5MzYyN1oXDTIyMDQyMjA5MzYyN1owFjEUMBIGA1UE" - + "AwwLZWRnY19kZXZfZWMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQVQc9JY190" - + "s/Jn0CBSq/AWuxmqUzRVu+AsCe6gfbqk3s0e4jonzp5v/5IMW/9t7v5Fu2ITMmOT" - + "VfKL1TuM+aixMAoGCCqGSM49BAMCA0gAMEUCIQCGWIk6ZET3afRxdpFVuXdrEYtF" - + "iR1MGDx4HweZfspjSgIgBdCJsT746/FI3euIbzKDoeY65m+Qx2/4Cd/vOayNbuw="; - - public static final String TEST_CERT_2_KID = "EzVuT0kOpJc="; - - public static final String TEST_CERT_3_STR = - "MIIDqDCCAhCgAwIBAgIEYIFDEjANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtl" - + "ZGdjX2Rldl9kZTAeFw0yMTA0MjIwOTM0MTBaFw0yMjA0MjIwOTM0MTBaMBYxFDAS" - + "BgNVBAMMC2VkZ2NfZGV2X2RlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKC" - + "AYEAt1aoSm/JB7qth70XBPR4avb1wcKHpBLFBDZIZnHzKYWvIy6JIXgd342tK825" - + "0jOJ5UC1SVJdtAckWEkV5HYQ3qJ7qr6booEQzK64lLSk6oimjOnnIOFWEIrPPqW+" - + "nQFOyw96opf6ISiyVvUipJVFuQC2RE3Ci/yKGBO7LeMQi2FDw+edo4/HtsmJlkEz" - + "8JxnCniwjTRCnRGNAs7YXMlrwcCcyIarDtxbdbcwm/6WpuOnj8MzTAAUXQ+SeFOq" - + "MlvUosKxL34nJ7liHySu6uuGCopFSvuRh3yIuwAqeufGVKBfoiJkrtsn+AB/Q/kP" - + "XpPR7Dk2NybbJX3g+dh2ok08zpbVcYBRrtITXPZIQvLuZXMd1CUnNz0aOWNAxT6P" - + "v4R4ROavuQcjJR785mspCovqXCy8SpD4JHs+HxYqE7RTWzd3j4HmPf7NuWMnlH04" - + "J2h10V/EffHu65+wQ4s9dMCRLttOBScV6EAgRLoCt11tvc8XUxzI0yq17YntZDr2" - + "1SjJAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABIWLWx/RQ3WQoHXmbLhkTTtM2b3" - + "Q/TZCXz5ZB89l/CrTeLQ+hy5pYv5HUTz00JnikyxbfVwsNhfVRMYm0NVJf6WWqHB" - + "OIk9MKAxksJ49QFHdL2sW4Vm5XhGy2FDaEgtx58q3koNHY9e5FyOcEZcXo2+eXKO" - + "bOsj80RJV5aj53SWY3Si+sq9iJMGYghskaEs/rnWn65ullbUKuC1+vkOV3qfFPKo" - + "CxeHlmGzdokRzbVKtXjDqb/edRX6I4k7laZ0+irFQqftvkaMHVEf13nXTIgQ9rpp" - + "+JQ0Y2pWSLPnWf/dah/D0/NmwI6E6V5+9U6i73RcalGw97gfyorMkYFFE8ByLdfp" - + "n76oTgJaXN/CQDLm2yzOX/ynt4t0ycqcVYrzewiKY2Fpnhao4U00vrh+0lwdUFr3" - + "jpOMeNg/2UDYhpWwWiT1ik+D6PSfKQ7Amuph6VcYEy/grQxNxPWcghoZSVKdXhOz" - + "6ggdK/eFNlO1aYj/DLxV3ZWcrAYk6dS4rnn8Ow=="; - - public static final String TEST_CERT_3_KID = "zoQi+KTb8LM="; - - private final SignerInformationRepository signerInformationRepository; private final CertificateUtils certificateUtils; private X509Certificate convertStringToX509Cert(String certificate) throws CertificateException { @@ -103,71 +67,6 @@ private X509Certificate convertStringToX509Cert(String certificate) throws Certi .generateCertificate(targetStream); } - public Long insertCertString(String certStr) { - String kid; - try { - kid = certificateUtils.getCertKid(convertStringToX509Cert(certStr)); - }catch (CertificateException e) { - kid = "kid_"+ ZonedDateTime.now(); - } - - SignerInformationEntity cert = new SignerInformationEntity( - null, - kid, - ZonedDateTime.now(), - certStr, - "de", - "thumbprint", - ZonedDateTime.now(), - false - ); - - signerInformationRepository.save(cert); - - return cert.getId(); - } - - public Long insertCertString(String certStr, String country, - String thumbprint, ZonedDateTime date, boolean deleted) { - String kid; - try { - kid = certificateUtils.getCertKid(convertStringToX509Cert(certStr)); - }catch (CertificateException e) { - kid = "kid_"+ ZonedDateTime.now(); - } - - SignerInformationEntity cert = new SignerInformationEntity( - null, - kid, - ZonedDateTime.now(), - certStr, - country, - thumbprint, - date, - deleted - ); - - signerInformationRepository.save(cert); - - return cert.getId(); - } - - public TrustListItem createTrustListItem(String certStr) { - String kid; - try { - kid = certificateUtils.getCertKid(convertStringToX509Cert(certStr)); - }catch (CertificateException e) { - kid = "kid_"+ ZonedDateTime.now(); - } - - TrustListItem item = new TrustListItem(); - item.setKid(kid); - item.setTimestamp(ZonedDateTime.now()); - item.setRawData(certStr); - - return item; - } - public TrustedCertificateTrustListItem createTrustedCertificateTrustListItem(String certStr) { String kid; try { @@ -183,5 +82,4 @@ public TrustedCertificateTrustListItem createTrustedCertificateTrustListItem(Str return item; } - } diff --git a/src/test/java/tng/trustnetwork/keydistribution/testdata/TrustedIssuerTestHelper.java b/src/test/java/tng/trustnetwork/keydistribution/testdata/TrustedIssuerTestHelper.java index 0cc3c02..b880bd2 100644 --- a/src/test/java/tng/trustnetwork/keydistribution/testdata/TrustedIssuerTestHelper.java +++ b/src/test/java/tng/trustnetwork/keydistribution/testdata/TrustedIssuerTestHelper.java @@ -21,14 +21,14 @@ package tng.trustnetwork.keydistribution.testdata; import eu.europa.ec.dgc.gateway.connector.model.TrustedIssuer; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import tng.trustnetwork.keydistribution.entity.TrustedIssuerEntity; import tng.trustnetwork.keydistribution.repository.TrustedIssuerRepository; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; @Service @RequiredArgsConstructor @@ -37,60 +37,20 @@ public class TrustedIssuerTestHelper { @Autowired TrustedIssuerRepository trustedIssuerRepository; + public TrustedIssuerEntity createTrustedIssuer(final String country) { + TrustedIssuerEntity trustedIssuer = new TrustedIssuerEntity(); + trustedIssuer.setUrl("did:trusted:" + country + ":issuer"); + trustedIssuer.setName("tiName"); + trustedIssuer.setCountry(country); + trustedIssuer.setUrlType(TrustedIssuerEntity.UrlType.DID); + trustedIssuer.setSslPublicKey("pubKey"); + trustedIssuer.setThumbprint("thumbprint"); + trustedIssuer.setKeyStorageType("JWKS"); + trustedIssuer.setSignature("sig"); - public TrustedIssuerEntity getIssuer(int number) { - TrustedIssuerEntity issuer = new TrustedIssuerEntity(); - - switch (number) { - case 1: - issuer.setEtag("TestEtag"); - issuer.setCreatedAt(ZonedDateTime.parse("2022-04-04T02:21:00Z")); - issuer.setCountry("DE"); - issuer.setUrl("https://TestUrl.de"); - issuer.setName("example1.de"); - issuer.setUrlType(TrustedIssuerEntity.UrlType.HTTP); - issuer.setThumbprint("thumbprint1"); - issuer.setSslPublicKey("PublicKey1"); - issuer.setKeyStorageType("JWKS"); - issuer.setSignature("Signature1"); - return issuer; - - case 2: - issuer.setEtag("TestEtag"); - issuer.setCreatedAt(ZonedDateTime.parse("2022-04-03T03:33:00Z")); - issuer.setCountry("DE"); - issuer.setUrl("https://TestUrl2.de"); - issuer.setName("example2.de"); - issuer.setUrlType(TrustedIssuerEntity.UrlType.HTTP); - issuer.setThumbprint("thumbprint2"); - issuer.setSslPublicKey("PublicKey2"); - issuer.setKeyStorageType("JWKS"); - issuer.setSignature("Signature2"); - break; - default: - issuer.setEtag("TestEtag"); - issuer.setCreatedAt(ZonedDateTime.parse("2022-04-03T03:33:00Z")); - issuer.setCountry("DE"); - issuer.setUrl("https://TestUrlDefault.de"); - issuer.setName("exampleDefault.de"); - issuer.setUrlType(TrustedIssuerEntity.UrlType.HTTP); - issuer.setThumbprint("thumbprintDefault"); - issuer.setSslPublicKey("PublicKeyDefault"); - issuer.setKeyStorageType("JWKS"); - issuer.setSignature("SignatureDefault"); - break; - } - - return issuer; - - } - - - public void insertTrustedIssuer(TrustedIssuerEntity issuer) { - trustedIssuerRepository.save(issuer); + return trustedIssuer; } - public List getTrustedIssuerList() { List list = new ArrayList<>(); @@ -100,38 +60,39 @@ public List getTrustedIssuerList() { issuer.setType(TrustedIssuer.UrlType.HTTP); issuer.setThumbprint("8e5b84a5c807f8661e470453119830f2ec27971fce4a3420bb744bad66e5bf4c"); issuer.setSslPublicKey("MHcCAQEEICdvyZFxcPenETpnkmMf8m7te73UE6olhUB72OpIuGRpoAoGCCqGSM49AwEHoUQDQgAE7ni62sNPT7" - + "02PoVkwd8+oCJMkDjht8gcFVGSgYNmjUFDXjKuLK/IVl87xQ5G8zNTbIMllwD1JJZB9LElhFb3JA=="); + + "02PoVkwd8+oCJMkDjht8gcFVGSgYNmjUFDXjKuLK/IVl87xQ5G8zNTbIMllwD1JJZB9LElhFb3JA=="); issuer.setKeyStorageType("JWKS"); - issuer.setSignature("MIAGCSqGSIb3DQEHAqCAMIACAQExDTALBglghkgBZQMEAgEwgAYJKoZIhvcNAQcBAACggDCCBX0wggNloAMCAQICF" - + "CfArZMSPZ2iPmF85n5LHsj4D5XgMA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkVVMRcwFQYDVQQIDA5FdXJvcGVhbiBVbmlvbjEU" - + "MBIGA1UECgwLVHJ1c3RBbmNob3IxEDAOBgNVBAsMB1RTVCBFTlYwHhcNMjEwNDIyMDgxNTIyWhcNMzEwNDIwMDgxNTIyWjBOMQswCQY" - + "DVQQGEwJFVTEXMBUGA1UECAwORXVyb3BlYW4gVW5pb24xFDASBgNVBAoMC1RydXN0QW5jaG9yMRAwDgYDVQQLDAdUU1QgRU5WMIICIj" - + "ANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA13sh56S2sRAwnS4TCKci0UHGFC1/GxptcaAow2jznzRaJyz7k6oghedDzibFZREen" - + "g3cO+pw4XpNO8SiWK8w8fipE9TOkbWBNP8cij/yWj+jfyZvVCPY8eXyS5okzS2PNN2lPswdiB5m5BkuXcm8I8d0fgi4bTzT3lwtxlRo" - + "JZo6LVMFjI/sB3LTYsMiL/OnYozpQWf7Cd6wLJI3c9IiQWFH40dGFFwtdQifDWPjOj9iwMASeCarqtOpNhpkn1ZxCDmqPj1mPqreLdq" - + "2RCbzrdvuFRs8KsIrjzJFCcBACPzQeP0jFijPhMa9p8BLSwCrlZOz7OEASPqWDstOqBazTUYBvcwGnP2ZcBuXKUS+lN9V+r37J4ANb/" - + "OpM+iZuPUURxf7OxPa+0INauy6OD8018OleL4svS+8tQadT4G9Nbr/2JqFfqat0FVhaZxQHEyLgQdt70wX1BOctgbCKlGQKBuLMyvyT" - + "wUJ6Qd0IKxmzFbOVfe+AWHb+V+x8oBpAo+vhS6OCaFuB8dIma1pgf6JP6kfmBERvm8n7158q92ZfGebzhSDhbsuB6Gaj0Ew5qJ/kdzQ" - + "rZP5QywHZQ8mEum7JR8rygPEEXDRhdtn3CHIDWEt0we+hGU2GchHOrZwMenQKMdxWnNr5/4M6WobefnOk+t2t4aF1ceWd8nXvK2j1l8" - + "CAwEAAaNTMFEwHQYDVR0OBBYEFK9nb1NMVv4ZzXG7A2alSueXrLBQMB8GA1UdIwQYMBaAFK9nb1NMVv4ZzXG7A2alSueXrLBQMA8GA1" - + "UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAEujCHeHgcqBFeKvt9bAsEDB1QH19+kcd2TdW87GWlA+sYPM3ARwSy5E7JbYj" - + "yk0pZ/XbDi6qC+CE8OgOyWQaj9CELEZCktXZsdGvOs9dKJd5yf97CLDT9EMp2284Ek67VWp5wqqa1+B6xGTg5r8a0OCNrCR04siQNoQ" - + "3pq669hQfhmg5iR0sz4JZrgUL6LIukrd5b/kDvaP37xh8gUrYLX5ApdQFuX41FiP/zcwC4/LG4llsAfYw2lh9ZhXqj3VW8SCayYeJ/O" - + "ExQLM8sHCxJ5NMHoXEvlOjoz+X3/Jib7GHIb0z70EaA8BN6KQ8YPcm+U6sgrjsj501WNAz2GA7ji5Iv/Pet5HGZsYNsDYZSWspe5hbc" - + "Buc271sVbofLkIXxS8l1mVyhJYj4G+X2DWU3RDoQE+XN8wUdYXcrnKlpp8BKQTOxjofp5xnymCq5GXO50+K1C/tqHjCP1aiir2V1Sb1" - + "SumgFoJ10bJXCaqCtUX1/7U7f9lGLirAhgN26s4T13hp+8X1D2hMxfo0w/w90fvtcxfSxutoMwwyU917JtPO/8TA+rE07MbnS0SVsYI" - + "Pg+CVPBHV2jSa1ZVSSsVhJSteG6Hs971ci3kgo4rN/ukosBycylzjBLXBnWfWYAoMb3YoNs1jQJnSyll+N2WxX7vHkKwPrh7OpI9yh+" - + "IEOnYAAAxggMoMIIDJAIBATBmME4xCzAJBgNVBAYTAkVVMRcwFQYDVQQIDA5FdXJvcGVhbiBVbmlvbjEUMBIGA1UECgwLVHJ1c3RBbm" - + "Nob3IxEDAOBgNVBAsMB1RTVCBFTlYCFCfArZMSPZ2iPmF85n5LHsj4D5XgMAsGCWCGSAFlAwQCAaCBljAYBgkqhkiG9w0BCQMxCwYJK" - + "oZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMjAzMjUxMTE3MzRaMCsGCSqGSIb3DQEJNDEeMBwwCwYJYIZIAWUDBAIBoQ0GCSqGSIb3" - + "DQEBCwUAMC8GCSqGSIb3DQEJBDEiBCDRX6mP3IuhUUd3UlbOhbuPYgXXjxeGv+F6IlfEC1aeRTANBgkqhkiG9w0BAQsFAASCAgC23Mz" - + "bNZgXilk+NjuGPfbqQM2veffsKdA0Ln89ODg7Bjtjc0UKTpIQj/o8K9xR/xLkANxM+jLr1v4ya7CUwG9fCde0lqxozSl/j4+P+9Ir82" - + "yTDO7AgT0tNpYI+Pa1NzIlRNgqiTVfEg+AmaKLHkg/SJaDa3KxMslkaeQrUwGqaWBLbaMjQFzk/S92s+uRl00At04peXClb87ml6qlO" - + "BEipjzpcmz/pJPXctBJ38rLSaWyId+Gi+2z5xyClP3N5xUBumVNJZQvkE21cxggUw9CF7m7TPl6O3+6pbkW5ZLrDPOYvGMVH2XYkIJN" - + "AsxEnJSOIEhCAF2PWaKQ5A2ioHOpEvO7Ao2XHxHYZviH66dibxz1tZKe+lxdn65wChfHimvgmu3qyEVjAW3DcHBK8Vs4vB5xdBcx9Q8" - + "1tES/w/Q5ML4rIXKHv6aWlg5cpLuxY6q/T39AxxHnn7CZfIhj+A7kFQGQzy98qRj/qUDgTGF2VoEVX5hDRpkINZhStsW5pTVWtppLVc" - + "CLn7L67FKp8pj8z1S5XY/5akbflY0NPy/a9u71aVHPA+O3RaOlNKG9ZzIKBjApdoDuEEabhwmUmqxbtPhKOSklhv0qOJ1rvuMZLCOha" - + "S1u3C1KyLok+6WI0oSr+hnLwzR69j9Mcfrq98HjvYpmZgSgOKaRe4XsKIBpNQAAAAAAAA=="); + issuer.setSignature(""" + MIAGCSqGSIb3DQEHAqCAMIACAQExDTALBglghkgBZQMEAgEwgAYJKoZIhvcNAQcBAACggDCCBX0wggNloAMCAQICF\ + CfArZMSPZ2iPmF85n5LHsj4D5XgMA0GCSqGSIb3DQEBCwUAME4xCzAJBgNVBAYTAkVVMRcwFQYDVQQIDA5FdXJvcGVhbiBVbmlvbjEU\ + MBIGA1UECgwLVHJ1c3RBbmNob3IxEDAOBgNVBAsMB1RTVCBFTlYwHhcNMjEwNDIyMDgxNTIyWhcNMzEwNDIwMDgxNTIyWjBOMQswCQY\ + DVQQGEwJFVTEXMBUGA1UECAwORXVyb3BlYW4gVW5pb24xFDASBgNVBAoMC1RydXN0QW5jaG9yMRAwDgYDVQQLDAdUU1QgRU5WMIICIj\ + ANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA13sh56S2sRAwnS4TCKci0UHGFC1/GxptcaAow2jznzRaJyz7k6oghedDzibFZREen\ + g3cO+pw4XpNO8SiWK8w8fipE9TOkbWBNP8cij/yWj+jfyZvVCPY8eXyS5okzS2PNN2lPswdiB5m5BkuXcm8I8d0fgi4bTzT3lwtxlRo\ + JZo6LVMFjI/sB3LTYsMiL/OnYozpQWf7Cd6wLJI3c9IiQWFH40dGFFwtdQifDWPjOj9iwMASeCarqtOpNhpkn1ZxCDmqPj1mPqreLdq\ + 2RCbzrdvuFRs8KsIrjzJFCcBACPzQeP0jFijPhMa9p8BLSwCrlZOz7OEASPqWDstOqBazTUYBvcwGnP2ZcBuXKUS+lN9V+r37J4ANb/\ + OpM+iZuPUURxf7OxPa+0INauy6OD8018OleL4svS+8tQadT4G9Nbr/2JqFfqat0FVhaZxQHEyLgQdt70wX1BOctgbCKlGQKBuLMyvyT\ + wUJ6Qd0IKxmzFbOVfe+AWHb+V+x8oBpAo+vhS6OCaFuB8dIma1pgf6JP6kfmBERvm8n7158q92ZfGebzhSDhbsuB6Gaj0Ew5qJ/kdzQ\ + rZP5QywHZQ8mEum7JR8rygPEEXDRhdtn3CHIDWEt0we+hGU2GchHOrZwMenQKMdxWnNr5/4M6WobefnOk+t2t4aF1ceWd8nXvK2j1l8\ + CAwEAAaNTMFEwHQYDVR0OBBYEFK9nb1NMVv4ZzXG7A2alSueXrLBQMB8GA1UdIwQYMBaAFK9nb1NMVv4ZzXG7A2alSueXrLBQMA8GA1\ + UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAEujCHeHgcqBFeKvt9bAsEDB1QH19+kcd2TdW87GWlA+sYPM3ARwSy5E7JbYj\ + yk0pZ/XbDi6qC+CE8OgOyWQaj9CELEZCktXZsdGvOs9dKJd5yf97CLDT9EMp2284Ek67VWp5wqqa1+B6xGTg5r8a0OCNrCR04siQNoQ\ + 3pq669hQfhmg5iR0sz4JZrgUL6LIukrd5b/kDvaP37xh8gUrYLX5ApdQFuX41FiP/zcwC4/LG4llsAfYw2lh9ZhXqj3VW8SCayYeJ/O\ + ExQLM8sHCxJ5NMHoXEvlOjoz+X3/Jib7GHIb0z70EaA8BN6KQ8YPcm+U6sgrjsj501WNAz2GA7ji5Iv/Pet5HGZsYNsDYZSWspe5hbc\ + Buc271sVbofLkIXxS8l1mVyhJYj4G+X2DWU3RDoQE+XN8wUdYXcrnKlpp8BKQTOxjofp5xnymCq5GXO50+K1C/tqHjCP1aiir2V1Sb1\ + SumgFoJ10bJXCaqCtUX1/7U7f9lGLirAhgN26s4T13hp+8X1D2hMxfo0w/w90fvtcxfSxutoMwwyU917JtPO/8TA+rE07MbnS0SVsYI\ + Pg+CVPBHV2jSa1ZVSSsVhJSteG6Hs971ci3kgo4rN/ukosBycylzjBLXBnWfWYAoMb3YoNs1jQJnSyll+N2WxX7vHkKwPrh7OpI9yh+\ + IEOnYAAAxggMoMIIDJAIBATBmME4xCzAJBgNVBAYTAkVVMRcwFQYDVQQIDA5FdXJvcGVhbiBVbmlvbjEUMBIGA1UECgwLVHJ1c3RBbm\ + Nob3IxEDAOBgNVBAsMB1RTVCBFTlYCFCfArZMSPZ2iPmF85n5LHsj4D5XgMAsGCWCGSAFlAwQCAaCBljAYBgkqhkiG9w0BCQMxCwYJK\ + oZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMjAzMjUxMTE3MzRaMCsGCSqGSIb3DQEJNDEeMBwwCwYJYIZIAWUDBAIBoQ0GCSqGSIb3\ + DQEBCwUAMC8GCSqGSIb3DQEJBDEiBCDRX6mP3IuhUUd3UlbOhbuPYgXXjxeGv+F6IlfEC1aeRTANBgkqhkiG9w0BAQsFAASCAgC23Mz\ + bNZgXilk+NjuGPfbqQM2veffsKdA0Ln89ODg7Bjtjc0UKTpIQj/o8K9xR/xLkANxM+jLr1v4ya7CUwG9fCde0lqxozSl/j4+P+9Ir82\ + yTDO7AgT0tNpYI+Pa1NzIlRNgqiTVfEg+AmaKLHkg/SJaDa3KxMslkaeQrUwGqaWBLbaMjQFzk/S92s+uRl00At04peXClb87ml6qlO\ + BEipjzpcmz/pJPXctBJ38rLSaWyId+Gi+2z5xyClP3N5xUBumVNJZQvkE21cxggUw9CF7m7TPl6O3+6pbkW5ZLrDPOYvGMVH2XYkIJN\ + AsxEnJSOIEhCAF2PWaKQ5A2ioHOpEvO7Ao2XHxHYZviH66dibxz1tZKe+lxdn65wChfHimvgmu3qyEVjAW3DcHBK8Vs4vB5xdBcx9Q8\ + 1tES/w/Q5ML4rIXKHv6aWlg5cpLuxY6q/T39AxxHnn7CZfIhj+A7kFQGQzy98qRj/qUDgTGF2VoEVX5hDRpkINZhStsW5pTVWtppLVc\ + CLn7L67FKp8pj8z1S5XY/5akbflY0NPy/a9u71aVHPA+O3RaOlNKG9ZzIKBjApdoDuEEabhwmUmqxbtPhKOSklhv0qOJ1rvuMZLCOha\ + S1u3C1KyLok+6WI0oSr+hnLwzR69j9Mcfrq98HjvYpmZgSgOKaRe4XsKIBpNQAAAAAAAA=="""); issuer.setTimestamp(ZonedDateTime.parse("2022-03-25T12:14:49+01:00")); issuer.setName("example-de"); @@ -141,21 +102,4 @@ public List getTrustedIssuerList() { list.add(issuer); return list; } - - public TrustedIssuerEntity createTrustedIssuer(final String country) { - TrustedIssuerEntity trustedIssuer = new TrustedIssuerEntity(); - trustedIssuer.setUrl("did:trusted:" + country + ":issuer"); - trustedIssuer.setName("tiName"); - trustedIssuer.setCountry(country); - trustedIssuer.setUrlType(TrustedIssuerEntity.UrlType.DID); - trustedIssuer.setSslPublicKey("pubKey"); - trustedIssuer.setThumbprint("thumbprint"); - trustedIssuer.setKeyStorageType("JWKS"); - trustedIssuer.setEtag("etag"); - trustedIssuer.setSignature("sig"); - - return trustedIssuer; - } - - } diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 7fa7d4e..ce649d3 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,6 +1,3 @@ -server: - port: 8080 - spring: application: name: tng-key-distribution @@ -49,9 +46,10 @@ dgc: url: "" pat: "" ld-proof-verification-method: did:web:dummy.net - ld-proof-nonce: n0nc3 ld-proof-domain: d0m4in did-id: did:web:abc + trust-list-path: trustlist + trust-list-ref-path: trustlist-ref did-controller: did:web:def trust-list-id-prefix: did:web:abc trust-list-controller-prefix: did:web:abc @@ -59,13 +57,11 @@ dgc: "[https://www.w3.org/ns/did/v1]": did_v1.json "[https://w3id.org/security/suites/jws-2020/v1]": jws-2020_v1.json virtualCountries: - EU: xeu -springdoc: - api-docs: - path: /api/docs - swagger-ui: - path: /swagger - + EU: XEU + group-deny-list: + - UPLOAD + group-name-mapping: + CSCA: CSA universal: resolver: "https://dev.uniresolver.io/1.0/identifiers"