From 0c410ddee747e58b3cd66bad2b31d033f40cc370 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 7 Sep 2023 12:32:19 +0200 Subject: [PATCH 1/4] feat(impl):[TRI-1610] change logic and add logs --- .../job/delegate/AbstractDelegate.java | 2 +- .../job/delegate/IntegrityDelegate.java | 3 +- .../irs/services/DataIntegrityService.java | 34 +++++++++---------- .../services/IrsItemGraphQueryService.java | 4 +-- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java index 4342c89df3..a0e4513817 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java @@ -105,7 +105,7 @@ private void addSubmodelToList(final EdcSubmodelFacade submodelFacade, final End submodelFacade.getSubmodelRawPayload(connectorEndpoint, endpoint.getProtocolInformation().getHref(), extractAssetId(endpoint.getProtocolInformation().getSubprotocolBody()))); } catch (ItemNotFoundInCatalogException e) { - log.info("Could not find asset in catalog. Requesting next endpoint.", e); + log.debug("Could not find asset in catalog. Requesting next endpoint.", e); } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/IntegrityDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/IntegrityDelegate.java index d4a3c4f408..4c44795fd9 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/IntegrityDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/IntegrityDelegate.java @@ -95,13 +95,14 @@ private Optional getIntegrityAspect(final Endpoint endpoint, fi itemId.getGlobalAssetId()); itemContainerBuilder.tombstone( Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), - "Can't get relationship without a BPN", retryCount, ProcessStep.DATA_INTEGRITY_CHECK)); + "Can't get Data Integrity aspect without a BPN", retryCount, ProcessStep.DATA_INTEGRITY_CHECK)); return Optional.empty(); } try { final String submodelRawPayload = requestSubmodelAsString(submodelFacade, connectorEndpointsService, endpoint, itemId.getBpn()); + log.debug("Found DataIntegrity aspect for item: {}", itemId.getGlobalAssetId()); return Optional.ofNullable(jsonUtil.fromString(submodelRawPayload, IntegrityAspect.class)); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java index e7ac4762ea..8654b8ba01 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java @@ -31,7 +31,6 @@ import java.security.NoSuchAlgorithmException; import java.security.Security; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Set; import java.util.function.Predicate; @@ -58,6 +57,7 @@ @Slf4j public class DataIntegrityService { + private static final String SHA3_256 = "SHA3-256"; private AsymmetricKeyParameter publicKey; public DataIntegrityService(@Value("${integrity.publicKeyCert:}") final String publicKeyCert) { @@ -76,20 +76,16 @@ public DataIntegrityService(@Value("${integrity.publicKeyCert:}") final String p * @return flag indicates if chain is valid */ public IntegrityState chainDataIntegrityIsValid(final ItemContainer itemContainer) { - final long numberOfValidSubmodels = itemContainer.getSubmodels().stream().takeWhile(submodel -> { - try { - return submodelDataIntegrityIsValid(submodel, itemContainer.getIntegrities()); - } catch (NoSuchElementException | NoSuchAlgorithmException exc) { - log.error("DataIntegrity aspect is missing. Integrity of data chain cannot be determined."); - return false; - } - }).count(); + log.debug("Starting validation of Data Chain Integrity with {} integrity aspects.", itemContainer.getIntegrities().size()); + final long numberOfValidSubmodels = itemContainer.getSubmodels() + .stream() + .takeWhile(submodel -> submodelDataIntegrityIsValid(submodel, itemContainer.getIntegrities())) + .count(); return IntegrityState.from(numberOfValidSubmodels, totalNumberOfSubmodels(itemContainer)); } - private boolean submodelDataIntegrityIsValid(final Submodel submodel, final Set integrities) - throws NoSuchAlgorithmException { + private boolean submodelDataIntegrityIsValid(final Submodel submodel, final Set integrities) { final IntegrityAspect.ChildData childData = integrities.stream() .map(IntegrityAspect::getChildParts) .flatMap(Set::stream) @@ -103,9 +99,10 @@ private boolean submodelDataIntegrityIsValid(final Submodel submodel, final Set< .findFirst() .orElseThrow(); + log.debug("Calculating hash of Submodel id: {}", submodel.getIdentification()); final String calculatedHash = calculateHashForRawSubmodelPayload(submodel.getPayload()); - log.debug("Comparing hashes and signatures Data integrity of Submodel id: {}", submodel.getIdentification()); + log.debug("Comparing hashes and signatures Data integrity of Submodel id: {}", submodel.getIdentification()); return hashesEquals(reference.getHash(), calculatedHash) && signaturesEquals(reference.getSignature(), bytesOf(submodel.getPayload())); } @@ -126,16 +123,19 @@ private int totalNumberOfSubmodels(final ItemContainer itemContainer) { return itemContainer.getSubmodels().size(); } - private String calculateHashForRawSubmodelPayload(final Map payload) - throws NoSuchAlgorithmException { - log.debug("Calculating hash for payload '{}", payload); + private String calculateHashForRawSubmodelPayload(final Map payload) { final byte[] digest = bytesOf(payload); log.debug("Returning hash '{}'", Hex.toHexString(digest)); return Hex.toHexString(digest); } - private byte[] bytesOf(final Map payload) throws NoSuchAlgorithmException { - return MessageDigest.getInstance("SHA3-256").digest(mapToString(payload).getBytes(StandardCharsets.UTF_8)); + private byte[] bytesOf(final Map payload) { + try { + return MessageDigest.getInstance(SHA3_256).digest(mapToString(payload).getBytes(StandardCharsets.UTF_8)); + } catch (NoSuchAlgorithmException exc) { + log.error("Cant retrieve bytes from payload, integrity of data chain cannot be determined.", exc); + return new byte[0]; + } } private Predicate findReference(final String aspectType) { diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java index 6aed16b805..50bcb3d152 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryService.java @@ -230,8 +230,8 @@ private void validateAspectTypeValues(final List aspectTypeValues) { try { final HashSet availableModels = new HashSet<>( semanticsHubFacade.getAllAspectModels().models()); - log.info("Available AspectModels: '{}'", availableModels); - log.info("Provided AspectModels: '{}'", aspectTypeValues); + log.debug("Available AspectModels: '{}'", availableModels); + log.debug("Provided AspectModels: '{}'", aspectTypeValues); final Set availableNames = new HashSet<>(availableModels.stream().map(AspectModel::name).toList()); final Set availableUrns = new HashSet<>(availableModels.stream().map(AspectModel::urn).toList()); From 2b25793e4a2826b9b66a70c64c7dfb39227dd2b3 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 7 Sep 2023 13:34:12 +0200 Subject: [PATCH 2/4] feat(impl):[TRI-1610] update impl --- .../irs/aaswrapper/job/IntegrityAspect.java | 8 +++ .../irs/services/DataIntegrityService.java | 56 +++++++++---------- .../eclipse/tractusx/irs/util/TestMother.java | 1 + 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java index 23963d50c0..cb0cc205ad 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java @@ -23,6 +23,7 @@ package org.eclipse.tractusx.irs.aaswrapper.job; import java.util.Set; +import java.util.function.Predicate; import lombok.AllArgsConstructor; import lombok.Data; @@ -51,6 +52,10 @@ public static class ChildData { private String childCatenaXId; private Set reference; + public boolean childCatenaXIdMatches(final String catenaXId) { + return this.childCatenaXId.equals(catenaXId); + } + } /** @@ -64,5 +69,8 @@ public static class Reference { private String hash; private String signature; + public boolean semanticModelUrnMatches(final String aspectType) { + return this.getSemanticModelUrn().equals(aspectType); + } } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java index 8654b8ba01..9a4d1785d8 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java @@ -31,8 +31,8 @@ import java.security.NoSuchAlgorithmException; import java.security.Security; import java.util.Map; +import java.util.Optional; import java.util.Set; -import java.util.function.Predicate; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; @@ -86,25 +86,31 @@ public IntegrityState chainDataIntegrityIsValid(final ItemContainer itemContaine } private boolean submodelDataIntegrityIsValid(final Submodel submodel, final Set integrities) { - final IntegrityAspect.ChildData childData = integrities.stream() - .map(IntegrityAspect::getChildParts) - .flatMap(Set::stream) - .filter(findIntegrityChildPart(submodel.getCatenaXId())) - .findFirst() - .orElseThrow(); - - final IntegrityAspect.Reference reference = childData.getReference() - .stream() - .filter(findReference(submodel.getAspectType())) - .findFirst() - .orElseThrow(); - - log.debug("Calculating hash of Submodel id: {}", submodel.getIdentification()); - final String calculatedHash = calculateHashForRawSubmodelPayload(submodel.getPayload()); - - log.debug("Comparing hashes and signatures Data integrity of Submodel id: {}", submodel.getIdentification()); - return hashesEquals(reference.getHash(), calculatedHash) - && signaturesEquals(reference.getSignature(), bytesOf(submodel.getPayload())); + final Optional reference = findIntegrityAspectReferenceForSubmodel(submodel, integrities); + + if (reference.isPresent()) { + log.debug("Calculating hash of Submodel id: {}", submodel.getIdentification()); + final String calculatedHash = calculateHashForRawSubmodelPayload(submodel.getPayload()); + + log.debug("Comparing hashes and signatures Data integrity of Submodel id: {}", submodel.getIdentification()); + return hashesEquals(reference.get().getHash(), calculatedHash) && + signaturesEquals(reference.get().getSignature(), bytesOf(submodel.getPayload())); + } else { + log.debug("Integrity of Data chain cannot be determined, as Data Integrity Aspect Reference was not found for Submodel: {}, {}", submodel.getIdentification(), submodel.getAspectType()); + return false; + } + } + + private Optional findIntegrityAspectReferenceForSubmodel(final Submodel submodel, final Set integrities) { + return integrities.stream() + .map(IntegrityAspect::getChildParts) + .flatMap(Set::stream) + .filter(childData -> childData.childCatenaXIdMatches(submodel.getCatenaXId())) + .findFirst() + .flatMap(childData -> childData.getReference() + .stream() + .filter(reference -> reference.semanticModelUrnMatches(submodel.getAspectType())) + .findFirst()); } private static boolean hashesEquals(final String hashReference, final String calculatedHash) { @@ -133,17 +139,9 @@ private byte[] bytesOf(final Map payload) { try { return MessageDigest.getInstance(SHA3_256).digest(mapToString(payload).getBytes(StandardCharsets.UTF_8)); } catch (NoSuchAlgorithmException exc) { - log.error("Cant retrieve bytes from payload, integrity of data chain cannot be determined.", exc); + log.error("Integrity of Data chain cannot be determined, cant retrieve bytes from payload.", exc); return new byte[0]; } } - private Predicate findReference(final String aspectType) { - return reference -> reference.getSemanticModelUrn().equals(aspectType); - } - - private Predicate findIntegrityChildPart(final String catenaXId) { - return integrityChildPart -> integrityChildPart.getChildCatenaXId().equals(catenaXId); - } - } diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java index ae90b3f254..c58610e76a 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/util/TestMother.java @@ -116,6 +116,7 @@ public static RegisterJob registerJob(final String globalAssetId, final Integer registerJob.setCollectAspects(collectAspects); registerJob.setDirection(direction); registerJob.setLookupBPNs(lookupBPNs); + registerJob.setIntegrityCheck(false); return registerJob; } From 31bada9dbbeed32aea3b5d060e4c1a8793502a21 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 7 Sep 2023 13:36:22 +0200 Subject: [PATCH 3/4] feat(impl):[TRI-1610] update javadoc --- .../tractusx/irs/aaswrapper/job/IntegrityAspect.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java index cb0cc205ad..4a2dbfbd75 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java @@ -52,6 +52,11 @@ public static class ChildData { private String childCatenaXId; private Set reference; + /** + * + * @param catenaXId filter + * @return Check if childCatenaXId matches argument + */ public boolean childCatenaXIdMatches(final String catenaXId) { return this.childCatenaXId.equals(catenaXId); } @@ -69,6 +74,10 @@ public static class Reference { private String hash; private String signature; + /** + * @param aspectType filter + * @return Check if semanticModelUrn matches argument + */ public boolean semanticModelUrnMatches(final String aspectType) { return this.getSemanticModelUrn().equals(aspectType); } From efc5fb9073672d7fe2064e9a6e3424db2059b598 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 7 Sep 2023 13:42:48 +0200 Subject: [PATCH 4/4] feat(impl):[TRI-1610] fix findings trivy --- .../eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java | 1 - .../eclipse/tractusx/irs/services/DataIntegrityService.java | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java index 4a2dbfbd75..b818b6d0b2 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/IntegrityAspect.java @@ -23,7 +23,6 @@ package org.eclipse.tractusx.irs.aaswrapper.job; import java.util.Set; -import java.util.function.Predicate; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java index 9a4d1785d8..26bb74a6ea 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/services/DataIntegrityService.java @@ -93,8 +93,8 @@ private boolean submodelDataIntegrityIsValid(final Submodel submodel, final Set< final String calculatedHash = calculateHashForRawSubmodelPayload(submodel.getPayload()); log.debug("Comparing hashes and signatures Data integrity of Submodel id: {}", submodel.getIdentification()); - return hashesEquals(reference.get().getHash(), calculatedHash) && - signaturesEquals(reference.get().getSignature(), bytesOf(submodel.getPayload())); + return hashesEquals(reference.get().getHash(), calculatedHash) + && signaturesEquals(reference.get().getSignature(), bytesOf(submodel.getPayload())); } else { log.debug("Integrity of Data chain cannot be determined, as Data Integrity Aspect Reference was not found for Submodel: {}, {}", submodel.getIdentification(), submodel.getAspectType()); return false;