diff --git a/pom.xml b/pom.xml
index c79a35a..f979264 100644
--- a/pom.xml
+++ b/pom.xml
@@ -126,7 +126,7 @@
org.springframework
spring-web
- 6.1.6
+ 6.1.12
diff --git a/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java b/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java
index 78416ca..e34c0da 100644
--- a/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java
+++ b/src/main/java/tng/trustnetwork/keydistribution/repository/SignerInformationRepository.java
@@ -33,6 +33,10 @@ public interface SignerInformationRepository extends JpaRepository getByDomainIsAndCountryIs(String domain, String country);
+ List findByCountryIn(List country);
+
+ List findByGroupIn(List group);
+
List getByCountryIsAndGroupIs(String country, String group);
List getByCountryIsAndGroupIsAndKidIs(String country, String group, String kid);
diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java b/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java
index bb5e478..7492def 100644
--- a/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java
+++ b/src/main/java/tng/trustnetwork/keydistribution/service/SignerInformationService.java
@@ -150,6 +150,15 @@ public List getCertificatesByCountry(String country) {
return signerInformationRepository.getByCountryIs(country);
}
+ public List getCertificatesByAllCountries(List countries) {
+
+ return signerInformationRepository.findByCountryIn(countries);
+ }
+
+ public List getCertificatesByAllGroups(List groups) {
+
+ return signerInformationRepository.findByGroupIn(groups);
+ }
/**
* Returns signer information that are filtered by domain and participant.
*
@@ -157,6 +166,7 @@ public List getCertificatesByCountry(String country) {
* @param country a participant aka country code, used as filter
* @return matching SignerInformationEntities
*/
+
public List getCertificatesByCountryDomain(String country, String domain) {
return signerInformationRepository.getByDomainIsAndCountryIs(domain, country);
diff --git a/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java b/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java
index 10866cf..1c3447a 100644
--- a/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java
+++ b/src/main/java/tng/trustnetwork/keydistribution/service/did/DidTrustListService.java
@@ -49,6 +49,8 @@
import java.util.Map;
import java.util.MissingResourceException;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -111,6 +113,8 @@ private class DidSpecification {
private final Supplier> issuerSupplier;
+ private final Supplier> didPathSupplier;
+
public List getPath(boolean ref) {
ArrayList path = new ArrayList<>(this.path);
path.add(0, getListPathElement(ref));
@@ -163,49 +167,91 @@ public void job() {
didSpecifications.add(new DidSpecification(
Collections.emptyList(),
signerInformationService::getAllCertificates,
- trustedIssuerService::getAllDid));
+ trustedIssuerService::getAllDid,
+ () -> Stream.concat(Stream.of(WILDCARD_CHAR), domains.stream()).collect(Collectors.toList())
+ ));
// Add all Domain DID
- domains.forEach(
- domain -> didSpecifications.add(new DidSpecification(
+ domains.forEach(domain -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByDomain(domain);
+ didSpecifications.add(new DidSpecification(
List.of(domain),
- () -> signerInformationService.getCertificatesByDomain(domain),
- () -> trustedIssuerService.getAllDid(domain, null))));
+ () -> signerInformationEntitiesList,
+ () -> trustedIssuerService.getAllDid(domain, null),
+ () -> new ArrayList<>(
+ Stream.concat(Stream.of(WILDCARD_CHAR),signerInformationEntitiesList
+ .stream().map(entity -> getParticipantCode(entity.getCountry()))).collect(Collectors.toSet()))
+ ));
+ });
// Add all Country and Domain specific DID
domains.forEach(
- domain -> countries.forEach(
- country -> didSpecifications.add(new DidSpecification(
+ domain -> countries.forEach(country -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByCountryDomain(country, domain);
+ didSpecifications.add(new DidSpecification(
List.of(domain, getParticipantCode(country)),
- () -> signerInformationService.getCertificatesByCountryDomain(country, domain),
- () -> trustedIssuerService.getAllDid(domain, country))
- )));
+ () -> signerInformationEntitiesList,
+ () -> trustedIssuerService.getAllDid(domain, country),
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream()
+ .filter(signerInformationEntity -> isDeniedGroup(signerInformationEntity.getGroup()))
+ .map(entity -> getMappedGroupName(entity.getGroup())).collect(Collectors.toSet()))));
+ }));
+
+ // Add all Country and Domain independant DID
+ didSpecifications.add(new DidSpecification(
+ List.of(WILDCARD_CHAR),
+ () -> signerInformationService.getCertificatesByAllCountries(countries),
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ Stream.concat(Stream.of(WILDCARD_CHAR), countries.stream().map(country -> getParticipantCode(country)))
+ .collect(Collectors.toSet()))));
+
+
// Add all Domain independent and country specific DID
countries.forEach(
- country -> didSpecifications.add(new DidSpecification(
- List.of(WILDCARD_CHAR, getParticipantCode(country)),
- () -> signerInformationService.getCertificatesByCountry(country),
- () -> trustedIssuerService.getAllDid(null, country))));
+ country -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByCountry(country);
+ didSpecifications.add(new DidSpecification(
+ List.of(WILDCARD_CHAR, getParticipantCode(country)),
+ () -> signerInformationEntitiesList,
+ () -> trustedIssuerService.getAllDid(null, country),
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream()
+ .filter(signerInformation -> isDeniedGroup(signerInformation.getGroup()))
+ .map(entity -> getMappedGroupName(entity.getGroup())).collect(Collectors.toSet()))
+ ));
+ });
// Add all domain, country and group specific did
domains.forEach(
domain -> countries.forEach(
country -> groups.forEach(
- group -> didSpecifications.add(new DidSpecification(
- List.of(domain, getParticipantCode(country), getMappedGroupName(group)),
- () -> signerInformationService.getCertificatesByDomainParticipantGroup(domain, country, group),
- Collections::emptyList)))));
+ group -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByDomainParticipantGroup(domain, country, group);
+ didSpecifications.add(new DidSpecification(
+ List.of(domain, getParticipantCode(country), getMappedGroupName(group)),
+ () -> signerInformationEntitiesList,
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream().map(entity -> encodeKid(entity.getKid()))
+ .collect(Collectors.toSet()))));
+ })));
// Add all domain, country, group, kid specific did
domains.forEach(
domain -> countries.forEach(
country -> groups.forEach(
group -> {
- List entityList =
+ List signerInformationEntitiesList =
signerInformationService.getCertificatesByDomainParticipantGroup(domain, country, group);
- entityList.forEach(entity -> {
+ signerInformationEntitiesList.forEach(entity -> {
didSpecifications.add(new DidSpecification(
List.of(domain, getParticipantCode(country), getMappedGroupName(group),
encodeKid(entity.getKid())),
@@ -213,6 +259,7 @@ public void job() {
() -> signerInformationService.getCertificatesByDomainParticipantGroupKid(
domain, country, group, entity.getKid()),
+ Collections::emptyList,
Collections::emptyList
));
});
@@ -223,19 +270,26 @@ public void job() {
// Add all country and group specific did
countries.forEach(
country -> groups.forEach(
- group -> didSpecifications.add(new DidSpecification(
- List.of(WILDCARD_CHAR, getParticipantCode(country), getMappedGroupName(group)),
- () -> signerInformationService.getCertificatesByGroupCountry(group, country),
- Collections::emptyList))));
+ group -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByGroupCountry(group, country);
+ didSpecifications.add(new DidSpecification(
+ List.of(WILDCARD_CHAR, getParticipantCode(country), getMappedGroupName(group)),
+ () -> signerInformationEntitiesList,
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream().map(entity -> encodeKid(entity.getKid()))
+ .collect(Collectors.toSet()))));
+ }));
// Add all country, group, kid specific did
countries.forEach(
country -> groups.forEach(
group -> {
- List entityList =
+ List signerInformationEntitiesList =
signerInformationService.getCertificatesByGroupCountry(group, country);
- entityList.forEach(entity -> {
+ signerInformationEntitiesList.forEach(entity -> {
didSpecifications.add(new DidSpecification(
List.of(WILDCARD_CHAR, getParticipantCode(country), getMappedGroupName(group),
@@ -244,6 +298,7 @@ public void job() {
() -> signerInformationService.getCertificatesByKidGroupCountry(
country, group, entity.getKid()),
+ Collections::emptyList,
Collections::emptyList
));
});
@@ -252,18 +307,45 @@ public void job() {
// Add all domain and group specific did
domains.forEach(
domain -> groups.forEach(
- group -> didSpecifications.add(new DidSpecification(
- List.of(domain, WILDCARD_CHAR, getMappedGroupName(group)),
- () -> signerInformationService.getCertificatesByDomainGroup(domain, group),
- Collections::emptyList))));
+ group -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByDomainGroup(domain, group);
+ didSpecifications.add(new DidSpecification(
+ List.of(domain, WILDCARD_CHAR, getMappedGroupName(group)),
+ () -> signerInformationEntitiesList,
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream().map(entity -> encodeKid(entity.getKid()))
+ .collect(Collectors.toSet()))));
+
+ }));
+
+ // Add all country independent but domain and group specific did
+ domains.forEach(
+ domain -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByDomain(domain);
+ didSpecifications.add(new DidSpecification(
+ List.of(domain, WILDCARD_CHAR),
+ () -> signerInformationEntitiesList,
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream()
+ .filter(domainEntity -> isDeniedGroup(domainEntity.getGroup()))
+ .map(domainEntity -> getMappedGroupName(domainEntity.getGroup()))
+ .collect(Collectors.toSet()))
+ ));
+ });
+
+
// Add all domain, group and kid specific did
domains.forEach(
domain -> groups.forEach(
group -> {
- List entityList =
+ List signerInformationEntitiesList =
signerInformationService.getCertificatesByDomainGroup(domain, group);
- entityList.forEach(entity -> {
+ signerInformationEntitiesList.forEach(entity -> {
didSpecifications.add(new DidSpecification(
List.of(domain, WILDCARD_CHAR, getMappedGroupName(group),
encodeKid(entity.getKid())),
@@ -271,29 +353,52 @@ public void job() {
() -> signerInformationService.getCertificatesByDomainGroupKid(
domain, group, entity.getKid()),
+ Collections::emptyList,
Collections::emptyList
));
});
}));
+
+
// Add all group specific did
groups.forEach(
- group -> didSpecifications.add(new DidSpecification(
- List.of(WILDCARD_CHAR, WILDCARD_CHAR, getMappedGroupName(group)),
- () -> signerInformationService.getCertificatesByGroup(group),
- Collections::emptyList)));
+ group -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByGroup(group);
+ didSpecifications.add(new DidSpecification(
+ List.of(WILDCARD_CHAR, WILDCARD_CHAR, getMappedGroupName(group)),
+ () -> signerInformationEntitiesList,
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ signerInformationEntitiesList.stream()
+ .map(entity -> encodeKid(entity.getKid()))
+ .collect(Collectors.toSet()))));
+ });
+
+ // Add all domain country independent and group specific did
+ didSpecifications.add(new DidSpecification(
+ List.of(WILDCARD_CHAR, WILDCARD_CHAR),
+ () -> signerInformationService.getCertificatesByAllGroups(groups),
+ Collections::emptyList,
+ () -> new ArrayList<>(
+ groups.stream().filter(group -> isDeniedGroup(group))
+ .map(group -> getMappedGroupName(group))
+ .collect(Collectors.toSet()))));
// Add all group, kid specific did
groups.forEach(
group -> {
- List entityList = signerInformationService.getCertificatesByGroup(group);
- entityList.forEach(entity -> {
+ List signerInformationEntitiesList =
+ signerInformationService.getCertificatesByGroup(group);
+ signerInformationEntitiesList.forEach(entity -> {
didSpecifications.add(new DidSpecification(
List.of(WILDCARD_CHAR, WILDCARD_CHAR, getMappedGroupName(group),
encodeKid(entity.getKid())),
() -> signerInformationService.getCertificatesByGroupKid(group, entity.getKid()),
+ Collections::emptyList,
Collections::emptyList
));
});
@@ -335,6 +440,7 @@ private String generateTrustList(DidSpecification specification, boolean onlyRef
List signerInformationEntities = filterEntities(specification.getCertSupplier().get());
List trustedIssuerEntities = specification.getIssuerSupplier().get();
+ List didRefPathList = specification.getDidPathSupplier().get();
if (signerInformationEntities.isEmpty() && trustedIssuerEntities.isEmpty()) {
log.info("Empty DID for path {}", specification.getPath());
@@ -348,15 +454,28 @@ private String generateTrustList(DidSpecification specification, boolean onlyRef
trustList.setVerificationMethod(new ArrayList<>());
// Add Certificates
+ if (onlyReferences) {
+ if (didRefPathList.isEmpty()) {
+ trustList.getVerificationMethod().add(specification.getDocumentId(false));
+ } else {
+ didRefPathList.forEach(path -> {
+ trustList.getVerificationMethod()
+ .add(specification.getDocumentId(true) + SEPARATOR_DID_PATH + path);
+ });
+ }
+
+ trustedIssuerEntities.forEach(did -> {
+ if (!trustList.getVerificationMethod().contains(did.getUrl())) {
+ trustList.getVerificationMethod().add(did.getUrl());
+ }
+ });
- for (SignerInformationEntity signerInformationEntity : signerInformationEntities) {
+ } else {
+ for (SignerInformationEntity signerInformationEntity : signerInformationEntities) {
- if (onlyReferences) {
- trustList.getVerificationMethod().add(
- specification.getEntryId(encodeKid(signerInformationEntity.getKid())));
+ X509Certificate parsedCertificate =
+ kdsCertUtils.parseCertificate(signerInformationEntity.getRawData());
- } else {
- X509Certificate parsedCertificate = kdsCertUtils.parseCertificate(signerInformationEntity.getRawData());
if (parsedCertificate == null) {
log.error("Could not parse cert {} of country {}",
signerInformationEntity.getKid(),
@@ -384,11 +503,6 @@ private String generateTrustList(DidSpecification specification, boolean onlyRef
}
}
- // Add Trusted Issuer (DID References)
- // TODO: Add filtering for TrustedIssuers
- if (onlyReferences) {
- trustedIssuerEntities.forEach(did -> trustList.getVerificationMethod().add(did.getUrl()));
- }
// Sign Document
JsonWebSignature2020LdSigner signer = new JsonWebSignature2020LdSigner(byteSigner);
@@ -453,8 +567,7 @@ private void addTrustListEntry(DidTrustList trustList,
private List filterEntities(List entities) {
return entities.stream()
- .filter(entity -> kdsConfigProperties.getDid().getGroupDenyList().stream()
- .noneMatch(e -> entity.getGroup().equalsIgnoreCase(e)))
+ .filter(entity -> isDeniedGroup(entity.getGroup()))
.toList();
}
@@ -464,6 +577,12 @@ private String getMappedGroupName(String groupName) {
.computeIfAbsent(groupName, g -> g);
}
+
+ private boolean isDeniedGroup(String group) {
+ return kdsConfigProperties.getDid().getGroupDenyList().stream()
+ .noneMatch(e -> group.equalsIgnoreCase(e));
+ }
+
/**
* Recursively resolve certificate chains based on current database.
* Resolving is done country-code and domain aware.
diff --git a/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java b/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java
index 91b1bc5..e4181ff 100644
--- a/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java
+++ b/src/test/java/tng/trustnetwork/keydistribution/service/DidTrustListServiceTest.java
@@ -206,7 +206,7 @@ void testTrustList(boolean isEcAlgorithm) throws Exception {
didTrustListService.job();
- Assertions.assertEquals(104, uploadArgumentCaptor.getAllValues().size());
+ Assertions.assertEquals(110, uploadArgumentCaptor.getAllValues().size());
int expectedNullDid = 32;
@@ -239,7 +239,41 @@ void testTrustList(boolean isEcAlgorithm) throws Exception {
assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist#" + encodeKid(certCscaEuKid)),
certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist");
break;
-
+ case "did:web:abc:trustlist:-":
+ Assertions.assertEquals("did:web:abc:trustlist:-", parsed.getController());
+ Assertions.assertEquals(4, parsed.getVerificationMethod().size());
+
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-#" + encodeKid(certDscDeKid)),
+ certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:-");
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-#" + encodeKid(certCscaDeKid)),
+ certCscaDeKid, certCscaDe, null, "did:web:abc:trustlist:-");
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-#" + encodeKid(certDscEuKid)),
+ certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:-");
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-#" + encodeKid(certCscaEuKid)),
+ certCscaEuKid, certCscaEu, null, "did:web:abc:trustlist:-");
+ break;
+
+ case "did:web:abc:trustlist:-:-":
+ Assertions.assertEquals("did:web:abc:trustlist:-:-", parsed.getController());
+ Assertions.assertEquals(4, parsed.getVerificationMethod().size());
+
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:-#" + encodeKid(certDscDeKid)),
+ certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:-:-");
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:-:-#" + encodeKid(certDscEuKid)),
+ certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:-:-");
+ break;
+
+ case "did:web:abc:trustlist:DCC:-":
+ Assertions.assertEquals("did:web:abc:trustlist:DCC:-", parsed.getController());
+ Assertions.assertEquals(4, parsed.getVerificationMethod().size());
+
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:-#" + encodeKid(certDscDeKid)),
+ certDscDeKid, certDscDe, certCscaDe, "did:web:abc:trustlist:DCC:-");
+ assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(),"did:web:abc:trustlist:DCC:-#" + encodeKid(certDscEuKid)),
+ certDscEuKid, certDscEu, certCscaEu, "did:web:abc:trustlist:DCC:-");
+ break;
+
+
case "did:web:abc:trustlist:DCC:XEU:DSC":
Assertions.assertEquals("did:web:abc:trustlist:DCC:XEU:DSC", parsed.getController());
Assertions.assertEquals(1, parsed.getVerificationMethod().size());