e5Jk-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