From b9dcaca405d08bafe6806692b9bb693236b9f413 Mon Sep 17 00:00:00 2001 From: Felix Dittrich <31076102+f11h@users.noreply.github.com> Date: Thu, 3 Aug 2023 14:08:59 +0200 Subject: [PATCH 01/41] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c02d4f2b..55ec308f 100644 --- a/pom.xml +++ b/pom.xml @@ -247,7 +247,7 @@ com.google.protobuf protobuf-javalite - 3.21.12 + 3.21.12 From 42ddf1c49b024bce2c674b0ab4a34f5182c93212 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 3 Aug 2023 12:22:51 +0000 Subject: [PATCH 02/41] Update License Header and Third Party Notices --- THIRD-PARTY.md | 222 ++++++++++++++++++++++++------------------------- 1 file changed, 109 insertions(+), 113 deletions(-) diff --git a/THIRD-PARTY.md b/THIRD-PARTY.md index ae39d6cc..9c3f0910 100644 --- a/THIRD-PARTY.md +++ b/THIRD-PARTY.md @@ -11,8 +11,8 @@ ThirdParty Licenses | Dependency | License | | --- | --- | -| ch.qos.logback:logback-classic:1.4.6 | Eclipse Public License - v 1.0 GNU Lesser General Public License | -| ch.qos.logback:logback-core:1.4.6 | Eclipse Public License - v 1.0 GNU Lesser General Public License | +| ch.qos.logback:logback-classic:1.4.8 | Eclipse Public License - v 1.0 GNU Lesser General Public License | +| ch.qos.logback:logback-core:1.4.8 | Eclipse Public License - v 1.0 GNU Lesser General Public License | | com.apicatalog:titanium-json-ld:1.1.0 | Apache License, Version 2.0 | | com.azure:azure-core:1.34.0 | The MIT License (MIT) | | com.azure:azure-core-http-netty:1.12.7 | The MIT License (MIT) | @@ -24,14 +24,14 @@ ThirdParty Licenses | com.damnhandy:handy-uri-templates:2.1.8 | The Apache Software License, Version 2.0 | | com.danubetech:key-formats-java:1.2.0 | Unknown license | | com.fasterxml:classmate:1.5.1 | Apache License, Version 2.0 | -| com.fasterxml.jackson.core:jackson-annotations:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.core:jackson-core:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.core:jackson-databind:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2 | The Apache Software License, Version 2.0 | -| com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.2 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.core:jackson-annotations:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.core:jackson-core:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.core:jackson-databind:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.3 | The Apache Software License, Version 2.0 | +| com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.3 | The Apache Software License, Version 2.0 | | com.fasterxml.woodstox:woodstox-core:6.4.0 | The Apache License, Version 2.0 | | com.github.everit-org.json-schema:org.everit.json.schema:1.14.2 | Apache License, Version 2.0 | | com.github.jnr:jffi:1.2.9 | The Apache Software License, Version 2.0 | @@ -48,11 +48,11 @@ ThirdParty Licenses | com.google.j2objc:j2objc-annotations:1.3 | The Apache Software License, Version 2.0 | | com.google.protobuf:protobuf-javalite:3.21.12 | BSD-3-Clause | | com.google.re2j:re2j:1.6 | Go License | -| com.h2database:h2:2.1.214 | EPL 1.0 MPL 2.0 | +| com.h2database:h2:2.2.220 | EPL 1.0 MPL 2.0 | | com.jayway.jsonpath:json-path:2.7.0 | The Apache Software License, Version 2.0 | | com.microsoft.azure:msal4j:1.13.3 | MIT License | | com.microsoft.azure:msal4j-persistence-extension:1.1.0 | MIT License | -| com.mysql:mysql-connector-j:8.0.32 | The GNU General Public License, v2 with Universal FOSS Exception, v1.0 | +| com.mysql:mysql-connector-j:8.0.33 | The GNU General Public License, v2 with Universal FOSS Exception, v1.0 | | com.nimbusds:content-type:2.2 | The Apache Software License, Version 2.0 | | com.nimbusds:lang-tag:1.6 | The Apache Software License, Version 2.0 | | com.nimbusds:nimbus-jose-jwt:9.9 | The Apache Software License, Version 2.0 | @@ -60,7 +60,7 @@ ThirdParty Licenses | com.opencsv:opencsv:5.7.1 | Apache 2 | | com.squareup.okhttp3:okhttp:4.10.0 | The Apache Software License, Version 2.0 | | com.squareup.okio:okio-jvm:3.0.0 | The Apache Software License, Version 2.0 | -| com.sun.istack:istack-commons-runtime:4.1.1 | Eclipse Distribution License - v 1.0 | +| com.sun.istack:istack-commons-runtime:4.1.2 | Eclipse Distribution License - v 1.0 | | com.upokecenter:cbor:4.5.2 | CC0-1.0 | | com.vaadin.external.google:android-json:0.0.20131108.vaadin1 | Apache License 2.0 | | com.zaxxer:HikariCP:5.0.1 | The Apache Software License, Version 2.0 | @@ -74,39 +74,39 @@ ThirdParty Licenses | decentralized-identity:jsonld-common-java:1.0.0 | Unknown license | | info.weboftrust:ld-signatures-java:1.1.0 | Unknown license | | io.github.erdtman:java-json-canonicalization:1.1 | Apache License, Version 2.0 | -| io.github.openfeign:feign-core:12.1 | The Apache Software License, Version 2.0 | -| io.github.openfeign:feign-httpclient:12.1 | The Apache Software License, Version 2.0 | -| io.github.openfeign:feign-slf4j:12.1 | The Apache Software License, Version 2.0 | +| io.github.openfeign:feign-core:12.4 | The Apache Software License, Version 2.0 | +| io.github.openfeign:feign-httpclient:12.4 | The Apache Software License, Version 2.0 | +| io.github.openfeign:feign-slf4j:12.4 | The Apache Software License, Version 2.0 | | io.github.openfeign.form:feign-form:3.8.0 | The Apache Software License, Version 2.0 | | io.github.openfeign.form:feign-form-spring:3.8.0 | The Apache Software License, Version 2.0 | -| io.micrometer:micrometer-commons:1.10.5 | The Apache Software License, Version 2.0 | -| io.micrometer:micrometer-core:1.10.5 | The Apache Software License, Version 2.0 | -| io.micrometer:micrometer-observation:1.10.5 | The Apache Software License, Version 2.0 | -| io.micrometer:micrometer-registry-prometheus:1.10.5 | The Apache Software License, Version 2.0 | -| io.netty:netty-buffer:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-codec:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-codec-dns:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-codec-http:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-codec-http2:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-codec-socks:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-common:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-handler:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-handler-proxy:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-resolver:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-resolver-dns:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-resolver-dns-classes-macos:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-resolver-dns-native-macos:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-tcnative-boringssl-static:2.0.59.Final | The Apache Software License, Version 2.0 | -| io.netty:netty-tcnative-classes:2.0.59.Final | The Apache Software License, Version 2.0 | -| io.netty:netty-transport:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-transport-classes-epoll:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-transport-classes-kqueue:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-transport-native-epoll:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-transport-native-kqueue:4.1.90.Final | Apache License, Version 2.0 | -| io.netty:netty-transport-native-unix-common:4.1.90.Final | Apache License, Version 2.0 | -| io.projectreactor:reactor-core:3.5.4 | Apache License, Version 2.0 | -| io.projectreactor.netty:reactor-netty-core:1.1.5 | The Apache Software License, Version 2.0 | -| io.projectreactor.netty:reactor-netty-http:1.1.5 | The Apache Software License, Version 2.0 | +| io.micrometer:micrometer-commons:1.10.9 | The Apache Software License, Version 2.0 | +| io.micrometer:micrometer-core:1.10.9 | The Apache Software License, Version 2.0 | +| io.micrometer:micrometer-observation:1.10.9 | The Apache Software License, Version 2.0 | +| io.micrometer:micrometer-registry-prometheus:1.10.9 | The Apache Software License, Version 2.0 | +| io.netty:netty-buffer:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-codec:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-codec-dns:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-codec-http:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-codec-http2:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-codec-socks:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-common:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-handler:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-handler-proxy:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-resolver:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-resolver-dns:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-resolver-dns-classes-macos:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-resolver-dns-native-macos:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-tcnative-boringssl-static:2.0.61.Final | The Apache Software License, Version 2.0 | +| io.netty:netty-tcnative-classes:2.0.61.Final | The Apache Software License, Version 2.0 | +| io.netty:netty-transport:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-transport-classes-epoll:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-transport-classes-kqueue:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-transport-native-epoll:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-transport-native-kqueue:4.1.94.Final | Apache License, Version 2.0 | +| io.netty:netty-transport-native-unix-common:4.1.94.Final | Apache License, Version 2.0 | +| io.projectreactor:reactor-core:3.5.8 | Apache License, Version 2.0 | +| io.projectreactor.netty:reactor-netty-core:1.1.9 | The Apache Software License, Version 2.0 | +| io.projectreactor.netty:reactor-netty-http:1.1.9 | The Apache Software License, Version 2.0 | | io.prometheus:simpleclient:0.16.0 | The Apache Software License, Version 2.0 | | io.prometheus:simpleclient_common:0.16.0 | The Apache Software License, Version 2.0 | | io.prometheus:simpleclient_tracer_common:0.16.0 | The Apache Software License, Version 2.0 | @@ -116,7 +116,7 @@ ThirdParty Licenses | io.swagger.core.v3:swagger-annotations-jakarta:2.2.9 | Apache License 2.0 | | io.swagger.core.v3:swagger-core-jakarta:2.2.9 | Apache License 2.0 | | io.swagger.core.v3:swagger-models-jakarta:2.2.9 | Apache License 2.0 | -| jakarta.activation:jakarta.activation-api:2.1.1 | EDL 1.0 | +| jakarta.activation:jakarta.activation-api:2.1.2 | EDL 1.0 | | jakarta.annotation:jakarta.annotation-api:2.1.1 | EPL 2.0 GPL2 w/ CPE | | jakarta.inject:jakarta.inject-api:2.0.0 | The Apache Software License, Version 2.0 | | jakarta.persistence:jakarta.persistence-api:3.1.0 | Eclipse Distribution License v. 1.0 Eclipse Public License v. 2.0 | @@ -134,8 +134,8 @@ ThirdParty Licenses | net.javacrumbs.shedlock:shedlock-provider-jdbc-template:5.2.0 | The Apache Software License, Version 2.0 | | net.javacrumbs.shedlock:shedlock-spring:5.2.0 | The Apache Software License, Version 2.0 | | net.jcip:jcip-annotations:1.0 | Unknown license | -| net.minidev:accessors-smart:2.4.9 | The Apache Software License, Version 2.0 | -| net.minidev:json-smart:2.4.10 | The Apache Software License, Version 2.0 | +| net.minidev:accessors-smart:2.4.11 | The Apache Software License, Version 2.0 | +| net.minidev:json-smart:2.4.11 | The Apache Software License, Version 2.0 | | org.abstractj.kalium:kalium:0.8.0 | The Apache Software License, Version 2.0 | | org.antlr:antlr4-runtime:4.10.1 | The BSD License | | org.apache.commons:commons-collections4:4.4 | Apache License, Version 2.0 | @@ -145,47 +145,43 @@ ThirdParty Licenses | org.apache.httpcomponents:httpcore:4.4.16 | Apache License, Version 2.0 | | org.apache.logging.log4j:log4j-api:2.19.0 | Apache License, Version 2.0 | | org.apache.logging.log4j:log4j-to-slf4j:2.19.0 | Apache License, Version 2.0 | -| org.apache.tomcat.embed:tomcat-embed-core:10.1.7 | Apache License, Version 2.0 | -| org.apache.tomcat.embed:tomcat-embed-el:10.1.7 | Apache License, Version 2.0 | -| org.apache.tomcat.embed:tomcat-embed-websocket:10.1.7 | Apache License, Version 2.0 | +| org.apache.tomcat.embed:tomcat-embed-core:10.1.11 | Apache License, Version 2.0 | +| org.apache.tomcat.embed:tomcat-embed-el:10.1.11 | Apache License, Version 2.0 | +| org.apache.tomcat.embed:tomcat-embed-websocket:10.1.11 | Apache License, Version 2.0 | | org.apiguardian:apiguardian-api:1.1.2 | The Apache License, Version 2.0 | | org.aspectj:aspectjweaver:1.9.19 | Eclipse Public License - v 2.0 | | org.assertj:assertj-core:3.23.1 | Apache License, Version 2.0 | | org.bitcoinj:bitcoinj-core:0.16.2 | The Apache Software License, Version 2.0 | -| org.bouncycastle:bcpkix-jdk15on:1.69 | Bouncy Castle Licence | -| org.bouncycastle:bcpkix-jdk18on:1.73 | Bouncy Castle Licence | -| org.bouncycastle:bcprov-jdk15on:1.69 | Bouncy Castle Licence | -| org.bouncycastle:bcprov-jdk15to18:1.69 | Bouncy Castle Licence | -| org.bouncycastle:bcprov-jdk18on:1.73 | Bouncy Castle Licence | -| org.bouncycastle:bcutil-jdk15on:1.69 | Bouncy Castle Licence | -| org.bouncycastle:bcutil-jdk18on:1.73 | Bouncy Castle Licence | +| org.bouncycastle:bcpkix-jdk18on:1.76 | Bouncy Castle Licence | +| org.bouncycastle:bcprov-jdk18on:1.76 | Bouncy Castle Licence | +| org.bouncycastle:bcutil-jdk18on:1.76 | Bouncy Castle Licence | | org.checkerframework:checker-compat-qual:2.5.5 | GNU General Public License, version 2 (GPL2), with the classpath exception The MIT License | | org.checkerframework:checker-qual:3.5.0 | The MIT License | | org.codehaus.woodstox:stax2-api:4.2.1 | The BSD License | -| org.eclipse.angus:angus-activation:2.0.0 | EDL 1.0 | +| org.eclipse.angus:angus-activation:2.0.1 | EDL 1.0 | | org.glassfish:jakarta.json:2.0.0 | Eclipse Public License 2.0 GNU General Public License, version 2 with the GNU Classpath Exception | -| org.glassfish.jaxb:jaxb-core:4.0.2 | Eclipse Distribution License - v 1.0 | -| org.glassfish.jaxb:jaxb-runtime:4.0.2 | Eclipse Distribution License - v 1.0 | -| org.glassfish.jaxb:txw2:4.0.2 | Eclipse Distribution License - v 1.0 | +| org.glassfish.jaxb:jaxb-core:4.0.3 | Eclipse Distribution License - v 1.0 | +| org.glassfish.jaxb:jaxb-runtime:4.0.3 | Eclipse Distribution License - v 1.0 | +| org.glassfish.jaxb:txw2:4.0.3 | Eclipse Distribution License - v 1.0 | | org.hamcrest:hamcrest:2.2 | BSD License 3 | | org.hdrhistogram:HdrHistogram:2.1.12 | BSD-2-Clause Public Domain, per Creative Commons CC0 | | org.hibernate.common:hibernate-commons-annotations:6.0.6.Final | GNU Library General Public License v2.1 or later | | org.hibernate.orm:hibernate-core:6.1.7.Final | GNU Library General Public License v2.1 or later | -| org.hibernate.validator:hibernate-validator:8.0.0.Final | Apache License 2.0 | +| org.hibernate.validator:hibernate-validator:8.0.1.Final | Apache License 2.0 | | org.jboss:jandex:2.4.2.Final | Apache License, Version 2.0 | -| org.jboss.logging:jboss-logging:3.5.0.Final | Apache License, version 2.0 | +| org.jboss.logging:jboss-logging:3.5.3.Final | Apache License 2.0 | | org.jetbrains:annotations:13.0 | The Apache Software License, Version 2.0 | | org.jetbrains.kotlin:kotlin-stdlib:1.7.22 | The Apache License, Version 2.0 | | org.jetbrains.kotlin:kotlin-stdlib-common:1.7.22 | The Apache License, Version 2.0 | | org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.22 | The Apache License, Version 2.0 | | org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.22 | The Apache License, Version 2.0 | | org.json:json:20230227 | Public Domain | -| org.junit.jupiter:junit-jupiter:5.9.2 | Eclipse Public License v2.0 | -| org.junit.jupiter:junit-jupiter-api:5.9.2 | Eclipse Public License v2.0 | -| org.junit.jupiter:junit-jupiter-engine:5.9.2 | Eclipse Public License v2.0 | -| org.junit.jupiter:junit-jupiter-params:5.9.2 | Eclipse Public License v2.0 | -| org.junit.platform:junit-platform-commons:1.9.2 | Eclipse Public License v2.0 | -| org.junit.platform:junit-platform-engine:1.9.2 | Eclipse Public License v2.0 | +| org.junit.jupiter:junit-jupiter:5.9.3 | Eclipse Public License v2.0 | +| org.junit.jupiter:junit-jupiter-api:5.9.3 | Eclipse Public License v2.0 | +| org.junit.jupiter:junit-jupiter-engine:5.9.3 | Eclipse Public License v2.0 | +| org.junit.jupiter:junit-jupiter-params:5.9.3 | Eclipse Public License v2.0 | +| org.junit.platform:junit-platform-commons:1.9.3 | Eclipse Public License v2.0 | +| org.junit.platform:junit-platform-engine:1.9.3 | Eclipse Public License v2.0 | | org.latencyutils:LatencyUtils:2.0.3 | Public Domain, per Creative Commons CC0 | | org.liquibase:liquibase-core:4.17.2 | Apache License, Version 2.0 | | org.mapstruct:mapstruct:1.5.5.Final | The Apache Software License, Version 2.0 | @@ -199,7 +195,7 @@ ThirdParty Licenses | org.ow2.asm:asm-tree:5.0.3 | BSD | | org.ow2.asm:asm-util:5.0.3 | BSD | | org.postgresql:postgresql:42.5.4 | BSD-2-Clause | -| org.projectlombok:lombok:1.18.26 | The MIT License | +| org.projectlombok:lombok:1.18.28 | The MIT License | | org.reactivestreams:reactive-streams:1.0.4 | MIT-0 | | org.semver4j:semver4j:4.3.0 | The MIT License | | org.skyscreamer:jsonassert:1.5.1 | The Apache Software License, Version 2.0 | @@ -208,49 +204,49 @@ ThirdParty Licenses | org.springdoc:springdoc-openapi-starter-common:2.1.0 | The Apache License, Version 2.0 | | org.springdoc:springdoc-openapi-starter-webmvc-api:2.1.0 | The Apache License, Version 2.0 | | org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0 | The Apache License, Version 2.0 | -| org.springframework:spring-aop:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-aspects:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-beans:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-context:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-core:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-expression:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-jcl:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-jdbc:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-orm:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-test:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-tx:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-web:6.0.7 | Apache License, Version 2.0 | -| org.springframework:spring-webmvc:6.0.7 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-actuator:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-actuator-autoconfigure:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-autoconfigure:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-actuator:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-aop:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-data-jpa:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-jdbc:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-json:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-logging:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-test:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-tomcat:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-validation:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-starter-web:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-test:3.0.5 | Apache License, Version 2.0 | -| org.springframework.boot:spring-boot-test-autoconfigure:3.0.5 | Apache License, Version 2.0 | -| org.springframework.cloud:spring-cloud-commons:4.0.2 | Apache License, Version 2.0 | -| org.springframework.cloud:spring-cloud-context:4.0.2 | Apache License, Version 2.0 | -| org.springframework.cloud:spring-cloud-openfeign-core:4.0.2 | Apache License, Version 2.0 | -| org.springframework.cloud:spring-cloud-starter:4.0.2 | Apache License, Version 2.0 | -| org.springframework.cloud:spring-cloud-starter-openfeign:4.0.2 | Apache License, Version 2.0 | -| org.springframework.data:spring-data-commons:3.0.4 | Apache License, Version 2.0 | -| org.springframework.data:spring-data-jpa:3.0.4 | Apache License, Version 2.0 | -| org.springframework.security:spring-security-config:6.0.2 | Apache License, Version 2.0 | -| org.springframework.security:spring-security-core:6.0.2 | Apache License, Version 2.0 | -| org.springframework.security:spring-security-crypto:6.0.2 | Apache License, Version 2.0 | -| org.springframework.security:spring-security-rsa:1.0.11.RELEASE | Apache 2.0 | -| org.springframework.security:spring-security-test:6.0.2 | Apache License, Version 2.0 | -| org.springframework.security:spring-security-web:6.0.2 | Apache License, Version 2.0 | +| org.springframework:spring-aop:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-aspects:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-beans:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-context:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-core:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-expression:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-jcl:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-jdbc:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-orm:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-test:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-tx:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-web:6.0.11 | Apache License, Version 2.0 | +| org.springframework:spring-webmvc:6.0.11 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-actuator:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-actuator-autoconfigure:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-autoconfigure:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-actuator:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-aop:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-data-jpa:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-jdbc:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-json:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-logging:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-test:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-tomcat:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-validation:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-starter-web:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-test:3.0.9 | Apache License, Version 2.0 | +| org.springframework.boot:spring-boot-test-autoconfigure:3.0.9 | Apache License, Version 2.0 | +| org.springframework.cloud:spring-cloud-commons:4.0.4 | Apache License, Version 2.0 | +| org.springframework.cloud:spring-cloud-context:4.0.4 | Apache License, Version 2.0 | +| org.springframework.cloud:spring-cloud-openfeign-core:4.0.4 | Apache License, Version 2.0 | +| org.springframework.cloud:spring-cloud-starter:4.0.4 | Apache License, Version 2.0 | +| org.springframework.cloud:spring-cloud-starter-openfeign:4.0.4 | Apache License, Version 2.0 | +| org.springframework.data:spring-data-commons:3.0.8 | Apache License, Version 2.0 | +| org.springframework.data:spring-data-jpa:3.0.8 | Apache License, Version 2.0 | +| org.springframework.security:spring-security-config:6.0.5 | Apache License, Version 2.0 | +| org.springframework.security:spring-security-core:6.0.5 | Apache License, Version 2.0 | +| org.springframework.security:spring-security-crypto:6.0.5 | Apache License, Version 2.0 | +| org.springframework.security:spring-security-rsa:1.0.12.RELEASE | Apache 2.0 | +| org.springframework.security:spring-security-test:6.0.5 | Apache License, Version 2.0 | +| org.springframework.security:spring-security-web:6.0.5 | Apache License, Version 2.0 | | org.webjars:swagger-ui:4.18.2 | Apache 2.0 | | org.xmlunit:xmlunit-core:2.9.1 | The Apache Software License, Version 2.0 | | org.yaml:snakeyaml:1.33 | Apache License, Version 2.0 | From 1f8553fea6e34532b591ddbaf73abda4916dd101 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Fri, 4 Aug 2023 16:47:57 +0200 Subject: [PATCH 03/41] Fix: Implicit KID isn't used at DID-TrustList generation --- .../model/TrustedCertificateTrustList.java | 3 ++ .../dgc/gateway/service/TrustListService.java | 6 ++- .../service/did/DidTrustListService.java | 52 ++++++++++--------- .../service/DidTrustListServiceTest.java | 8 ++- 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/model/TrustedCertificateTrustList.java b/src/main/java/eu/europa/ec/dgc/gateway/model/TrustedCertificateTrustList.java index 15d4cac2..06adb56b 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/model/TrustedCertificateTrustList.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/model/TrustedCertificateTrustList.java @@ -20,6 +20,7 @@ package eu.europa.ec.dgc.gateway.model; +import java.security.cert.X509Certificate; import java.time.ZonedDateTime; import lombok.AllArgsConstructor; import lombok.Data; @@ -52,4 +53,6 @@ public class TrustedCertificateTrustList { private Integer version; + private X509Certificate parsedCertificate; + } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java index 7b823da2..294a2dcc 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java @@ -156,7 +156,8 @@ private TrustedCertificateTrustList convertTrustedCertificate(TrustedPartyEntity ? trustedPartyEntity.getSourceGateway().getGatewayId() : null, trustedPartyEntity.getUuid(), trustedPartyEntity.getDomain(), - trustedPartyEntity.getVersion() + trustedPartyEntity.getVersion(), + trustedPartyService.getX509CertificateFromEntity(trustedPartyEntity) ); } @@ -174,7 +175,8 @@ private TrustedCertificateTrustList convertTrustedCertificate(SignerInformationE ? signerInformationEntity.getSourceGateway().getGatewayId() : null, signerInformationEntity.getUuid(), signerInformationEntity.getDomain(), - signerInformationEntity.getVersion() + signerInformationEntity.getVersion(), + signerInformationService.getX509CertificateFromEntity(signerInformationEntity) ); } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 8dc7b3e2..46f2bfae 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -27,11 +27,11 @@ import eu.europa.ec.dgc.gateway.entity.SignerInformationEntity; import eu.europa.ec.dgc.gateway.entity.TrustedIssuerEntity; import eu.europa.ec.dgc.gateway.entity.TrustedPartyEntity; +import eu.europa.ec.dgc.gateway.model.TrustedCertificateTrustList; import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListDto; import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListEntryDto; -import eu.europa.ec.dgc.gateway.service.SignerInformationService; +import eu.europa.ec.dgc.gateway.service.TrustListService; import eu.europa.ec.dgc.gateway.service.TrustedIssuerService; -import eu.europa.ec.dgc.gateway.service.TrustedPartyService; import foundation.identity.jsonld.ConfigurableDocumentLoader; import foundation.identity.jsonld.JsonLDObject; import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; @@ -39,7 +39,6 @@ import java.io.InputStream; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.security.cert.X509Certificate; import java.security.interfaces.ECPublicKey; import java.util.ArrayList; import java.util.Base64; @@ -66,12 +65,10 @@ public class DidTrustListService { "https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/jws-2020/v1"); - private final TrustedPartyService trustedPartyService; - - private final SignerInformationService signerInformationService; - private final TrustedIssuerService trustedIssuerService; + private final TrustListService trustListService; + private final DgcConfigProperties configProperties; private final ByteSigner byteSigner; @@ -112,17 +109,18 @@ private String generateTrustList() throws Exception { // Add DSC - List certs = signerInformationService.getSignerInformation( - null, null, null, configProperties.getDid().getIncludeFederated()); - - for (SignerInformationEntity cert : certs) { + List certs = trustListService.getTrustedCertificateTrustList( + SignerInformationEntity.CertificateType.stringValues(), + null, + null, + configProperties.getDid().getIncludeFederated() + ); + + for (TrustedCertificateTrustList cert : certs) { DidTrustListEntryDto.EcPublicKeyJwk.EcPublicKeyJwkBuilder jwkBuilder = DidTrustListEntryDto.EcPublicKeyJwk.builder(); - X509Certificate x509 = signerInformationService.getX509CertificateFromEntity(cert); - - - if (x509.getPublicKey() instanceof ECPublicKey publicKey) { + if (cert.getParsedCertificate().getPublicKey() instanceof ECPublicKey publicKey) { jwkBuilder.valueX(Base64.getEncoder().encodeToString(publicKey.getW().getAffineX().toByteArray())); jwkBuilder.valueY(Base64.getEncoder().encodeToString(publicKey.getW().getAffineY().toByteArray())); @@ -137,18 +135,22 @@ private String generateTrustList() throws Exception { } jwkBuilder.keyType("EC"); - jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getRawData()))); + jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); DidTrustListEntryDto.EcPublicKeyJwk jwk = jwkBuilder.build(); - Optional csca = - trustedPartyService.getCertificate( - cert.getCountry(), TrustedPartyEntity.CertificateType.CSCA).stream() - .map(trustedPartyService::getX509CertificateFromEntity) - .filter(tp -> tp.getSubjectX500Principal().equals(x509.getIssuerX500Principal())) - .findFirst(); + // Search for Issuer of DSC + Optional csca = trustListService.getTrustedCertificateTrustList( + List.of(TrustedPartyEntity.CertificateType.CSCA.name()), + List.of(cert.getCountry()), + List.of(cert.getDomain()), + configProperties.getDid().getIncludeFederated()).stream() + .filter(tp -> tp.getParsedCertificate().getSubjectX500Principal() + .equals(cert.getParsedCertificate().getIssuerX500Principal())) + .findFirst(); if (csca.isPresent()) { - jwk.getEncodedX509Certificates().add(Base64.getEncoder().encodeToString(csca.get().getEncoded())); + jwk.getEncodedX509Certificates() + .add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded())); } DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto(); @@ -161,8 +163,8 @@ private String generateTrustList() throws Exception { } else { log.error("Public Key is not EC Public Key for cert {} of country {}", - cert.getThumbprint(), - cert.getCountry()); + cert.getThumbprint(), + cert.getCountry()); } } diff --git a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java index b2ef582c..382d7344 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java @@ -100,6 +100,8 @@ public class DidTrustListServiceTest { X509Certificate certUploadDe, certUploadEu, certCscaDe, certCscaEu, certAuthDe, certAuthEu, certDscDe, certDscEu, federatedCertDscEx; + String certDscDeKid; + FederationGatewayEntity federationGateway; @AfterEach @@ -130,6 +132,8 @@ void testData() throws Exception { certDscDe = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "DE", "Test", certCscaDe, trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.AUTHENTICATION, "DE")); + + certDscDeKid = certificateUtils.getCertKid(certDscDe); certDscEu = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EU", "Test", certCscaEu, trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU")); @@ -141,7 +145,7 @@ void testData() throws Exception { certificateUtils.getCertThumbprint(certDscDe), Base64.getEncoder().encodeToString(certDscDe.getEncoded()), "sig1", - "kid1", + null, // Don't provide a KID to test that calculated KID will be used SignerInformationEntity.CertificateType.DSC, null )); @@ -191,7 +195,7 @@ void testTrustList() throws IOException, CertificateEncodingException { Assertions.assertEquals("b", parsed.getController()); Assertions.assertEquals(6, parsed.getVerificationMethod().size()); - assertVerificationMethod(parsed.getVerificationMethod().get(0), "kid1", certDscDe, certCscaDe); + assertVerificationMethod(parsed.getVerificationMethod().get(0), certDscDeKid, certDscDe, certCscaDe); assertVerificationMethod(parsed.getVerificationMethod().get(1), "kid2", certDscEu, certCscaEu); assertVerificationMethod(parsed.getVerificationMethod().get(2), "kid3", federatedCertDscEx, null); From 5db74724c39e45ff7d62ff837be79e94ec6e6a67 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Mon, 7 Aug 2023 13:31:26 +0200 Subject: [PATCH 04/41] Remove wrong spaces in log format --- src/main/resources/logback-spring.xml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 268f5e8c..45a45700 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -11,9 +11,7 @@ - timestamp="%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC}", level="%level", hostname="${HOSTNAME}", - pid="${PID:-}", thread="%thread", class="%logger{40}", message="%replace(%replace(%m){'[\r\n]+', ', - '}){'"', '\''}", trace="%X{traceId}", span="%X{spanId}", %X%n + timestamp="%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC}", level="%level", hostname="${HOSTNAME}", pid="${PID:-}", thread="%thread", class="%logger{40}", message="%replace(%replace(%m){'[\r\n]+', ','}){'"', '\''}", trace="%X{traceId}", span="%X{spanId}", %X%n utf8 @@ -31,10 +29,7 @@ - timestamp="%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC}", level="%level", hostname="${HOSTNAME}", - pid="${PID:-}", thread="%thread", class="%logger{40}", message="%replace(%replace(%m){'[\r\n]+', - ','}){'"', '\''}", exception="%replace(%ex){'[\r\n]+', ', '}", trace="%X{traceId}", span="%X{spanId}", - %X%n%nopex + timestamp="%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC}", level="%level", hostname="${HOSTNAME}", pid="${PID:-}", thread="%thread", class="%logger{40}", message="%replace(%replace(%m){'[\r\n]+',','}){'"', '\''}", exception="%replace(%ex){'[\r\n]+', ', '}", trace="%X{traceId}", span="%X{spanId}", %X%n%nopex utf8 From ba43866a717b89cfcf12304c9a4d1a178d72c476 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Mon, 7 Aug 2023 16:00:52 +0200 Subject: [PATCH 05/41] Fix DID Trustlist UnitTest --- .../service/DidTrustListServiceTest.java | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java index 382d7344..167716d5 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java @@ -48,6 +48,7 @@ import java.util.ArrayList; import java.util.Base64; import java.util.LinkedHashMap; +import java.util.List; import lombok.Data; import lombok.Getter; import lombok.Setter; @@ -109,6 +110,7 @@ public void cleanUp() { trustedPartyRepository.deleteAll(); signerInformationRepository.deleteAll(); federationGatewayRepository.deleteAll(); + trustedIssuerRepository.deleteAll(); } @BeforeEach @@ -189,29 +191,41 @@ void testTrustList() throws IOException, CertificateEncodingException { didTrustListService.job(); - SignedDidTrustListDto parsed = objectMapper.readValue(uploadArgumentCaptor.getValue(), SignedDidTrustListDto.class); + SignedDidTrustListDto parsed = + objectMapper.readValue(uploadArgumentCaptor.getValue(), SignedDidTrustListDto.class); Assertions.assertEquals("a", parsed.getId()); Assertions.assertEquals("b", parsed.getController()); Assertions.assertEquals(6, parsed.getVerificationMethod().size()); - assertVerificationMethod(parsed.getVerificationMethod().get(0), certDscDeKid, certDscDe, certCscaDe); - assertVerificationMethod(parsed.getVerificationMethod().get(1), "kid2", certDscEu, certCscaEu); - assertVerificationMethod(parsed.getVerificationMethod().get(2), "kid3", federatedCertDscEx, null); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + certDscDeKid), + certDscDeKid, certDscDe, certCscaDe); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "ckid2"), + "kid2", certDscEu, certCscaEu); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "ckid3"), + "kid3", federatedCertDscEx, null); 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.assertTrue( + Instant.now().toEpochMilli() - parsed.getProof().getCreated().toInstant().toEpochMilli() < 10000); Assertions.assertEquals("f", parsed.getProof().getDomain()); Assertions.assertEquals("g", parsed.getProof().getNonce()); Assertions.assertEquals("assertionMethod", parsed.getProof().getProofPurpose()); Assertions.assertEquals("e", parsed.getProof().getVerificationMethod()); Assertions.assertNotNull(parsed.getProof().getJws()); Assertions.assertNotEquals("", parsed.getProof().getJws()); + } + private Object getVerificationMethodByKid(List verificationMethods, String kid) { + return verificationMethods.stream() + .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) @@ -223,8 +237,10 @@ private void assertVerificationMethod(Object in, String kid, X509Certificate dsc LinkedHashMap publicKeyJwk = (LinkedHashMap) jsonNode.get("publicKeyJwk"); - Assertions.assertEquals(((ECPublicKey) dsc.getPublicKey()).getW().getAffineX(), 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()))); + Assertions.assertEquals(((ECPublicKey) dsc.getPublicKey()).getW().getAffineX(), + 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()))); Assertions.assertEquals("EC", publicKeyJwk.get("kty").toString()); Assertions.assertEquals("P-256", publicKeyJwk.get("crv").toString()); ArrayList x5c = ((ArrayList) publicKeyJwk.get("x5c")); From 21f509982556fa16ad7d76dac5c76b0536a8b8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karsten=20Ra=CC=88th?= Date: Mon, 21 Aug 2023 11:00:23 +0200 Subject: [PATCH 06/41] Support for RSA in DID Trust List added. --- .../restapi/dto/did/DidTrustListEntryDto.java | 11 ++ .../service/did/DidTrustListService.java | 148 +++++++++++++----- 2 files changed, 116 insertions(+), 43 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java index 12e97d65..ebf49308 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java @@ -60,4 +60,15 @@ public static class EcPublicKeyJwk extends PublicKeyJwk { private String valueY; } + @Data + @SuperBuilder + public static class RsaPublicKeyJwk extends PublicKeyJwk { + + @JsonProperty("e") + private String valueE; + + @JsonProperty("n") + private String valueN; + } + } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 46f2bfae..90e8cea0 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -39,7 +39,12 @@ import java.io.InputStream; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.security.PublicKey; +import java.security.cert.CertificateEncodingException; import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.AlgorithmParameterSpec; import java.util.ArrayList; import java.util.Base64; import java.util.Date; @@ -51,6 +56,7 @@ import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; import org.bouncycastle.jce.spec.ECNamedCurveSpec; +import org.jetbrains.annotations.NotNull; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -117,56 +123,20 @@ private String generateTrustList() throws Exception { ); for (TrustedCertificateTrustList cert : certs) { - DidTrustListEntryDto.EcPublicKeyJwk.EcPublicKeyJwkBuilder jwkBuilder = - DidTrustListEntryDto.EcPublicKeyJwk.builder(); - - if (cert.getParsedCertificate().getPublicKey() instanceof ECPublicKey publicKey) { - jwkBuilder.valueX(Base64.getEncoder().encodeToString(publicKey.getW().getAffineX().toByteArray())); - jwkBuilder.valueY(Base64.getEncoder().encodeToString(publicKey.getW().getAffineY().toByteArray())); - - ECNamedCurveSpec curveSpec = (ECNamedCurveSpec) publicKey.getParams(); - if (curveSpec.getName().equals("prime256v1")) { - jwkBuilder.curve("P-256"); - } else if (curveSpec.getName().equals("prime384v1")) { - jwkBuilder.curve("P-384"); - } else if (curveSpec.getName().equals("prime521v1")) { - jwkBuilder.curve("P-521"); - } + PublicKey publicKey = cert.getParsedCertificate().getPublicKey(); - jwkBuilder.keyType("EC"); - jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); - DidTrustListEntryDto.EcPublicKeyJwk jwk = jwkBuilder.build(); - - // Search for Issuer of DSC - Optional csca = trustListService.getTrustedCertificateTrustList( - List.of(TrustedPartyEntity.CertificateType.CSCA.name()), - List.of(cert.getCountry()), - List.of(cert.getDomain()), - configProperties.getDid().getIncludeFederated()).stream() - .filter(tp -> tp.getParsedCertificate().getSubjectX500Principal() - .equals(cert.getParsedCertificate().getIssuerX500Principal())) - .findFirst(); - - if (csca.isPresent()) { - jwk.getEncodedX509Certificates() - .add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded())); + if (publicKey instanceof RSAPublicKey rsaPublicKey) { + if (addRsaTrustListEntry(trustList, cert, rsaPublicKey)) { + continue; } - - DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto(); - trustListEntry.setType("JsonWebKey2020"); - trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + cert.getKid()); - trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()); - trustListEntry.setPublicKeyJwk(jwk); - - trustList.getVerificationMethod().add(trustListEntry); - + } else if (publicKey instanceof ECPublicKey ecPublicKey) { + addEcTrustListEntry(trustList, cert, ecPublicKey); } else { - log.error("Public Key is not EC Public Key for cert {} of country {}", + log.error("Public Key is not RSA or EC Public Key for cert {} of country {}", cert.getThumbprint(), cert.getCountry()); } - } // Add TrustedIssuer @@ -210,4 +180,96 @@ private String generateTrustList() throws Exception { return jsonLdObject.toJson(); } + + private void addEcTrustListEntry(DidTrustListDto trustList, + TrustedCertificateTrustList cert, + ECPublicKey ecPublicKey) throws CertificateEncodingException { + DidTrustListEntryDto.EcPublicKeyJwk.EcPublicKeyJwkBuilder jwkBuilder = + DidTrustListEntryDto.EcPublicKeyJwk.builder(); + + jwkBuilder.valueX(Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineX().toByteArray())); + jwkBuilder.valueY(Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineY().toByteArray())); + + ECNamedCurveSpec curveSpec = (ECNamedCurveSpec) ecPublicKey.getParams(); + switch (curveSpec.getName()) { + case "prime256v1" -> jwkBuilder.curve("P-256"); + case "prime384v1" -> jwkBuilder.curve("P-384"); + case "prime521v1" -> jwkBuilder.curve("P-521"); + default -> { + log.error("Unknown Curve: {}", curveSpec.getName()); + return; + } + } + + jwkBuilder.keyType("EC"); + jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); + DidTrustListEntryDto.EcPublicKeyJwk jwk = jwkBuilder.build(); + + Optional csca = searchForIssuer(cert); + + if (csca.isPresent()) { + jwk.getEncodedX509Certificates() + .add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded())); + } + + DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto(); + trustListEntry.setType("JsonWebKey2020"); + trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + cert.getKid()); + trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()); + trustListEntry.setPublicKeyJwk(jwk); + + trustList.getVerificationMethod().add(trustListEntry); + } + + private boolean addRsaTrustListEntry(DidTrustListDto trustList, + TrustedCertificateTrustList cert, + RSAPublicKey rsaPublicKey) throws CertificateEncodingException { + DidTrustListEntryDto.RsaPublicKeyJwk.RsaPublicKeyJwkBuilder jwkBuilder = + DidTrustListEntryDto.RsaPublicKeyJwk.builder(); + AlgorithmParameterSpec params = rsaPublicKey.getParams(); + if (params instanceof RSAKey) { + jwkBuilder.valueN(Base64.getEncoder() + .encodeToString(rsaPublicKey.getModulus().toByteArray())); + jwkBuilder.valueE(Base64.getEncoder() + .encodeToString(rsaPublicKey.getPublicExponent().toByteArray())); + } else { + log.error("RSA Public Key has no Parameters for cert {} of country {}", + cert.getThumbprint(), + cert.getCountry()); + return true; + } + jwkBuilder.keyType("RSA"); + jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); + DidTrustListEntryDto.RsaPublicKeyJwk jwk = jwkBuilder.build(); + + Optional csca = searchForIssuer(cert); + + if (csca.isPresent()) { + jwk.getEncodedX509Certificates() + .add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded())); + } + + DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto(); + trustListEntry.setType("JsonWebKey2020"); + trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + cert.getKid()); + trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()); + trustListEntry.setPublicKeyJwk(jwk); + + trustList.getVerificationMethod().add(trustListEntry); + return false; + } + + @NotNull + private Optional searchForIssuer(TrustedCertificateTrustList cert) { + // Search for Issuer of DSC + Optional csca = trustListService.getTrustedCertificateTrustList( + List.of(TrustedPartyEntity.CertificateType.CSCA.name()), + List.of(cert.getCountry()), + List.of(cert.getDomain()), + configProperties.getDid().getIncludeFederated()).stream() + .filter(tp -> tp.getParsedCertificate().getSubjectX500Principal() + .equals(cert.getParsedCertificate().getIssuerX500Principal())) + .findFirst(); + return csca; + } } From 267028cb5b5cace4b37032ab2ff4c6527d136962 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Fri, 25 Aug 2023 16:04:26 +0200 Subject: [PATCH 07/41] fix(db-schema): data type for valuesets --- src/main/resources/db/changelog.xml | 1 + .../db/changelog/change-data-type-for-valuesets.xml | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/main/resources/db/changelog/change-data-type-for-valuesets.xml diff --git a/src/main/resources/db/changelog.xml b/src/main/resources/db/changelog.xml index 33cdf04c..f5f943f1 100644 --- a/src/main/resources/db/changelog.xml +++ b/src/main/resources/db/changelog.xml @@ -19,4 +19,5 @@ + diff --git a/src/main/resources/db/changelog/change-data-type-for-valuesets.xml b/src/main/resources/db/changelog/change-data-type-for-valuesets.xml new file mode 100644 index 00000000..4b28e862 --- /dev/null +++ b/src/main/resources/db/changelog/change-data-type-for-valuesets.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file From 0dbf97b632d363b4848c1bba48a70e96c1da889c Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Fri, 25 Aug 2023 18:39:07 +0200 Subject: [PATCH 08/41] fix(db-schema): data type for valuesets --- .../java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java index 3a506fa8..8bd4f295 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java @@ -30,6 +30,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; + @Getter @Setter @Entity @@ -45,8 +46,7 @@ public class ValuesetEntity { /** * Signature of the TrustAnchor. */ - @Column(name = "json", nullable = false, length = 1024000) - @Lob + @Column(name = "json", nullable = false, columnDefinition = "TEXT") String json; } From b6d1ca0bbfc04034ca7f6b322a43c2e38db8e8b8 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Fri, 25 Aug 2023 18:48:17 +0200 Subject: [PATCH 09/41] fix(db-schema): data type for valuesets --- .../java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java index 8bd4f295..7b195502 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java @@ -47,6 +47,7 @@ public class ValuesetEntity { * Signature of the TrustAnchor. */ @Column(name = "json", nullable = false, columnDefinition = "TEXT") + @Lob String json; } From 3f18b848bdc080b7ab24ec59cbd6dd98932c7b67 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 28 Aug 2023 10:32:42 +0200 Subject: [PATCH 10/41] fix(db-schema): data type for valuesets --- .../java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java | 4 +--- .../resources/db/changelog/change-data-type-for-valuesets.xml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java index 7b195502..80b62389 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java @@ -23,7 +23,6 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; -import jakarta.persistence.Lob; import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Getter; @@ -46,8 +45,7 @@ public class ValuesetEntity { /** * Signature of the TrustAnchor. */ - @Column(name = "json", nullable = false, columnDefinition = "TEXT") - @Lob + @Column(name = "json", nullable = false, columnDefinition = "text") String json; } diff --git a/src/main/resources/db/changelog/change-data-type-for-valuesets.xml b/src/main/resources/db/changelog/change-data-type-for-valuesets.xml index 4b28e862..e222c2d8 100644 --- a/src/main/resources/db/changelog/change-data-type-for-valuesets.xml +++ b/src/main/resources/db/changelog/change-data-type-for-valuesets.xml @@ -6,7 +6,7 @@ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS"> - + \ No newline at end of file From 16532c8f823a1798cbf4253d9ddc9f26d9b2198a Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 28 Aug 2023 19:02:54 +0200 Subject: [PATCH 11/41] fix(db-schema): data type for valuesets --- .../java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java index 80b62389..00f4c54b 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/entity/ValuesetEntity.java @@ -28,6 +28,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.annotations.JdbcType; +import org.hibernate.type.descriptor.jdbc.LongVarcharJdbcType; @Getter @@ -45,7 +47,8 @@ public class ValuesetEntity { /** * Signature of the TrustAnchor. */ - @Column(name = "json", nullable = false, columnDefinition = "text") + @Column(name = "json", nullable = false, length = 1_024_000) + @JdbcType(LongVarcharJdbcType.class) String json; } From 681ad50f70cfde8eac42443838fa779a6722ebf9 Mon Sep 17 00:00:00 2001 From: Andreas Scheibal Date: Tue, 29 Aug 2023 18:16:34 +0200 Subject: [PATCH 12/41] fix: clob type signed_batch, compose postgres --- docker-compose.yml | 42 +++++++++++++------ .../gateway/entity/RevocationBatchEntity.java | 5 ++- src/main/resources/db/changelog.xml | 1 + .../change-revocation-batch-value-type.xml | 11 +++++ 4 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 src/main/resources/db/changelog/change-revocation-batch-value-type.xml diff --git a/docker-compose.yml b/docker-compose.yml index 0024c7a9..a5dc328a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,21 +1,34 @@ version: '3' services: - mysql: - image: mysql/mysql-server:5.7 + # mysql: + # image: mysql/mysql-server:5.7 + # ports: + # - 3306:3306 + # environment: + # - MYSQL_DATABASE=dgc + # - MYSQL_ROOT_PASSWORD=admin # do not use this for production deployments + # - MYSQL_USER=dgc_adm + # - MYSQL_PASSWORD=admin # do not use this for production deployments + # networks: + # persistence: + + postgres: + image: postgres ports: - - 3306:3306 + - 5432:5432 environment: - - MYSQL_DATABASE=dgc - - MYSQL_ROOT_PASSWORD=admin # do not use this for production deployments - - MYSQL_USER=dgc_adm - - MYSQL_PASSWORD=admin # do not use this for production deployments + - POSTGRES_PASSWORD=admin + - PGPASSWORD=admin + - POSTGRES_USER=postgres + - POSTGRES_DB=postgres networks: persistence: ddcc-gateway: build: . - image: world-health-organization/ddcc-gateway + #image: world-health-organization/ddcc-gateway + image: smarttrustnetworkgateway:latest volumes: - ./certs:/ec/prod/app/san/dgc - ./logs:/logs @@ -23,9 +36,13 @@ services: - 8080:8080 environment: - SERVER_PORT=8080 - - SPRING_PROFILES_ACTIVE=mysql,docker - - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/dgc - - SPRING_DATASOURCE_USERNAME=dgc_adm + - SPRING_PROFILES_ACTIVE=log2console,local + #- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/dgc + - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/postgres + - SPRING_DATASOURCE_DRIVERCLASSNAME=org.postgresql.Driver + - SPRING_DATASOURCE_JNDI_NAME=false + - SPRING_JPA_DATABASEPLATFORM=org.hibernate.dialect.PostgreSQLDialect + - SPRING_DATASOURCE_USERNAME=postgres - SPRING_DATASOURCE_PASSWORD=admin # do not use this for production deployments - DGC_TRUSTANCHOR_KEYSTOREPATH=/ec/prod/app/san/dgc/ta.jks - DGC_TRUSTANCHOR_KEYSTOREPASS=dgcg-p4ssw0rd # do not use this for production deployments @@ -33,7 +50,8 @@ services: - DGC_FEDERATION_KEYSTOREPATH=/ec/prod/app/san/dgc/ta.jks #TODO: change to federation.jks - DGC_FEDERATION_KEYSTOREPASSWORD=dgcg-p4ssw0rd # do not use this for production deployments depends_on: - - mysql + # - mysql + - postgres networks: backend: persistence: diff --git a/src/main/java/eu/europa/ec/dgc/gateway/entity/RevocationBatchEntity.java b/src/main/java/eu/europa/ec/dgc/gateway/entity/RevocationBatchEntity.java index b3fca6c3..37f34c7f 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/entity/RevocationBatchEntity.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/entity/RevocationBatchEntity.java @@ -28,13 +28,14 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Index; -import jakarta.persistence.Lob; import jakarta.persistence.Table; import java.time.ZonedDateTime; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.annotations.JdbcType; +import org.hibernate.type.descriptor.jdbc.LongVarcharJdbcType; @Getter @Setter @@ -97,7 +98,7 @@ public class RevocationBatchEntity { * The Signed CMS with the batch. */ @Column(name = "signed_batch", length = 1_024_000) - @Lob + @JdbcType(LongVarcharJdbcType.class) private String signedBatch; /** diff --git a/src/main/resources/db/changelog.xml b/src/main/resources/db/changelog.xml index f5f943f1..0d59babf 100644 --- a/src/main/resources/db/changelog.xml +++ b/src/main/resources/db/changelog.xml @@ -20,4 +20,5 @@ + diff --git a/src/main/resources/db/changelog/change-revocation-batch-value-type.xml b/src/main/resources/db/changelog/change-revocation-batch-value-type.xml new file mode 100644 index 00000000..44e697ae --- /dev/null +++ b/src/main/resources/db/changelog/change-revocation-batch-value-type.xml @@ -0,0 +1,11 @@ + + + + + + From 8865183ec967cfda16a02e7bd9a7596cd303137a Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Tue, 29 Aug 2023 19:45:22 +0200 Subject: [PATCH 13/41] fix(db-schema): data type for valuesets --- .../resources/db/changelog/change-data-type-for-valuesets.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/change-data-type-for-valuesets.xml b/src/main/resources/db/changelog/change-data-type-for-valuesets.xml index e222c2d8..93e52c0d 100644 --- a/src/main/resources/db/changelog/change-data-type-for-valuesets.xml +++ b/src/main/resources/db/changelog/change-data-type-for-valuesets.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS"> - + From 69f5882c50b99accab60315315ff7c15bee4af0c Mon Sep 17 00:00:00 2001 From: Andreas Scheibal Date: Thu, 31 Aug 2023 07:51:40 +0200 Subject: [PATCH 14/41] =?UTF-8?q?chore:=20remove=20unwanted=20.DS=5FStore?= =?UTF-8?q?=20=F0=9F=98=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 8196 -> 0 bytes .gitignore | 2 +- src/main/resources/.DS_Store | Bin 8196 -> 0 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 .DS_Store delete mode 100644 src/main/resources/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 51cfc3672d1a553c32b382818c1b11a0aae417c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMU2hUW6g|^oDPU?-AMA?>f1pkL2iQWjiGl$dNeBGAo3oA+QGuvHR3Iu46^IJl1_k)embSg-y>IWvJ}M9u_%9WZ=R=*BV8h|k zqCPsm+hH;gHv2@;VIQykVONY^w>Bp^X zT!ms>;bH1(4%4t0`=~%vAg_Sb?j;;zj7uzn`u#EQ9sbg$#PT0Iyu&pHf%T8Ty1KHy zr1vYNm|>LVn1_WN+R=W73wn5udBFJ=aPH$AUl@&}r3 zq)Dg|L|312&qda!_fs4(zCN*yCq*%;!ajSCYo%QC16Q0;FIjy;#ZoFYTBDUH?)#`x zmA^jTQt4dOM)dVLCAV&{o2sF2SH?4Db4=~p=%JNY&+K^WZPBWu`IC{gmCQ4?cNp_W zo|QSKfhF_HSe8|f3Dx*id~!0@74Ace``W~F;+k`kVbmlu=6I$%*vG3PmYfvx)yws+ z?$81YJ=tSD*#+^*dCBlLY02+Wkh7@cd*7npbJ~r03WDc=5q*5y3T;PvY7%l}9PFy> zeulBbJ$lN0?NX%!ykKr!&J^Y?C&J^#_dmZ#u|)-LK!Hu`bH7Gxt^fW123C$PqXJQZ z+oFIeHG9n?M&oMhTwGFX*Ll6+B~9#>7L~$I%W3fdDHf?9xKg!JHn1S&S7Ezt4N$P9Tl&XOncW#+!gQwY%x=Mo zRvtlpRHHGP_?KuTJ_!Cqqb6$92Tcen7!!?&4<^2tD2bY==gyraZgCTR(16ZO=AOCt zo^$U#XTR^>J-duCWQyi;#u^!8GCf@CDph|{_&9$qDpJ%_OA=(yn9cIcU;#<*BJH>% zjzAoNI0A75;t0eMxD+BlcQ!9_m3v=|#&sNlI0FC62=MbEK@XSdNKOhF9vxJLDF8{H z0)&O$DGvy35|K%rZKpcUKBf#mSvN2Xn+>w8BII-{<4OgMz- zP+&8rIC#9ecaC3b7v9yZFMIcSe5Jk-f;3oQnuP0Cu`p+wDSeeae6%84s6dI8VsyM0UzTN zRSXRd`(7bv4<{S6X?~$Ko3GJ5#*O`ctKgGViYtNZkdj0Gx z8&q|e;^+qUKHDnn7`M&fz>wkRE!VW&{R1W2w{wow=Nh9{J@SfjW_G4GPy6 zcFXb*pR&y~Ei>HY_FitG+iuAwbW^Ye$o12*EH{-Q)|74$uN5(BN~c6`Ls>79{DND+ zQY^!^usuY$!|XVFkUh>`Vkg-t_AdK~onv3JZ`t?kJo}0L%zi;FreQi{)MFl+u^25_ zf|W?44Hxb}y9)wzJYJ$)a|Z+yaXf~^hWg?9}T{M&0QkiI~OJP%8 zuHCE<8TA^`OlqqYS%+w>Q*Tj-mU^vdZdBV8ej?~BY-=6bZ8A|y|ECcD0Xxmkvai^8 zg!o@kLpYy{1a87otic9sB#gJC6St!q+X?9$=XKw^gDV=c}W-lr6Z9=k6zs zGAAmHFQZnC*lQ!t|2wPy{(l*H6mK<-KpcU;8v)dIWIHlsRqaIMxpsn{z4Y+H^(KW3 yO{fafagt#=PV&MZhV-5wRc@1xgln!H)0$`2L@o6#r-L|K9 Date: Thu, 31 Aug 2023 09:27:35 +0200 Subject: [PATCH 15/41] chore: Update CODEOWNERS --- CODEOWNERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 0f8a2d3b..b7948371 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,5 +5,4 @@ # For more details, read the following article on GitHub: https://help.github.com/articles/about-codeowners/. # These are the default owners for the whole content of this repository. The default owners are automatically added as reviewers when you open a pull request, unless different owners are specified in the file. -* @eu-digital-green-certificates/dgc-gateway-members -* @ascheibal @f11h @litlfred +* @ascheibal @f11h @litlfred @tence From 93f55b6b357c300d1a2cc8a9417dcd5528c5ab54 Mon Sep 17 00:00:00 2001 From: Andreas Scheibal Date: Thu, 31 Aug 2023 09:56:03 +0200 Subject: [PATCH 16/41] fix: remove comments --- docker-compose.yml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a5dc328a..49d6ccd6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,25 +1,13 @@ version: '3' services: - # mysql: - # image: mysql/mysql-server:5.7 - # ports: - # - 3306:3306 - # environment: - # - MYSQL_DATABASE=dgc - # - MYSQL_ROOT_PASSWORD=admin # do not use this for production deployments - # - MYSQL_USER=dgc_adm - # - MYSQL_PASSWORD=admin # do not use this for production deployments - # networks: - # persistence: - postgres: image: postgres ports: - 5432:5432 environment: - - POSTGRES_PASSWORD=admin - - PGPASSWORD=admin + - POSTGRES_PASSWORD=admin # do not use this for production deployments + - PGPASSWORD=admin # do not use this for production deployments - POSTGRES_USER=postgres - POSTGRES_DB=postgres networks: @@ -27,7 +15,6 @@ services: ddcc-gateway: build: . - #image: world-health-organization/ddcc-gateway image: smarttrustnetworkgateway:latest volumes: - ./certs:/ec/prod/app/san/dgc @@ -37,7 +24,6 @@ services: environment: - SERVER_PORT=8080 - SPRING_PROFILES_ACTIVE=log2console,local - #- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/dgc - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/postgres - SPRING_DATASOURCE_DRIVERCLASSNAME=org.postgresql.Driver - SPRING_DATASOURCE_JNDI_NAME=false @@ -50,7 +36,6 @@ services: - DGC_FEDERATION_KEYSTOREPATH=/ec/prod/app/san/dgc/ta.jks #TODO: change to federation.jks - DGC_FEDERATION_KEYSTOREPASSWORD=dgcg-p4ssw0rd # do not use this for production deployments depends_on: - # - mysql - postgres networks: backend: From 7a573cf3aeaaa3c31017ec8158d34abb543ac58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karsten=20Ra=CC=88th?= Date: Wed, 13 Sep 2023 17:27:12 +0200 Subject: [PATCH 17/41] Tests for RSA DidTrustList added. --- .../service/did/DidTrustListService.java | 20 ++--- .../service/DidTrustListServiceTest.java | 82 +++++++++++++------ .../testdata/CertificateTestUtils.java | 44 ++++++++-- .../testdata/TrustedPartyTestHelper.java | 30 +++++-- 4 files changed, 121 insertions(+), 55 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 90e8cea0..3fa0f6ef 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -160,7 +160,6 @@ private String generateTrustList() throws Exception { 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( @@ -226,18 +225,10 @@ private boolean addRsaTrustListEntry(DidTrustListDto trustList, RSAPublicKey rsaPublicKey) throws CertificateEncodingException { DidTrustListEntryDto.RsaPublicKeyJwk.RsaPublicKeyJwkBuilder jwkBuilder = DidTrustListEntryDto.RsaPublicKeyJwk.builder(); - AlgorithmParameterSpec params = rsaPublicKey.getParams(); - if (params instanceof RSAKey) { - jwkBuilder.valueN(Base64.getEncoder() - .encodeToString(rsaPublicKey.getModulus().toByteArray())); - jwkBuilder.valueE(Base64.getEncoder() - .encodeToString(rsaPublicKey.getPublicExponent().toByteArray())); - } else { - log.error("RSA Public Key has no Parameters for cert {} of country {}", - cert.getThumbprint(), - cert.getCountry()); - return true; - } + jwkBuilder.valueN(Base64.getEncoder() + .encodeToString(rsaPublicKey.getModulus().toByteArray())); + jwkBuilder.valueE(Base64.getEncoder() + .encodeToString(rsaPublicKey.getPublicExponent().toByteArray())); jwkBuilder.keyType("RSA"); jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); DidTrustListEntryDto.RsaPublicKeyJwk jwk = jwkBuilder.build(); @@ -262,7 +253,7 @@ private boolean addRsaTrustListEntry(DidTrustListDto trustList, @NotNull private Optional searchForIssuer(TrustedCertificateTrustList cert) { // Search for Issuer of DSC - Optional csca = trustListService.getTrustedCertificateTrustList( + return trustListService.getTrustedCertificateTrustList( List.of(TrustedPartyEntity.CertificateType.CSCA.name()), List.of(cert.getCountry()), List.of(cert.getDomain()), @@ -270,6 +261,5 @@ private Optional searchForIssuer(TrustedCertificate .filter(tp -> tp.getParsedCertificate().getSubjectX500Principal() .equals(cert.getParsedCertificate().getIssuerX500Principal())) .findFirst(); - return csca; } } diff --git a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java index 167716d5..eac6e628 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java @@ -43,6 +43,7 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; import java.time.Instant; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -56,6 +57,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -64,7 +67,6 @@ @SpringBootTest public class DidTrustListServiceTest { - @Autowired ObjectMapper objectMapper; @@ -111,34 +113,45 @@ public void cleanUp() { signerInformationRepository.deleteAll(); federationGatewayRepository.deleteAll(); trustedIssuerRepository.deleteAll(); + trustedPartyTestHelper.clear(TrustedPartyEntity.CertificateType.UPLOAD, "DE"); + trustedPartyTestHelper.clear(TrustedPartyEntity.CertificateType.UPLOAD, "EU"); + trustedPartyTestHelper.clear(TrustedPartyEntity.CertificateType.CSCA, "DE"); + trustedPartyTestHelper.clear(TrustedPartyEntity.CertificateType.CSCA, "EU"); + trustedPartyTestHelper.clear(TrustedPartyEntity.CertificateType.AUTHENTICATION, "DE"); + trustedPartyTestHelper.clear(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU"); } - @BeforeEach - void testData() throws Exception { + void testData(CertificateTestUtils.SignerType signerType) throws Exception { cleanUp(); federationGateway = - new FederationGatewayEntity(null, ZonedDateTime.now(), "gw-id", "endpoint", "kid", "pk", "impl", - FederationGatewayEntity.DownloadTarget.FEDERATION, FederationGatewayEntity.Mode.APPEND, "sig", -1L, - null, null, 0L, null, null); + new FederationGatewayEntity(null, ZonedDateTime.now(), "gw-id", "endpoint", + "kid", "pk", "impl", + FederationGatewayEntity.DownloadTarget.FEDERATION, FederationGatewayEntity.Mode.APPEND, "sig", + -1L, null, null, 0L, null, + null); federationGateway = federationGatewayRepository.save(federationGateway); - certUploadDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.UPLOAD, "DE"); - certUploadEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.UPLOAD, "EU"); - certCscaDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.CSCA, "DE"); - certCscaEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.CSCA, "EU"); - certAuthDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.AUTHENTICATION, "DE"); - certAuthEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU"); + certUploadDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.UPLOAD, "DE", signerType); + certUploadEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.UPLOAD, "EU", signerType); + certCscaDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.CSCA, "DE", signerType); + certCscaEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.CSCA, "EU", signerType); + certAuthDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.AUTHENTICATION, "DE", signerType); + certAuthEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU", signerType); - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ec"); + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(signerType.getSigningAlgorithm()); certDscDe = - CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "DE", "Test", certCscaDe, - trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.AUTHENTICATION, "DE")); + CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "DE", + "Test", certCscaDe, + trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.AUTHENTICATION, + "DE", signerType), signerType); certDscDeKid = certificateUtils.getCertKid(certDscDe); certDscEu = - CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EU", "Test", certCscaEu, - trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU")); + CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EU", + "Test", certCscaEu, + trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU", signerType), + signerType); signerInformationRepository.save(new SignerInformationEntity( null, @@ -164,7 +177,8 @@ void testData() throws Exception { null )); - federatedCertDscEx = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EX", "Test"); + federatedCertDscEx = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EX", + "Test", signerType); SignerInformationEntity federatedDscEntity = new SignerInformationEntity( null, ZonedDateTime.now(), @@ -184,8 +198,14 @@ void testData() throws Exception { trustedIssuerRepository.save(trustedIssuerTestHelper.createTrustedIssuer("XY", "DCC")); } - @Test - void testTrustList() throws IOException, CertificateEncodingException { + @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()); @@ -237,12 +257,22 @@ private void assertVerificationMethod(Object in, String kid, X509Certificate dsc LinkedHashMap publicKeyJwk = (LinkedHashMap) jsonNode.get("publicKeyJwk"); - Assertions.assertEquals(((ECPublicKey) dsc.getPublicKey()).getW().getAffineX(), - 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()))); - Assertions.assertEquals("EC", publicKeyJwk.get("kty").toString()); - Assertions.assertEquals("P-256", publicKeyJwk.get("crv").toString()); + 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()))); + Assertions.assertEquals(((ECPublicKey) dsc.getPublicKey()).getW().getAffineY(), + new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("y").toString()))); + Assertions.assertEquals(CertificateTestUtils.SignerType.EC.getSigningAlgorithm(), + 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()))); + Assertions.assertEquals(((RSAPublicKey) dsc.getPublicKey()).getModulus(), + new BigInteger(Base64.getDecoder().decode(publicKeyJwk.get("n").toString()))); + Assertions.assertEquals(CertificateTestUtils.SignerType.RSA.getSigningAlgorithm(), + publicKeyJwk.get("kty").toString()); + } ArrayList x5c = ((ArrayList) publicKeyJwk.get("x5c")); Assertions.assertEquals(Base64.getEncoder().encodeToString(dsc.getEncoded()), x5c.get(0)); if (csca != null) { diff --git a/src/test/java/eu/europa/ec/dgc/gateway/testdata/CertificateTestUtils.java b/src/test/java/eu/europa/ec/dgc/gateway/testdata/CertificateTestUtils.java index 903b9bf3..e1e20373 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/testdata/CertificateTestUtils.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/testdata/CertificateTestUtils.java @@ -31,6 +31,10 @@ import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x509.BasicConstraints; @@ -73,7 +77,15 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr 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); + 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)); + Date validTo = Date.from(Instant.now().plus(365, ChronoUnit.DAYS)); + + return generateCertificate(keyPair, country, commonName, validFrom, validTo, signerType); } public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName, @@ -81,11 +93,21 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr 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); + 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 { + 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); } public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName, - Date validFrom, Date validTo) throws Exception { + Date validFrom, Date validTo, + SignerType signerType) throws Exception { X500Name subject = new X500NameBuilder() .addRDN(X509ObjectIdentifiers.countryName, country) .addRDN(X509ObjectIdentifiers.commonName, commonName) @@ -93,7 +115,7 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr BigInteger certSerial = new BigInteger(Long.toString(System.currentTimeMillis())); - ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withECDSA").build(keyPair.getPrivate()); + ContentSigner contentSigner = new JcaContentSignerBuilder(signerType.signingMethod).build(keyPair.getPrivate()); JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(subject, certSerial, validFrom, validTo, subject, keyPair.getPublic()); @@ -106,7 +128,7 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr public static X509Certificate generateCertificate(KeyPair keyPair, String country, String commonName, Date validFrom, Date validTo, X509Certificate ca, - PrivateKey caKey) throws Exception { + PrivateKey caKey, SignerType signerType) throws Exception { X500Name subject = new X500NameBuilder() .addRDN(X509ObjectIdentifiers.countryName, country) .addRDN(X509ObjectIdentifiers.commonName, commonName) @@ -116,7 +138,7 @@ public static X509Certificate generateCertificate(KeyPair keyPair, String countr BigInteger certSerial = new BigInteger(Long.toString(System.currentTimeMillis())); - ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withECDSA").build(caKey); + ContentSigner contentSigner = new JcaContentSignerBuilder(signerType.signingMethod).build(caKey); JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(issuer, certSerial, validFrom, validTo, subject, keyPair.getPublic()); @@ -144,4 +166,14 @@ public static void assertEquals(ValidationRule v1, ValidationRule v2) { Assertions.assertEquals(v1.getLogic(), v2.getLogic()); } + @RequiredArgsConstructor(access = AccessLevel.PRIVATE) + @Getter + public static class SignerType { + + private final String signingMethod; + private final String signingAlgorithm; + + public static SignerType RSA = new SignerType("SHA256withRSA", "RSA"); + public static SignerType EC = new SignerType("SHA256withECDSA", "EC"); + } } diff --git a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java index b4571f9a..87449667 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java @@ -72,17 +72,29 @@ public X509Certificate getTestCert(String testCertId, TrustedPartyEntity.Certifi } public String getHash(TrustedPartyEntity.CertificateType type, String countryCode) throws Exception { - prepareTestCert(type, countryCode); + prepareTestCert(type, countryCode, CertificateTestUtils.SignerType.EC); return hashMap.get(type).get(countryCode); } public X509Certificate getCert(TrustedPartyEntity.CertificateType type, String countryCode) throws Exception { - prepareTestCert(type, countryCode); + prepareTestCert(type, countryCode, CertificateTestUtils.SignerType.EC); + return certificateMap.get(type).get(countryCode); + } + + public X509Certificate getCert(TrustedPartyEntity.CertificateType type, String countryCode, + CertificateTestUtils.SignerType signerType) throws Exception { + prepareTestCert(type, countryCode, signerType); return certificateMap.get(type).get(countryCode); } public PrivateKey getPrivateKey(TrustedPartyEntity.CertificateType type, String countryCode) throws Exception { - prepareTestCert(type, countryCode); + prepareTestCert(type, countryCode, CertificateTestUtils.SignerType.EC); + return privateKeyMap.get(type).get(countryCode); + } + + public PrivateKey getPrivateKey(TrustedPartyEntity.CertificateType type, String countryCode, + CertificateTestUtils.SignerType signerType) throws Exception { + prepareTestCert(type, countryCode, signerType); return privateKeyMap.get(type).get(countryCode); } @@ -103,10 +115,11 @@ public void clear(TrustedPartyEntity.CertificateType type, String countryCode) { privateKeyMap.get(type).remove(countryCode); } - private void prepareTestCert(TrustedPartyEntity.CertificateType type, String countryCode) throws Exception { + private void prepareTestCert(TrustedPartyEntity.CertificateType type, String countryCode, + CertificateTestUtils.SignerType signerType) throws Exception { // Check if a test certificate already exists if (!hashMap.get(type).containsKey(countryCode)) { - createAndInsertCert(type, countryCode); + createAndInsertCert(type, countryCode, signerType); } // Check if generated certificate is (still) present in DB @@ -117,11 +130,12 @@ private void prepareTestCert(TrustedPartyEntity.CertificateType type, String cou } } - private void createAndInsertCert(TrustedPartyEntity.CertificateType type, String countryCode) throws Exception { - KeyPair keyPair = KeyPairGenerator.getInstance("ec").generateKeyPair(); + private void createAndInsertCert(TrustedPartyEntity.CertificateType type, String countryCode, + CertificateTestUtils.SignerType signerType) throws Exception { + KeyPair keyPair = KeyPairGenerator.getInstance(signerType.getSigningAlgorithm()).generateKeyPair(); X509Certificate authCertificate = CertificateTestUtils.generateCertificate(keyPair, countryCode, - "DGC Test " + type.name() + " Cert"); + "DGC Test " + type.name() + " Cert", signerType); certificateMap.get(type).put(countryCode, authCertificate); hashMap.get(type).put(countryCode, certificateUtils.getCertThumbprint(authCertificate)); From 07b4914c7fd0ab6ca25b213a4d7d69e02cc1f92f Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Fri, 15 Sep 2023 15:23:33 +0200 Subject: [PATCH 18/41] Cleanup Code --- .../restapi/dto/did/DidTrustListEntryDto.java | 49 ++++++++-- .../service/did/DidTrustListService.java | 89 ++++--------------- 2 files changed, 59 insertions(+), 79 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java index ebf49308..567aca31 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java @@ -21,9 +21,16 @@ package eu.europa.ec.dgc.gateway.restapi.dto.did; import com.fasterxml.jackson.annotation.JsonProperty; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.Base64; import java.util.List; import lombok.Data; -import lombok.experimental.SuperBuilder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.bouncycastle.jce.spec.ECNamedCurveSpec; @Data public class DidTrustListEntryDto { @@ -36,18 +43,24 @@ public class DidTrustListEntryDto { private PublicKeyJwk publicKeyJwk; - @Data - @SuperBuilder - private abstract static class PublicKeyJwk { + @NoArgsConstructor + @Setter + @Getter + public abstract static class PublicKeyJwk { @JsonProperty("kty") private String keyType; @JsonProperty("x5c") private List encodedX509Certificates; + + private PublicKeyJwk(String keyType, List encodedX509Certificates) { + this.keyType = keyType; + this.encodedX509Certificates = new ArrayList<>(encodedX509Certificates); + } } - @Data - @SuperBuilder + @Getter + @Setter public static class EcPublicKeyJwk extends PublicKeyJwk { @JsonProperty("crv") @@ -58,10 +71,24 @@ public static class EcPublicKeyJwk extends PublicKeyJwk { @JsonProperty("y") private String valueY; + + public EcPublicKeyJwk(ECPublicKey ecPublicKey, List base64EncodedCertificates) { + super("EC", base64EncodedCertificates); + valueX = Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineX().toByteArray()); + valueY = Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineY().toByteArray()); + + ECNamedCurveSpec curveSpec = (ECNamedCurveSpec) ecPublicKey.getParams(); + switch (curveSpec.getName()) { + case "prime256v1" -> curve = "P-256"; + case "prime384v1" -> curve = "P-384"; + case "prime521v1" -> curve = "P-521"; + default -> curve = "UNKNOWN CURVE"; + } + } } - @Data - @SuperBuilder + @Getter + @Setter public static class RsaPublicKeyJwk extends PublicKeyJwk { @JsonProperty("e") @@ -69,6 +96,12 @@ public static class RsaPublicKeyJwk extends PublicKeyJwk { @JsonProperty("n") private String valueN; + + public RsaPublicKeyJwk(RSAPublicKey rsaPublicKey, List base64EncodedCertificates) { + super("RSA", base64EncodedCertificates); + valueN = Base64.getEncoder().encodeToString(rsaPublicKey.getModulus().toByteArray()); + valueE = Base64.getEncoder().encodeToString(rsaPublicKey.getPublicExponent().toByteArray()); + } } } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 3fa0f6ef..fa7dbce2 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -42,9 +42,7 @@ import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.interfaces.ECPublicKey; -import java.security.interfaces.RSAKey; import java.security.interfaces.RSAPublicKey; -import java.security.spec.AlgorithmParameterSpec; import java.util.ArrayList; import java.util.Base64; import java.util.Date; @@ -55,7 +53,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; -import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.jetbrains.annotations.NotNull; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; @@ -127,11 +124,13 @@ private String generateTrustList() throws Exception { PublicKey publicKey = cert.getParsedCertificate().getPublicKey(); if (publicKey instanceof RSAPublicKey rsaPublicKey) { - if (addRsaTrustListEntry(trustList, cert, rsaPublicKey)) { - continue; - } + addTrustListEntry(trustList, cert, + new DidTrustListEntryDto.RsaPublicKeyJwk(rsaPublicKey, List.of(cert.getCertificate()))); + } else if (publicKey instanceof ECPublicKey ecPublicKey) { - addEcTrustListEntry(trustList, cert, ecPublicKey); + addTrustListEntry(trustList, cert, + new DidTrustListEntryDto.EcPublicKeyJwk(ecPublicKey, List.of(cert.getCertificate()))); + } else { log.error("Public Key is not RSA or EC Public Key for cert {} of country {}", cert.getThumbprint(), @@ -179,35 +178,13 @@ private String generateTrustList() throws Exception { return jsonLdObject.toJson(); } - - private void addEcTrustListEntry(DidTrustListDto trustList, - TrustedCertificateTrustList cert, - ECPublicKey ecPublicKey) throws CertificateEncodingException { - DidTrustListEntryDto.EcPublicKeyJwk.EcPublicKeyJwkBuilder jwkBuilder = - DidTrustListEntryDto.EcPublicKeyJwk.builder(); - - jwkBuilder.valueX(Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineX().toByteArray())); - jwkBuilder.valueY(Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineY().toByteArray())); - - ECNamedCurveSpec curveSpec = (ECNamedCurveSpec) ecPublicKey.getParams(); - switch (curveSpec.getName()) { - case "prime256v1" -> jwkBuilder.curve("P-256"); - case "prime384v1" -> jwkBuilder.curve("P-384"); - case "prime521v1" -> jwkBuilder.curve("P-521"); - default -> { - log.error("Unknown Curve: {}", curveSpec.getName()); - return; - } - } - - jwkBuilder.keyType("EC"); - jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); - DidTrustListEntryDto.EcPublicKeyJwk jwk = jwkBuilder.build(); - + private void addTrustListEntry(DidTrustListDto trustList, + TrustedCertificateTrustList cert, + DidTrustListEntryDto.PublicKeyJwk publicKeyJwk) throws CertificateEncodingException { Optional csca = searchForIssuer(cert); if (csca.isPresent()) { - jwk.getEncodedX509Certificates() + publicKeyJwk.getEncodedX509Certificates() .add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded())); } @@ -215,51 +192,21 @@ private void addEcTrustListEntry(DidTrustListDto trustList, trustListEntry.setType("JsonWebKey2020"); trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + cert.getKid()); trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()); - trustListEntry.setPublicKeyJwk(jwk); - - trustList.getVerificationMethod().add(trustListEntry); - } - - private boolean addRsaTrustListEntry(DidTrustListDto trustList, - TrustedCertificateTrustList cert, - RSAPublicKey rsaPublicKey) throws CertificateEncodingException { - DidTrustListEntryDto.RsaPublicKeyJwk.RsaPublicKeyJwkBuilder jwkBuilder = - DidTrustListEntryDto.RsaPublicKeyJwk.builder(); - jwkBuilder.valueN(Base64.getEncoder() - .encodeToString(rsaPublicKey.getModulus().toByteArray())); - jwkBuilder.valueE(Base64.getEncoder() - .encodeToString(rsaPublicKey.getPublicExponent().toByteArray())); - jwkBuilder.keyType("RSA"); - jwkBuilder.encodedX509Certificates(new ArrayList<>(List.of(cert.getCertificate()))); - DidTrustListEntryDto.RsaPublicKeyJwk jwk = jwkBuilder.build(); - - Optional csca = searchForIssuer(cert); - - if (csca.isPresent()) { - jwk.getEncodedX509Certificates() - .add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded())); - } - - DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto(); - trustListEntry.setType("JsonWebKey2020"); - trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + cert.getKid()); - trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()); - trustListEntry.setPublicKeyJwk(jwk); + trustListEntry.setPublicKeyJwk(publicKeyJwk); trustList.getVerificationMethod().add(trustListEntry); - return false; } @NotNull private Optional searchForIssuer(TrustedCertificateTrustList cert) { // Search for Issuer of DSC return trustListService.getTrustedCertificateTrustList( - List.of(TrustedPartyEntity.CertificateType.CSCA.name()), - List.of(cert.getCountry()), - List.of(cert.getDomain()), - configProperties.getDid().getIncludeFederated()).stream() - .filter(tp -> tp.getParsedCertificate().getSubjectX500Principal() - .equals(cert.getParsedCertificate().getIssuerX500Principal())) - .findFirst(); + List.of(TrustedPartyEntity.CertificateType.CSCA.name()), + List.of(cert.getCountry()), + List.of(cert.getDomain()), + configProperties.getDid().getIncludeFederated()).stream() + .filter(tp -> tp.getParsedCertificate().getSubjectX500Principal() + .equals(cert.getParsedCertificate().getIssuerX500Principal())) + .findFirst(); } } From 7f8b9e379bc5813a510a2b5c20f887c1523a1a71 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Fri, 15 Sep 2023 15:28:32 +0200 Subject: [PATCH 19/41] Fix Checkstyle Findings --- .../restapi/dto/did/DidTrustListEntryDto.java | 14 ++++++++++++++ .../gateway/service/did/DidTrustListService.java | 1 + 2 files changed, 15 insertions(+) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java index 567aca31..25deb323 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListEntryDto.java @@ -72,6 +72,13 @@ public static class EcPublicKeyJwk extends PublicKeyJwk { @JsonProperty("y") private String valueY; + /** + * Instantiate EC PublicKey JWK Class. + * + * @param ecPublicKey EC Public Key that should be wrapped. + * @param base64EncodedCertificates List of Base64 encoded Certificates assigned to provided Public Key. + * They will be added within x5c property of JWK. + */ public EcPublicKeyJwk(ECPublicKey ecPublicKey, List base64EncodedCertificates) { super("EC", base64EncodedCertificates); valueX = Base64.getEncoder().encodeToString(ecPublicKey.getW().getAffineX().toByteArray()); @@ -97,6 +104,13 @@ public static class RsaPublicKeyJwk extends PublicKeyJwk { @JsonProperty("n") private String valueN; + /** + * Instantiate RSA PublicKey JWK Class. + * + * @param rsaPublicKey RSA Public Key that should be wrapped. + * @param base64EncodedCertificates List of Base64 encoded Certificates assigned to provided Public Key. + * They will be added within x5c property of JWK. + */ public RsaPublicKeyJwk(RSAPublicKey rsaPublicKey, List base64EncodedCertificates) { super("RSA", base64EncodedCertificates); valueN = Base64.getEncoder().encodeToString(rsaPublicKey.getModulus().toByteArray()); diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index fa7dbce2..f3cb1a4f 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -178,6 +178,7 @@ private String generateTrustList() throws Exception { return jsonLdObject.toJson(); } + private void addTrustListEntry(DidTrustListDto trustList, TrustedCertificateTrustList cert, DidTrustListEntryDto.PublicKeyJwk publicKeyJwk) throws CertificateEncodingException { From bc153ed83fd68e822e5f2645b58fe706ea8c0263 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 9 Oct 2023 16:22:01 +0200 Subject: [PATCH 20/41] feat(domain): changed supported length of domain to 32 --- .../dgc/gateway/entity/FederatedEntity.java | 2 +- .../change-supported-length-of-domain.xml | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/db/changelog/change-supported-length-of-domain.xml diff --git a/src/main/java/eu/europa/ec/dgc/gateway/entity/FederatedEntity.java b/src/main/java/eu/europa/ec/dgc/gateway/entity/FederatedEntity.java index dac491da..b433d178 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/entity/FederatedEntity.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/entity/FederatedEntity.java @@ -41,7 +41,7 @@ public abstract class FederatedEntity { @JoinColumn(name = "source_gateway_id", referencedColumnName = "gateway_id") private FederationGatewayEntity sourceGateway; - @Column(name = "domain", columnDefinition = "varchar(10) DEFAULT 'DCC'") + @Column(name = "domain", columnDefinition = "varchar(32) DEFAULT 'DCC'") String domain = "DCC"; @Column(name = "version", columnDefinition = "int default 1", nullable = false) diff --git a/src/main/resources/db/changelog/change-supported-length-of-domain.xml b/src/main/resources/db/changelog/change-supported-length-of-domain.xml new file mode 100644 index 00000000..dbf3afe5 --- /dev/null +++ b/src/main/resources/db/changelog/change-supported-length-of-domain.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + From 3049d9c0aff234f09eda6aa0a072eb8334866cbf Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 9 Oct 2023 16:25:33 +0200 Subject: [PATCH 21/41] Update change-supported-length-of-domain.xml --- .../db/changelog/change-supported-length-of-domain.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/resources/db/changelog/change-supported-length-of-domain.xml b/src/main/resources/db/changelog/change-supported-length-of-domain.xml index dbf3afe5..68dd2c03 100644 --- a/src/main/resources/db/changelog/change-supported-length-of-domain.xml +++ b/src/main/resources/db/changelog/change-supported-length-of-domain.xml @@ -5,10 +5,6 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd" objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS"> - - - - From 856e077f6e551213618802272a90c0e4654a2a53 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 9 Oct 2023 16:26:56 +0200 Subject: [PATCH 22/41] Update change-supported-length-of-domain.xml --- .../db/changelog/change-supported-length-of-domain.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/change-supported-length-of-domain.xml b/src/main/resources/db/changelog/change-supported-length-of-domain.xml index 68dd2c03..a65bbcbc 100644 --- a/src/main/resources/db/changelog/change-supported-length-of-domain.xml +++ b/src/main/resources/db/changelog/change-supported-length-of-domain.xml @@ -14,7 +14,7 @@ - + From 62f42bf5de8f69364a50225bae12d37f06bf335f Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 9 Oct 2023 16:34:31 +0200 Subject: [PATCH 23/41] feat(domain): changed supported length of domain to 32 --- src/main/resources/db/changelog.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/db/changelog.xml b/src/main/resources/db/changelog.xml index 0d59babf..b75ce0ef 100644 --- a/src/main/resources/db/changelog.xml +++ b/src/main/resources/db/changelog.xml @@ -21,4 +21,5 @@ + From e68dd148865b710eff86601e827d2cbda7eaa430 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 9 Oct 2023 16:37:05 +0200 Subject: [PATCH 24/41] feat(domain): changed supported length of domain to 32 --- src/main/resources/db/changelog.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog.xml b/src/main/resources/db/changelog.xml index b75ce0ef..b6921e11 100644 --- a/src/main/resources/db/changelog.xml +++ b/src/main/resources/db/changelog.xml @@ -21,5 +21,5 @@ - + From 3d5c6d1a7c1b29c3b6109454519c5296e6c94ad6 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Thu, 12 Oct 2023 12:20:48 +0200 Subject: [PATCH 25/41] Fix Legacy Trustlist Endpoint to only return EU DCC Types --- .../SignerInformationRepository.java | 2 - .../repository/TrustedPartyRepository.java | 3 +- .../service/SignerInformationService.java | 17 ++------- .../dgc/gateway/service/TrustListService.java | 8 ++-- .../gateway/service/TrustedPartyService.java | 8 ++-- .../controller/TrustListIntegrationTest.java | 37 ++++++++++++++++++- .../testdata/TrustedPartyTestHelper.java | 9 +++-- 7 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/repository/SignerInformationRepository.java b/src/main/java/eu/europa/ec/dgc/gateway/repository/SignerInformationRepository.java index a974da9b..7f0c5a46 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/repository/SignerInformationRepository.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/repository/SignerInformationRepository.java @@ -30,8 +30,6 @@ public interface SignerInformationRepository extends JpaRepository { - List getAllBySourceGatewayIsNullAndDomainIs(String domain); - @Query("SELECT s FROM SignerInformationEntity s WHERE " + "(:ignoreGroup = true OR s.certificateType IN (:group)) AND " + "(:ignoreCountry = true OR s.country IN (:country)) AND " diff --git a/src/main/java/eu/europa/ec/dgc/gateway/repository/TrustedPartyRepository.java b/src/main/java/eu/europa/ec/dgc/gateway/repository/TrustedPartyRepository.java index 00159ed3..9e2439c1 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/repository/TrustedPartyRepository.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/repository/TrustedPartyRepository.java @@ -30,7 +30,8 @@ public interface TrustedPartyRepository extends JpaRepository { - List getBySourceGatewayIsNullAndDomainIs(String domain); + List getBySourceGatewayIsNullAndDomainIsAndCertificateTypeIsIn( + String domain, List types); List getByCountryAndCertificateType(String country, TrustedPartyEntity.CertificateType type); diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/SignerInformationService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/SignerInformationService.java index 44faee95..11956bf9 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/SignerInformationService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/SignerInformationService.java @@ -70,24 +70,15 @@ public class SignerInformationService { private static final String MDC_PROP_UPLOAD_CERT_THUMBPRINT = "uploadCertThumbprint"; private static final String MDC_PROP_CSCA_CERT_THUMBPRINT = "cscaCertThumbprint"; - /** - * Method to query persistence layer for all stored non federated SignerInformation. - * - * @return List of SignerInformation - */ - public List getNonFederatedSignerInformation() { - return signerInformationRepository.getAllBySourceGatewayIsNullAndDomainIs("DCC"); - } /** - * Method to query persistence layer for SignerInformation filtered by Type. + * Method to query persistence layer for SignerInformation filtered by Type = DSC. * - * @param type type to filter for * @return List of SignerInformation */ - public List getNonFederatedSignerInformation( - SignerInformationEntity.CertificateType type) { - return signerInformationRepository.getByCertificateTypeAndSourceGatewayIsNullAndDomainIs(type, "DCC"); + public List getNonFederatedEuDscSignerInformation() { + return signerInformationRepository.getByCertificateTypeAndSourceGatewayIsNullAndDomainIs( + SignerInformationEntity.CertificateType.DSC, "DCC"); } /** diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java index 294a2dcc..023a5465 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustListService.java @@ -53,8 +53,8 @@ public class TrustListService { */ public List getTrustList() { return mergeAndConvert( - trustedPartyService.getNonFederatedTrustedParties(), - signerInformationService.getNonFederatedSignerInformation() + trustedPartyService.getNonFederatedEuDscTrustedParties(), + signerInformationService.getNonFederatedEuDscSignerInformation() ); } @@ -68,11 +68,11 @@ public List getTrustList(TrustListType type) { if (type == TrustListType.DSC) { return mergeAndConvert( Collections.emptyList(), - signerInformationService.getNonFederatedSignerInformation(SignerInformationEntity.CertificateType.DSC) + signerInformationService.getNonFederatedEuDscSignerInformation() ); } else { return mergeAndConvert( - trustedPartyService.getNonFederatedTrustedParties(map(type)), + trustedPartyService.getNonFederatedEuDscTrustedParties(map(type)), Collections.emptyList() ); } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedPartyService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedPartyService.java index 609b9562..9821e176 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedPartyService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedPartyService.java @@ -65,9 +65,11 @@ public class TrustedPartyService { * * @return List holding the found certificates. */ - public List getNonFederatedTrustedParties() { + public List getNonFederatedEuDscTrustedParties() { - return trustedPartyRepository.getBySourceGatewayIsNullAndDomainIs("DCC") + return trustedPartyRepository.getBySourceGatewayIsNullAndDomainIsAndCertificateTypeIsIn("DCC", + List.of(TrustedPartyEntity.CertificateType.UPLOAD, TrustedPartyEntity.CertificateType.AUTHENTICATION, + TrustedPartyEntity.CertificateType.CSCA)) .stream() .filter(this::validateCertificateIntegrity) .collect(Collectors.toList()); @@ -79,7 +81,7 @@ public List getNonFederatedTrustedParties() { * @param type type to filter for. * @return List holding the found certificates. */ - public List getNonFederatedTrustedParties(TrustedPartyEntity.CertificateType type) { + public List getNonFederatedEuDscTrustedParties(TrustedPartyEntity.CertificateType type) { return trustedPartyRepository.getByCertificateTypeAndSourceGatewayIsNullAndDomainIs(type, "DCC") .stream() diff --git a/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/TrustListIntegrationTest.java b/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/TrustListIntegrationTest.java index b92a6f6a..cc71884c 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/TrustListIntegrationTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/TrustListIntegrationTest.java @@ -98,7 +98,7 @@ class TrustListIntegrationTest { private static final String countryCode = "EU"; private static final String authCertSubject = "C=" + countryCode; - X509Certificate certUploadDe, certUploadEu, certCscaDe, certCscaEu, certAuthDe, certAuthEu, certDscDe, certDscEu; + X509Certificate certUploadDe, certUploadEu, certCscaDe, certCscaEu, certAuthDe, certAuthEu, certDscDe, certDscEu, certCustomEu, certTrustAnchorEu; @AfterEach public void cleanUp() { @@ -118,9 +118,14 @@ void testData() throws Exception { certAuthDe = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.AUTHENTICATION, "DE"); certAuthEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.AUTHENTICATION, "EU"); + // Add New TrustedPartyType to check that it will not be returned. + certTrustAnchorEu = trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.TRUSTANCHOR, "EU"); + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ec"); certDscDe = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "DE", "Test"); certDscEu = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EU", "Test"); + certCustomEu = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), "EU", "Test"); + signerInformationRepository.save(new SignerInformationEntity( null, @@ -146,6 +151,18 @@ void testData() throws Exception { null )); + signerInformationRepository.save(new SignerInformationEntity( + null, + ZonedDateTime.now(), + "DE", + certificateUtils.getCertThumbprint(certCustomEu), + Base64.getEncoder().encodeToString(certCustomEu.getEncoded()), + "sig3", + null, + SignerInformationEntity.CertificateType.CUSTOM, + null + )); + trustedIssuerRepository.saveAll(List.of( trustedIssuerTestHelper.createTrustedIssuer("EU", "ICAO"), trustedIssuerTestHelper.createTrustedIssuer("DE", "NONE"), @@ -173,6 +190,8 @@ void testTrustListDownloadNoFilter() throws Exception { .andExpect(c -> assertTrustListItem(c, certUploadEu, "EU", CertificateTypeDto.UPLOAD, null)) .andExpect(c -> assertTrustListItem(c, certAuthDe, "DE", CertificateTypeDto.AUTHENTICATION, null)) .andExpect(c -> assertTrustListItem(c, certAuthEu, "EU", CertificateTypeDto.AUTHENTICATION, null)) + .andExpect(c -> assertTrustListDoesNotContainItem(c, certCustomEu)) + .andExpect(c -> assertTrustListDoesNotContainItem(c, certTrustAnchorEu)) .andExpect(c -> assertTrustListLength(c, 8)); } @@ -556,6 +575,22 @@ void testTrustedIssuerEmpty() throws Exception { .andExpect(jsonPath("$", hasSize(0))); } + private void assertTrustListDoesNotContainItem(MvcResult result, X509Certificate certificate) + throws UnsupportedEncodingException, JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper() + .registerModule(new JavaTimeModule()); + List trustList = + objectMapper.readValue(result.getResponse().getContentAsString(), new TypeReference<>() { + }); + + Optional trustListOptional = trustList + .stream() + .filter(tl -> tl.getKid().equals(certificateUtils.getCertKid(certificate))) + .findFirst(); + + Assertions.assertFalse(trustListOptional.isPresent()); + } + private void assertTrustListItem(MvcResult result, X509Certificate certificate, String country, CertificateTypeDto certificateTypeDto, String signature) throws CertificateEncodingException, UnsupportedEncodingException, JsonProcessingException { diff --git a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java index b4571f9a..46d4cdc6 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedPartyTestHelper.java @@ -45,19 +45,22 @@ public class TrustedPartyTestHelper { private final Map> hashMap = Map.of( TrustedPartyEntity.CertificateType.AUTHENTICATION, new HashMap<>(), TrustedPartyEntity.CertificateType.CSCA, new HashMap<>(), - TrustedPartyEntity.CertificateType.UPLOAD, new HashMap<>() + TrustedPartyEntity.CertificateType.UPLOAD, new HashMap<>(), + TrustedPartyEntity.CertificateType.TRUSTANCHOR, new HashMap<>() ); private final Map> certificateMap = Map.of( TrustedPartyEntity.CertificateType.AUTHENTICATION, new HashMap<>(), TrustedPartyEntity.CertificateType.CSCA, new HashMap<>(), - TrustedPartyEntity.CertificateType.UPLOAD, new HashMap<>() + TrustedPartyEntity.CertificateType.UPLOAD, new HashMap<>(), + TrustedPartyEntity.CertificateType.TRUSTANCHOR, new HashMap<>() ); private final Map> privateKeyMap = Map.of( TrustedPartyEntity.CertificateType.AUTHENTICATION, new HashMap<>(), TrustedPartyEntity.CertificateType.CSCA, new HashMap<>(), - TrustedPartyEntity.CertificateType.UPLOAD, new HashMap<>() + TrustedPartyEntity.CertificateType.UPLOAD, new HashMap<>(), + TrustedPartyEntity.CertificateType.TRUSTANCHOR, new HashMap<>() ); private final TrustedPartyRepository trustedPartyRepository; From 62314702487894f1715c54e0b180f3ed900fee11 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Thu, 12 Oct 2023 15:51:50 +0200 Subject: [PATCH 26/41] feat(domain): added RACSEL-DDVC as supported domain --- src/main/resources/application.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 435e433f..33788649 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -86,6 +86,7 @@ dgc: - DCC - SHC - CRED + - RACSEL-DDVC did: enableDidGeneration: false contextMapping: From 41eba8124eda3f60acc7080939b529bf91c21510 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Sat, 14 Oct 2023 01:50:12 +0200 Subject: [PATCH 27/41] feat(did): refactored id and controller pattern of DID trustlist --- .../restapi/dto/did/DidTrustListDto.java | 2 ++ .../service/did/DidTrustListService.java | 18 ++++++++-- .../service/DidTrustListServiceTest.java | 34 ++++++++++++------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListDto.java b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListDto.java index acdb1106..db3661bf 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListDto.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/restapi/dto/did/DidTrustListDto.java @@ -21,10 +21,12 @@ package eu.europa.ec.dgc.gateway.restapi.dto.did; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import java.util.List; import lombok.Data; @Data +@JsonPropertyOrder({"@context", "id", "controller", "verificationMethod"}) public class DidTrustListDto { @JsonProperty("@context") diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index f3cb1a4f..6224b062 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -37,7 +37,9 @@ import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; import info.weboftrust.ldsignatures.signer.JsonWebSignature2020LdSigner; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; @@ -64,6 +66,10 @@ @ConditionalOnProperty("dgc.did.enableDidGeneration") public class DidTrustListService { + private static final String SEPARATOR_COLON = ":"; + + private static final String SEPARATOR_FRAGMENT = "#"; + private static final List DID_CONTEXTS = List.of( "https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/jws-2020/v1"); @@ -181,7 +187,8 @@ private String generateTrustList() throws Exception { private void addTrustListEntry(DidTrustListDto trustList, TrustedCertificateTrustList cert, - DidTrustListEntryDto.PublicKeyJwk publicKeyJwk) throws CertificateEncodingException { + DidTrustListEntryDto.PublicKeyJwk publicKeyJwk) + throws CertificateEncodingException, UnsupportedEncodingException { Optional csca = searchForIssuer(cert); if (csca.isPresent()) { @@ -191,8 +198,13 @@ private void addTrustListEntry(DidTrustListDto trustList, DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto(); trustListEntry.setType("JsonWebKey2020"); - trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + cert.getKid()); - trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()); + trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + + SEPARATOR_COLON + + cert.getCountry() + + SEPARATOR_FRAGMENT + + URLEncoder.encode(cert.getKid(), StandardCharsets.UTF_8)); + trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix() + + SEPARATOR_COLON + cert.getCountry()); trustListEntry.setPublicKeyJwk(publicKeyJwk); trustList.getVerificationMethod().add(trustListEntry); diff --git a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java index eac6e628..b2f7da1c 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java @@ -37,8 +37,10 @@ import eu.europa.ec.dgc.gateway.testdata.TrustedIssuerTestHelper; import eu.europa.ec.dgc.gateway.testdata.TrustedPartyTestHelper; import eu.europa.ec.dgc.utils.CertificateUtils; -import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.security.KeyPairGenerator; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; @@ -50,13 +52,13 @@ import java.util.Base64; import java.util.LinkedHashMap; import java.util.List; + +import foundation.identity.jsonld.JsonLDObject; import lombok.Data; import lombok.Getter; import lombok.Setter; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; @@ -218,12 +220,12 @@ void testTrustList(boolean isEcAlgorithm) throws Exception { Assertions.assertEquals("b", parsed.getController()); Assertions.assertEquals(6, parsed.getVerificationMethod().size()); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + certDscDeKid), - certDscDeKid, certDscDe, certCscaDe); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "ckid2"), - "kid2", certDscEu, certCscaEu); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "ckid3"), - "kid3", federatedCertDscEx, null); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":DE" + "#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "DE"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c:EU#kid2"), + "kid2", certDscEu, certCscaEu, "EU"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c:EX#kid3"), + "kid3", federatedCertDscEx, null, "EX"); Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:DE:issuer")); Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:EU:issuer")); @@ -238,8 +240,14 @@ void testTrustList(boolean isEcAlgorithm) throws Exception { Assertions.assertEquals("e", parsed.getProof().getVerificationMethod()); Assertions.assertNotNull(parsed.getProof().getJws()); Assertions.assertNotEquals("", parsed.getProof().getJws()); + + //JSON should start with "@context" due to https://www.w3.org/TR/json-ld11-streaming/#key-ordering-required + String json = JsonLDObject.fromJson(objectMapper.writeValueAsString(parsed)).toJson(); + String first10Characters = json.substring(0, Math.min(10, json.length())); + Assertions.assertTrue(first10Characters.contains("@context")); } + private Object getVerificationMethodByKid(List verificationMethods, String kid) { return verificationMethods.stream() .map(entry -> (LinkedHashMap) entry) @@ -248,12 +256,12 @@ private Object getVerificationMethodByKid(List verificationMethods, Stri .orElseGet(() -> Assertions.fail("Could not find VerificationMethod with KID " + kid)); } - private void assertVerificationMethod(Object in, String kid, X509Certificate dsc, X509Certificate csca) - throws CertificateEncodingException { + private void assertVerificationMethod(Object in, String kid, X509Certificate dsc, X509Certificate csca, String country) + throws CertificateEncodingException, UnsupportedEncodingException { LinkedHashMap jsonNode = (LinkedHashMap) in; Assertions.assertEquals("JsonWebKey2020", jsonNode.get("type")); - Assertions.assertEquals("d", jsonNode.get("controller")); - Assertions.assertEquals("c" + kid, jsonNode.get("id")); + Assertions.assertEquals("d" + ":" + country, jsonNode.get("controller")); + Assertions.assertEquals("c" + ":" + country + "#" + URLEncoder.encode(kid, StandardCharsets.UTF_8), jsonNode.get("id")); LinkedHashMap publicKeyJwk = (LinkedHashMap) jsonNode.get("publicKeyJwk"); From bc616ee96729bab5fa5a8845c2c40315b615820a Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Wed, 18 Oct 2023 13:33:35 +0200 Subject: [PATCH 28/41] feat(trsuted-issuer): removed uuid of trusted issuer hash --- .../dgc/gateway/service/TrustedIssuerService.java | 14 +++++++------- .../gateway/testdata/TrustedIssuerTestHelper.java | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java index 737be48c..82eb19aa 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java @@ -162,7 +162,8 @@ private boolean validateTrustedIssuerIntegrity(TrustedIssuerEntity trustedIssuer // verify signature SignedStringMessageParser parser = new SignedStringMessageParser( trustedIssuerEntity.getSignature(), - Base64.getEncoder().encodeToString(getHashData(trustedIssuerEntity).getBytes(StandardCharsets.UTF_8))); + Base64.getEncoder().encodeToString( + getHashData(trustedIssuerEntity).getBytes(StandardCharsets.UTF_8))); if (parser.getParserState() != SignedMessageParser.ParserState.SUCCESS) { DgcMdc.put(MDC_PROP_PARSER_STATE, parser.getParserState().name()); @@ -227,12 +228,11 @@ public TrustedIssuerEntity addFederatedTrustedIssuer(String country, return trustedIssuerEntity; } - private String getHashData(TrustedIssuerEntity entity) { - return entity.getUuid() + HASH_SEPARATOR - + entity.getCountry() + HASH_SEPARATOR - + entity.getName() + HASH_SEPARATOR - + entity.getUrl() + HASH_SEPARATOR - + entity.getUrlType().name() + HASH_SEPARATOR; + return entity.getCountry() + HASH_SEPARATOR + + entity.getName() + HASH_SEPARATOR + + entity.getUrl() + HASH_SEPARATOR + + entity.getUrlType().name() + HASH_SEPARATOR; } } + diff --git a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java index 5a79bcdc..0e03500f 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java @@ -51,8 +51,7 @@ public TrustedIssuerEntity createTrustedIssuer(final String country, final Strin } private String getHashData(TrustedIssuerEntity entity) { - return entity.getUuid() + ";" - + entity.getCountry() + ";" + return entity.getCountry() + ";" + entity.getName() + ";" + entity.getUrl() + ";" + entity.getUrlType().name() + ";"; From a6be39fa6419715cdc3c46d533a96fd5a3490d3b Mon Sep 17 00:00:00 2001 From: Andreas Scheibal Date: Wed, 18 Oct 2023 14:19:58 +0200 Subject: [PATCH 29/41] chore: update azure client bom --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 55ec308f..42e5680a 100644 --- a/pom.xml +++ b/pom.xml @@ -137,7 +137,7 @@ com.azure azure-sdk-bom - 1.2.8 + 1.2.17 pom import From c5a9f8f92200569fe1f6fb8c52cc7ff2682aa4de Mon Sep 17 00:00:00 2001 From: Felix Dittrich <31076102+f11h@users.noreply.github.com> Date: Wed, 18 Oct 2023 15:58:02 +0200 Subject: [PATCH 30/41] Update suppressions.xml --- owasp/suppressions.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/owasp/suppressions.xml b/owasp/suppressions.xml index 6cd96e52..5ee5e71e 100644 --- a/owasp/suppressions.xml +++ b/owasp/suppressions.xml @@ -38,4 +38,9 @@ CVE-2020-8908 CVE-2023-1370 + + No Fix available + CVE-2023-36414 + CVE-2023-36415 + From 7071e863407259be428a425281bb39820ae4691a Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 18 Oct 2023 14:12:38 +0000 Subject: [PATCH 31/41] Update License Header and Third Party Notices --- THIRD-PARTY.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/THIRD-PARTY.md b/THIRD-PARTY.md index 9c3f0910..2a3dc66b 100644 --- a/THIRD-PARTY.md +++ b/THIRD-PARTY.md @@ -14,13 +14,14 @@ ThirdParty Licenses | ch.qos.logback:logback-classic:1.4.8 | Eclipse Public License - v 1.0 GNU Lesser General Public License | | ch.qos.logback:logback-core:1.4.8 | Eclipse Public License - v 1.0 GNU Lesser General Public License | | com.apicatalog:titanium-json-ld:1.1.0 | Apache License, Version 2.0 | -| com.azure:azure-core:1.34.0 | The MIT License (MIT) | -| com.azure:azure-core-http-netty:1.12.7 | The MIT License (MIT) | -| com.azure:azure-identity:1.7.0 | The MIT License (MIT) | -| com.azure:azure-security-keyvault-keys:4.5.2 | The MIT License (MIT) | -| com.azure:azure-storage-blob:12.20.1 | The MIT License (MIT) | -| com.azure:azure-storage-common:12.19.1 | The MIT License (MIT) | -| com.azure:azure-storage-internal-avro:12.5.1 | The MIT License (MIT) | +| com.azure:azure-core:1.43.0 | The MIT License (MIT) | +| com.azure:azure-core-http-netty:1.13.7 | The MIT License (MIT) | +| com.azure:azure-identity:1.10.1 | The MIT License (MIT) | +| com.azure:azure-json:1.1.0 | The MIT License (MIT) | +| com.azure:azure-security-keyvault-keys:4.7.0 | The MIT License (MIT) | +| com.azure:azure-storage-blob:12.24.0 | The MIT License (MIT) | +| com.azure:azure-storage-common:12.23.0 | The MIT License (MIT) | +| com.azure:azure-storage-internal-avro:12.9.0 | The MIT License (MIT) | | com.damnhandy:handy-uri-templates:2.1.8 | The Apache Software License, Version 2.0 | | com.danubetech:key-formats-java:1.2.0 | Unknown license | | com.fasterxml:classmate:1.5.1 | Apache License, Version 2.0 | @@ -32,7 +33,7 @@ ThirdParty Licenses | com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.3 | The Apache Software License, Version 2.0 | | com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.3 | The Apache Software License, Version 2.0 | | com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.3 | The Apache Software License, Version 2.0 | -| com.fasterxml.woodstox:woodstox-core:6.4.0 | The Apache License, Version 2.0 | +| com.fasterxml.woodstox:woodstox-core:6.5.0 | The Apache License, Version 2.0 | | com.github.everit-org.json-schema:org.everit.json.schema:1.14.2 | Apache License, Version 2.0 | | com.github.jnr:jffi:1.2.9 | The Apache Software License, Version 2.0 | | com.github.jnr:jnr-ffi:2.0.5 | The Apache Software License, Version 2.0 | @@ -50,13 +51,13 @@ ThirdParty Licenses | com.google.re2j:re2j:1.6 | Go License | | com.h2database:h2:2.2.220 | EPL 1.0 MPL 2.0 | | com.jayway.jsonpath:json-path:2.7.0 | The Apache Software License, Version 2.0 | -| com.microsoft.azure:msal4j:1.13.3 | MIT License | -| com.microsoft.azure:msal4j-persistence-extension:1.1.0 | MIT License | +| com.microsoft.azure:msal4j:1.13.9 | MIT License | +| com.microsoft.azure:msal4j-persistence-extension:1.2.0 | MIT License | | com.mysql:mysql-connector-j:8.0.33 | The GNU General Public License, v2 with Universal FOSS Exception, v1.0 | | com.nimbusds:content-type:2.2 | The Apache Software License, Version 2.0 | -| com.nimbusds:lang-tag:1.6 | The Apache Software License, Version 2.0 | +| com.nimbusds:lang-tag:1.7 | The Apache Software License, Version 2.0 | | com.nimbusds:nimbus-jose-jwt:9.9 | The Apache Software License, Version 2.0 | -| com.nimbusds:oauth2-oidc-sdk:9.35 | Apache License, version 2.0 | +| com.nimbusds:oauth2-oidc-sdk:10.7.1 | Apache License, version 2.0 | | com.opencsv:opencsv:5.7.1 | Apache 2 | | com.squareup.okhttp3:okhttp:4.10.0 | The Apache Software License, Version 2.0 | | com.squareup.okio:okio-jvm:3.0.0 | The Apache Software License, Version 2.0 | @@ -128,7 +129,7 @@ ThirdParty Licenses | joda-time:joda-time:2.10.2 | Apache 2 | | net.bytebuddy:byte-buddy:1.12.23 | Apache License, Version 2.0 | | net.bytebuddy:byte-buddy-agent:1.12.23 | Apache License, Version 2.0 | -| net.java.dev.jna:jna:5.5.0 | Apache License v2.0 LGPL, version 2.1 | +| net.java.dev.jna:jna:5.13.0 | Apache-2.0 LGPL-2.1-or-later | | net.java.dev.jna:jna-platform:5.6.0 | Apache License v2.0 LGPL, version 2.1 | | net.javacrumbs.shedlock:shedlock-core:5.2.0 | The Apache Software License, Version 2.0 | | net.javacrumbs.shedlock:shedlock-provider-jdbc-template:5.2.0 | The Apache Software License, Version 2.0 | From 06c01d7d023bebd1f3b6a33ab99c71bcfc5589c0 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Wed, 18 Oct 2023 16:50:17 +0200 Subject: [PATCH 32/41] fix(trusted-issuer): removed hash seperator at the end --- .../eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java | 2 +- .../europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java index 82eb19aa..a2d9e180 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/TrustedIssuerService.java @@ -232,7 +232,7 @@ private String getHashData(TrustedIssuerEntity entity) { return entity.getCountry() + HASH_SEPARATOR + entity.getName() + HASH_SEPARATOR + entity.getUrl() + HASH_SEPARATOR - + entity.getUrlType().name() + HASH_SEPARATOR; + + entity.getUrlType().name(); } } diff --git a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java index 0e03500f..e5d69ff0 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/testdata/TrustedIssuerTestHelper.java @@ -54,6 +54,6 @@ private String getHashData(TrustedIssuerEntity entity) { return entity.getCountry() + ";" + entity.getName() + ";" + entity.getUrl() + ";" - + entity.getUrlType().name() + ";"; + + entity.getUrlType().name(); } } From a38aaa60732f0995d25c26fa6cc226d699e1b516 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 23 Oct 2023 15:24:19 +0200 Subject: [PATCH 33/41] feat(did): added did generation per country (WIP) --- .../gateway/service/did/AzureDidUploader.java | 39 +++++++++++-- .../service/did/DidTrustListService.java | 58 +++++++++++++++++-- .../dgc/gateway/service/did/DidUploader.java | 2 + .../gateway/service/did/DummyDidUploader.java | 5 ++ .../service/DidTrustListServiceTest.java | 12 ++-- 5 files changed, 99 insertions(+), 17 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/AzureDidUploader.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/AzureDidUploader.java index 47507e7c..393a89ca 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/AzureDidUploader.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/AzureDidUploader.java @@ -32,6 +32,7 @@ import com.azure.storage.blob.models.BlobHttpHeaders; import eu.europa.ec.dgc.gateway.config.DgcConfigProperties; import java.net.InetSocketAddress; +import java.text.MessageFormat; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.MediaType; @@ -42,7 +43,7 @@ @Slf4j public class AzureDidUploader implements DidUploader { - private final BlobClient blobClient; + private final BlobServiceClient blobServiceClient; private final DgcConfigProperties dgcConfigProperties; @@ -64,7 +65,7 @@ public AzureDidUploader(DgcConfigProperties dgcConfigProperties) { HttpClient httpClient = HttpClient.createDefault(httpClientOptions); - BlobServiceClient blobServiceClient = new BlobServiceClientBuilder() + blobServiceClient = new BlobServiceClientBuilder() .httpClient(httpClient) .endpoint(dgcConfigProperties.getDid().getAzure().getBlobEndpoint()) .credential(new ClientSecretCredentialBuilder() @@ -75,10 +76,24 @@ public AzureDidUploader(DgcConfigProperties dgcConfigProperties) { .build()) .buildClient(); - BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient( - dgcConfigProperties.getDid().getAzure().getBlobContainer()); + } - blobClient = blobContainerClient.getBlobClient(dgcConfigProperties.getDid().getAzure().getBlobName()); + /** + * Setup container specific BlobClient. + * @param subContainer the name of the container (will be used in lowercase) + */ + public BlobClient getBlobContainerClientForBlobContainer(String subContainer) { + BlobContainerClient blobContainerClient; + if (subContainer == null) { + blobContainerClient = blobServiceClient.getBlobContainerClient( + dgcConfigProperties.getDid().getAzure().getBlobContainer()); + } else { + blobContainerClient = blobServiceClient.getBlobContainerClient( + MessageFormat.format("{0}/{1}", + dgcConfigProperties.getDid().getAzure().getBlobContainer(), + subContainer.toLowerCase())); + } + return blobContainerClient.getBlobClient(dgcConfigProperties.getDid().getAzure().getBlobName()); } @Override @@ -88,6 +103,20 @@ public void uploadDid(byte[] content) { dgcConfigProperties.getDid().getAzure().getBlobContainer(), dgcConfigProperties.getDid().getAzure().getBlobName()); + BlobClient blobClient = getBlobContainerClientForBlobContainer(null); + blobClient.upload(BinaryData.fromBytes(content), true); + blobClient.setHttpHeaders(new BlobHttpHeaders().setContentType(MediaType.APPLICATION_JSON_VALUE)); + log.info("Upload successful"); + } + + @Override + public void uploadDid(String subContainer, byte[] content) { + log.info("Uploading {} bytes as {}{}/{} to Azure BLOB Storage", content.length, + dgcConfigProperties.getDid().getAzure().getBlobEndpoint(), + dgcConfigProperties.getDid().getAzure().getBlobContainer(), + dgcConfigProperties.getDid().getAzure().getBlobName()); + + BlobClient blobClient = getBlobContainerClientForBlobContainer(subContainer); blobClient.upload(BinaryData.fromBytes(content), true); blobClient.setHttpHeaders(new BlobHttpHeaders().setContentType(MediaType.APPLICATION_JSON_VALUE)); log.info("Upload successful"); diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 6224b062..109c9ef3 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -32,6 +32,7 @@ import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListEntryDto; import eu.europa.ec.dgc.gateway.service.TrustListService; import eu.europa.ec.dgc.gateway.service.TrustedIssuerService; +import eu.europa.ec.dgc.gateway.service.TrustedPartyService; import foundation.identity.jsonld.ConfigurableDocumentLoader; import foundation.identity.jsonld.JsonLDObject; import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; @@ -50,7 +51,9 @@ 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.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -86,6 +89,8 @@ public class DidTrustListService { private final ObjectMapper objectMapper; + private final TrustedPartyService trustedPartyService; + /** * Create and upload DID Document holding Uploaded DSC and Trusted Issuer. */ @@ -94,7 +99,7 @@ public class DidTrustListService { public void job() { String trustList; try { - trustList = generateTrustList(); + trustList = generateTrustList(null); } catch (Exception e) { log.error("Failed to generate DID-TrustList: {}", e.getMessage()); return; @@ -106,10 +111,51 @@ public void job() { log.error("Failed to Upload DID-TrustList: {}", e.getMessage()); return; } + + List countries = trustedPartyService.getCountryList(); + List countryAsList = null; + String countryTrustList = null; + for (String country : countries) { + String countryAsSubcontainer = getCountryAsLowerCaseAlpha3(country); + if (countryAsSubcontainer != null) { + countryAsList = List.of(country); + try { + countryTrustList = generateTrustList(countryAsList); + } catch (Exception e) { + log.error("Failed to generate DID-TrustList for country {} : {}", country, e.getMessage()); + return; + } + + try { + didUploader.uploadDid(countryAsSubcontainer, countryTrustList.getBytes(StandardCharsets.UTF_8)); + } catch (Exception e) { + log.error("Failed to Upload DID-TrustList for country {} : {}", country, e.getMessage()); + return; + } + } + } + log.info("Finished DID Export Process"); } - private String generateTrustList() throws Exception { + private String getCountryAsLowerCaseAlpha3(String country) { + String countryLowerCaseAlpha3 = null; + if (country != null & country.length() == 2) { + Locale locale = new Locale("en", country); + try { + countryLowerCaseAlpha3 = locale.getISO3Country().toLowerCase(locale); + } catch (MissingResourceException e) { + countryLowerCaseAlpha3 = ("X" + country).toLowerCase(); + //TODO: replace with mapping config for virtual countries + log.error("Country Code to alpha 3 conversion issue for country {} : {}", + country, + e.getMessage()); + } + } + return countryLowerCaseAlpha3; + } + + private String generateTrustList(List countries) throws Exception { DidTrustListDto trustList = new DidTrustListDto(); trustList.setContext(DID_CONTEXTS); trustList.setId(configProperties.getDid().getDidId()); @@ -120,7 +166,7 @@ private String generateTrustList() throws Exception { // Add DSC List certs = trustListService.getTrustedCertificateTrustList( SignerInformationEntity.CertificateType.stringValues(), - null, + countries, null, configProperties.getDid().getIncludeFederated() ); @@ -146,7 +192,7 @@ private String generateTrustList() throws Exception { // Add TrustedIssuer trustedIssuerService.search( - null, null, configProperties.getDid().getIncludeFederated()).stream() + null, countries, configProperties.getDid().getIncludeFederated()).stream() .filter(trustedIssuer -> trustedIssuer.getUrlType() == TrustedIssuerEntity.UrlType.DID) .forEach(trustedIssuer -> trustList.getVerificationMethod().add(trustedIssuer.getUrl())); @@ -200,11 +246,11 @@ private void addTrustListEntry(DidTrustListDto trustList, trustListEntry.setType("JsonWebKey2020"); trustListEntry.setId(configProperties.getDid().getTrustListIdPrefix() + SEPARATOR_COLON - + cert.getCountry() + + getCountryAsLowerCaseAlpha3(cert.getCountry()) + SEPARATOR_FRAGMENT + URLEncoder.encode(cert.getKid(), StandardCharsets.UTF_8)); trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix() - + SEPARATOR_COLON + cert.getCountry()); + + SEPARATOR_COLON + getCountryAsLowerCaseAlpha3(cert.getCountry())); trustListEntry.setPublicKeyJwk(publicKeyJwk); trustList.getVerificationMethod().add(trustListEntry); diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidUploader.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidUploader.java index e79271b7..4d74bb60 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidUploader.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidUploader.java @@ -24,4 +24,6 @@ public interface DidUploader { void uploadDid(byte[] content); + void uploadDid(String subContainer, byte[] content); + } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DummyDidUploader.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DummyDidUploader.java index 4949b519..2b3478a8 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DummyDidUploader.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DummyDidUploader.java @@ -34,4 +34,9 @@ public void uploadDid(byte[] content) { log.info("Uploaded {} bytes", content.length); } + @Override + public void uploadDid(String subContainer, byte[] content) { + log.info("Uploaded {} bytes to subContainer {}", content.length, subContainer); + } + } diff --git a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java index b2f7da1c..d52fb579 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/service/DidTrustListServiceTest.java @@ -220,12 +220,12 @@ void testTrustList(boolean isEcAlgorithm) throws Exception { Assertions.assertEquals("b", parsed.getController()); Assertions.assertEquals(6, parsed.getVerificationMethod().size()); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":DE" + "#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), - certDscDeKid, certDscDe, certCscaDe, "DE"); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c:EU#kid2"), - "kid2", certDscEu, certCscaEu, "EU"); - assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c:EX#kid3"), - "kid3", federatedCertDscEx, null, "EX"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":deu" + "#" + URLEncoder.encode(certDscDeKid, StandardCharsets.UTF_8)), + certDscDeKid, certDscDe, certCscaDe, "deu"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c:xeu#kid2"), + "kid2", certDscEu, certCscaEu, "xeu"); + assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c:xex#kid3"), + "kid3", federatedCertDscEx, null, "xex"); Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:DE:issuer")); Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:EU:issuer")); From 879434e2ff4cbf01f4ff1d935a9b2c405b2380d7 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 23 Oct 2023 16:02:34 +0200 Subject: [PATCH 34/41] fix(tests): daylight saving issue --- .../restapi/controller/ValidationRuleIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/ValidationRuleIntegrationTest.java b/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/ValidationRuleIntegrationTest.java index a59df119..9678717e 100644 --- a/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/ValidationRuleIntegrationTest.java +++ b/src/test/java/eu/europa/ec/dgc/gateway/restapi/controller/ValidationRuleIntegrationTest.java @@ -603,7 +603,7 @@ void testValidationTimestamps3() throws Exception { validationRule.setValidFrom(ZonedDateTime.now().plus(3, ChronoUnit.DAYS)); validationRule.setValidTo(ZonedDateTime.now() .plus(6, ChronoUnit.DAYS) - .minus(1, ChronoUnit.SECONDS)); + .minus(2, ChronoUnit.HOURS)); String payload = new SignedStringMessageBuilder() .withSigningCertificate(certificateUtils.convertCertificate(signerCertificate), signerPrivateKey) From 01ba469d3208cef1c9cf1bf709288d01a6301a4b Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 23 Oct 2023 16:10:22 +0200 Subject: [PATCH 35/41] fix(did): generate each 5 minutes for DEV deployment --- .../europa/ec/dgc/gateway/service/did/DidTrustListService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 109c9ef3..d3a84c93 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -94,7 +94,7 @@ public class DidTrustListService { /** * Create and upload DID Document holding Uploaded DSC and Trusted Issuer. */ - @Scheduled(cron = "0 0 * * * *") + @Scheduled(cron = "* */5 * * * *") @SchedulerLock(name = "didTrustListGenerator") public void job() { String trustList; From e32ee3f4968541563e74f5455d265c97b94a40c6 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Mon, 23 Oct 2023 17:44:28 +0200 Subject: [PATCH 36/41] fix(did): generate each 5 minutes for DEV deployment --- .../service/did/DidTrustListService.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index d3a84c93..fbc6970e 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -113,24 +113,23 @@ public void job() { } List countries = trustedPartyService.getCountryList(); - List countryAsList = null; - String countryTrustList = null; + for (String country : countries) { + String countryTrustList = null; + List countryAsList = List.of(country); String countryAsSubcontainer = getCountryAsLowerCaseAlpha3(country); if (countryAsSubcontainer != null) { - countryAsList = List.of(country); try { countryTrustList = generateTrustList(countryAsList); } catch (Exception e) { log.error("Failed to generate DID-TrustList for country {} : {}", country, e.getMessage()); - return; + continue; } try { didUploader.uploadDid(countryAsSubcontainer, countryTrustList.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { log.error("Failed to Upload DID-TrustList for country {} : {}", country, e.getMessage()); - return; } } } @@ -162,6 +161,14 @@ private String generateTrustList(List countries) throws Exception { trustList.setController(configProperties.getDid().getDidController()); trustList.setVerificationMethod(new ArrayList<>()); + if (countries != null && !countries.isEmpty()) { + trustList.setId(configProperties.getDid().getDidId() + + SEPARATOR_COLON + + getCountryAsLowerCaseAlpha3(countries.get(0))); + trustList.setController(configProperties.getDid().getDidController() + + SEPARATOR_COLON + + getCountryAsLowerCaseAlpha3(countries.get(0))); + } // Add DSC List certs = trustListService.getTrustedCertificateTrustList( From bc30d25aaafedb24bdd852da4d68d756a58d9fa3 Mon Sep 17 00:00:00 2001 From: Andreas Scheibal Date: Mon, 23 Oct 2023 22:37:50 +0200 Subject: [PATCH 37/41] feat: configurable cronjob --- .../service/did/DidTrustListService.java | 45 ++++++++++--------- src/main/resources/application.yml | 2 + 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index fbc6970e..30bd91c1 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -20,23 +20,6 @@ package eu.europa.ec.dgc.gateway.service.did; -import com.apicatalog.jsonld.document.JsonDocument; -import com.danubetech.keyformats.crypto.ByteSigner; -import com.fasterxml.jackson.databind.ObjectMapper; -import eu.europa.ec.dgc.gateway.config.DgcConfigProperties; -import eu.europa.ec.dgc.gateway.entity.SignerInformationEntity; -import eu.europa.ec.dgc.gateway.entity.TrustedIssuerEntity; -import eu.europa.ec.dgc.gateway.entity.TrustedPartyEntity; -import eu.europa.ec.dgc.gateway.model.TrustedCertificateTrustList; -import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListDto; -import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListEntryDto; -import eu.europa.ec.dgc.gateway.service.TrustListService; -import eu.europa.ec.dgc.gateway.service.TrustedIssuerService; -import eu.europa.ec.dgc.gateway.service.TrustedPartyService; -import foundation.identity.jsonld.ConfigurableDocumentLoader; -import foundation.identity.jsonld.JsonLDObject; -import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; -import info.weboftrust.ldsignatures.signer.JsonWebSignature2020LdSigner; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -55,14 +38,34 @@ import java.util.Map; import java.util.MissingResourceException; import java.util.Optional; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; + import org.jetbrains.annotations.NotNull; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import com.apicatalog.jsonld.document.JsonDocument; +import com.danubetech.keyformats.crypto.ByteSigner; +import com.fasterxml.jackson.databind.ObjectMapper; + +import eu.europa.ec.dgc.gateway.config.DgcConfigProperties; +import eu.europa.ec.dgc.gateway.entity.SignerInformationEntity; +import eu.europa.ec.dgc.gateway.entity.TrustedIssuerEntity; +import eu.europa.ec.dgc.gateway.entity.TrustedPartyEntity; +import eu.europa.ec.dgc.gateway.model.TrustedCertificateTrustList; +import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListDto; +import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListEntryDto; +import eu.europa.ec.dgc.gateway.service.TrustListService; +import eu.europa.ec.dgc.gateway.service.TrustedIssuerService; +import eu.europa.ec.dgc.gateway.service.TrustedPartyService; +import foundation.identity.jsonld.ConfigurableDocumentLoader; +import foundation.identity.jsonld.JsonLDObject; +import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; +import info.weboftrust.ldsignatures.signer.JsonWebSignature2020LdSigner; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; + @Slf4j @Service @RequiredArgsConstructor @@ -94,7 +97,7 @@ public class DidTrustListService { /** * Create and upload DID Document holding Uploaded DSC and Trusted Issuer. */ - @Scheduled(cron = "* */5 * * * *") + @Scheduled(cron = "${dgc.trustlist.cron}") @SchedulerLock(name = "didTrustListGenerator") public void job() { String trustList; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 33788649..2eafb6d0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -87,6 +87,8 @@ dgc: - SHC - CRED - RACSEL-DDVC + trustlist: + cron: "* */5 * * * *" did: enableDidGeneration: false contextMapping: From 1b0509a77494c3175d98b9f7ba3def049c28cff2 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Tue, 24 Oct 2023 09:54:56 +0200 Subject: [PATCH 38/41] fix(did): added temporary workaround for virtual country mapping (XL) --- .../service/did/DidTrustListService.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 30bd91c1..e94bf825 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -20,6 +20,23 @@ package eu.europa.ec.dgc.gateway.service.did; +import com.apicatalog.jsonld.document.JsonDocument; +import com.danubetech.keyformats.crypto.ByteSigner; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.europa.ec.dgc.gateway.config.DgcConfigProperties; +import eu.europa.ec.dgc.gateway.entity.SignerInformationEntity; +import eu.europa.ec.dgc.gateway.entity.TrustedIssuerEntity; +import eu.europa.ec.dgc.gateway.entity.TrustedPartyEntity; +import eu.europa.ec.dgc.gateway.model.TrustedCertificateTrustList; +import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListDto; +import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListEntryDto; +import eu.europa.ec.dgc.gateway.service.TrustListService; +import eu.europa.ec.dgc.gateway.service.TrustedIssuerService; +import eu.europa.ec.dgc.gateway.service.TrustedPartyService; +import foundation.identity.jsonld.ConfigurableDocumentLoader; +import foundation.identity.jsonld.JsonLDObject; +import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; +import info.weboftrust.ldsignatures.signer.JsonWebSignature2020LdSigner; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -38,33 +55,15 @@ import java.util.Map; import java.util.MissingResourceException; import java.util.Optional; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; import org.jetbrains.annotations.NotNull; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import com.apicatalog.jsonld.document.JsonDocument; -import com.danubetech.keyformats.crypto.ByteSigner; -import com.fasterxml.jackson.databind.ObjectMapper; -import eu.europa.ec.dgc.gateway.config.DgcConfigProperties; -import eu.europa.ec.dgc.gateway.entity.SignerInformationEntity; -import eu.europa.ec.dgc.gateway.entity.TrustedIssuerEntity; -import eu.europa.ec.dgc.gateway.entity.TrustedPartyEntity; -import eu.europa.ec.dgc.gateway.model.TrustedCertificateTrustList; -import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListDto; -import eu.europa.ec.dgc.gateway.restapi.dto.did.DidTrustListEntryDto; -import eu.europa.ec.dgc.gateway.service.TrustListService; -import eu.europa.ec.dgc.gateway.service.TrustedIssuerService; -import eu.europa.ec.dgc.gateway.service.TrustedPartyService; -import foundation.identity.jsonld.ConfigurableDocumentLoader; -import foundation.identity.jsonld.JsonLDObject; -import info.weboftrust.ldsignatures.jsonld.LDSecurityKeywords; -import info.weboftrust.ldsignatures.signer.JsonWebSignature2020LdSigner; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; @Slf4j @Service @@ -142,12 +141,15 @@ public void job() { private String getCountryAsLowerCaseAlpha3(String country) { String countryLowerCaseAlpha3 = null; - if (country != null & country.length() == 2) { + if (country != null && country.length() == 2) { Locale locale = new Locale("en", country); try { countryLowerCaseAlpha3 = locale.getISO3Country().toLowerCase(locale); } catch (MissingResourceException e) { countryLowerCaseAlpha3 = ("X" + country).toLowerCase(); + if (country.equalsIgnoreCase("XL")) { + countryLowerCaseAlpha3 = "xcl"; + } //TODO: replace with mapping config for virtual countries log.error("Country Code to alpha 3 conversion issue for country {} : {}", country, From 86410d80d1106c5e00ad600bf8d79ef6b59262b9 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Tue, 24 Oct 2023 16:20:40 +0200 Subject: [PATCH 39/41] fix(did): added virtual country mapping as config --- .../gateway/config/DgcConfigProperties.java | 8 +++++ .../service/did/DidTrustListService.java | 29 ++++++++++++------- src/main/resources/application.yml | 6 ++++ src/test/resources/application.yml | 8 +++++ 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/config/DgcConfigProperties.java b/src/main/java/eu/europa/ec/dgc/gateway/config/DgcConfigProperties.java index 5c650986..65c2574b 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/config/DgcConfigProperties.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/config/DgcConfigProperties.java @@ -52,6 +52,8 @@ public class DgcConfigProperties { private CloudmersiveConfig cloudmersive = new CloudmersiveConfig(); + private CountryCodeMap countryCodeMap = new CountryCodeMap(); + @Getter @Setter public static class DidConfig { @@ -170,4 +172,10 @@ public static class Federation { public static class SignerInformation { private int deleteThreshold = 14; } + + @Getter + @Setter + public static class CountryCodeMap { + private Map virtualCountries = new HashMap<>(); + } } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index e94bf825..39a6fa91 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -141,21 +141,28 @@ public void job() { private String getCountryAsLowerCaseAlpha3(String country) { String countryLowerCaseAlpha3 = null; + if (country != null && country.length() == 2) { - Locale locale = new Locale("en", country); - try { - countryLowerCaseAlpha3 = locale.getISO3Country().toLowerCase(locale); - } catch (MissingResourceException e) { - countryLowerCaseAlpha3 = ("X" + country).toLowerCase(); - if (country.equalsIgnoreCase("XL")) { - countryLowerCaseAlpha3 = "xcl"; + + countryLowerCaseAlpha3 = configProperties.getCountryCodeMap() + .getVirtualCountries().get(country); + + + if (countryLowerCaseAlpha3 == null) { + Locale locale = new Locale("en", country); + try { + countryLowerCaseAlpha3 = locale.getISO3Country().toLowerCase(locale); + } catch (MissingResourceException e) { + log.error("Country Code to alpha 3 conversion issue for country {} : {}", + country, + e.getMessage()); } - //TODO: replace with mapping config for virtual countries - log.error("Country Code to alpha 3 conversion issue for country {} : {}", - country, - e.getMessage()); + } else { + countryLowerCaseAlpha3 = countryLowerCaseAlpha3.toLowerCase(); } + } + return countryLowerCaseAlpha3; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2eafb6d0..ba197cfa 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -94,6 +94,12 @@ dgc: contextMapping: "[https://www.w3.org/ns/did/v1]": did_v1.json "[https://w3id.org/security/suites/jws-2020/v1]": jws-2020_v1.json + countryCodeMap: + virtualCountries: + XA: XXA + XB: XXB + XO: XXO + XL: XCL cloudmersive: apiKey: 0a0a0a0a-0a0a-0a0a-0a0a-0a0a0a0a0a0a url: https://api.cloudmersive.com diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 70f3dd91..d0efa1ae 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -58,3 +58,11 @@ dgc: apiKey: 0a0a0a0a-0a0a-0a0a-0a0a-0a0a0a0a0a0a enabled: true url: https://api.cloudmersive.com + countryCodeMap: + virtualCountries: + XA: XXA + XB: XXB + XO: XXO + XL: XCL + EU: XEU + EX: XEX \ No newline at end of file From 7b39a15df60054ff7b698538a2b1f0c1d97cb205 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Fri, 27 Oct 2023 12:10:47 +0200 Subject: [PATCH 40/41] Code Review Remarks --- .../service/did/DidTrustListService.java | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index 39a6fa91..d10389ec 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -64,7 +64,6 @@ import org.springframework.stereotype.Service; - @Slf4j @Service @RequiredArgsConstructor @@ -140,30 +139,24 @@ public void job() { } private String getCountryAsLowerCaseAlpha3(String country) { - String countryLowerCaseAlpha3 = null; - - if (country != null && country.length() == 2) { - - countryLowerCaseAlpha3 = configProperties.getCountryCodeMap() - .getVirtualCountries().get(country); + if (country == null || country.length() != 2 && country.length() != 3) { + return null; + } else if (country.length() == 3) { + return country; + } + return configProperties.getCountryCodeMap().getVirtualCountries() + .compute(country, (alpha2, alpha3) -> { + if (alpha3 != null) return alpha3.toLowerCase(); - if (countryLowerCaseAlpha3 == null) { - Locale locale = new Locale("en", country); try { - countryLowerCaseAlpha3 = locale.getISO3Country().toLowerCase(locale); + return new Locale("en", alpha2).getISO3Country().toLowerCase(); } catch (MissingResourceException e) { log.error("Country Code to alpha 3 conversion issue for country {} : {}", - country, - e.getMessage()); + country, e.getMessage()); + return null; } - } else { - countryLowerCaseAlpha3 = countryLowerCaseAlpha3.toLowerCase(); - } - - } - - return countryLowerCaseAlpha3; + }); } private String generateTrustList(List countries) throws Exception { From b6d132d54a9d706a3115a214ccc46b09461bc620 Mon Sep 17 00:00:00 2001 From: Torsten Egenolf Date: Fri, 27 Oct 2023 17:56:29 +0200 Subject: [PATCH 41/41] fix checkstyle --- .../ec/dgc/gateway/service/did/DidTrustListService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java index d10389ec..ef793993 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/service/did/DidTrustListService.java @@ -142,12 +142,14 @@ private String getCountryAsLowerCaseAlpha3(String country) { if (country == null || country.length() != 2 && country.length() != 3) { return null; } else if (country.length() == 3) { - return country; + return country.toLowerCase(); } return configProperties.getCountryCodeMap().getVirtualCountries() .compute(country, (alpha2, alpha3) -> { - if (alpha3 != null) return alpha3.toLowerCase(); + if (alpha3 != null) { + return alpha3.toLowerCase(); + } try { return new Locale("en", alpha2).getISO3Country().toLowerCase();