From a762eb316a044d9d62c3b7eb80bfddc7a44e8edb Mon Sep 17 00:00:00 2001
From: Martin Vogel <martin.vogel@sinc.de>
Date: Thu, 9 Jun 2022 10:56:09 +0200
Subject: [PATCH] #414 Add validator for certificate check and metadata
 validation

---
 .../metadata/data/EidasAdesProfile.java       |  1 +
 .../api/metadata/MetadataService.java         | 17 +++++++++-
 .../api/validation/CertificateValidator.java  | 12 +++++++
 .../api/validation/MetadataValidator.java     | 31 +++++++++++++++++++
 .../api/validation/ValidationResult.java      |  8 +++--
 .../fitconnect/impl/SubmissionSender.java     | 15 +++++++--
 .../fitconnect/impl/SubmissionSubscriber.java | 15 ++++++++-
 7 files changed, 93 insertions(+), 6 deletions(-)
 create mode 100644 api/src/main/java/fitconnect/api/validation/CertificateValidator.java
 create mode 100644 api/src/main/java/fitconnect/api/validation/MetadataValidator.java

diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java b/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java
index 0fd71a987..3e19a0aa2 100644
--- a/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java
@@ -18,6 +18,7 @@ public enum EidasAdesProfile {
     HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_T("http://uri.etsi.org/ades/191x2/level/baseline/B-T#"),
     HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_LT("http://uri.etsi.org/ades/191x2/level/baseline/B-LT#"),
     HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_LTA("http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#");
+
     private final String value;
     private final static Map<String, EidasAdesProfile> CONSTANTS = new HashMap<>();
 
diff --git a/api/src/main/java/fitconnect/api/metadata/MetadataService.java b/api/src/main/java/fitconnect/api/metadata/MetadataService.java
index e9d674575..94a847f08 100644
--- a/api/src/main/java/fitconnect/api/metadata/MetadataService.java
+++ b/api/src/main/java/fitconnect/api/metadata/MetadataService.java
@@ -1,8 +1,23 @@
 package fitconnect.api.metadata;
 
+import com.nimbusds.jose.jwk.RSAKey;
 import fitconnect.api.domain.metadata.Metadata;
+import fitconnect.api.domain.metadata.attachment.Attachment;
+import fitconnect.api.domain.metadata.data.Data;
 
+import java.util.List;
+
+/**
+ * Provides the generation of correct and valid {@link Metadata} for a submission
+ */
 public interface MetadataService {
 
-    Metadata createMetadata();
+    /**
+     *
+     * @param data the actual data payload (json or xml)
+     * @param attachments list of 0..n attachments as binary data
+     * @param publicKey the publicKey the data and attachments are encrypted with
+     * @return Metadata with hashes of the data and attachments to send
+     */
+    Metadata createMetadata(final Data data, final List<Attachment> attachments, final RSAKey publicKey);
 }
diff --git a/api/src/main/java/fitconnect/api/validation/CertificateValidator.java b/api/src/main/java/fitconnect/api/validation/CertificateValidator.java
new file mode 100644
index 000000000..af35996de
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/validation/CertificateValidator.java
@@ -0,0 +1,12 @@
+package fitconnect.api.validation;
+
+import com.nimbusds.jose.jwk.RSAKey;
+
+/**
+ *
+ * See <a>https://docs.fitko.de/fit-connect/docs/sending/encrypt/#certificateValidation</a>
+ */
+public interface CertificateValidator {
+
+    ValidationResult validatePublicKey(final RSAKey publicKey);
+}
diff --git a/api/src/main/java/fitconnect/api/validation/MetadataValidator.java b/api/src/main/java/fitconnect/api/validation/MetadataValidator.java
new file mode 100644
index 000000000..6c1e3776a
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/validation/MetadataValidator.java
@@ -0,0 +1,31 @@
+package fitconnect.api.validation;
+
+import fitconnect.api.domain.metadata.Metadata;
+import fitconnect.api.domain.metadata.attachment.Attachment;
+import fitconnect.api.domain.metadata.data.Data;
+
+/**
+ * A validator that ensure the integrity of the transferred metadata of a submission
+ */
+public interface MetadataValidator {
+
+    /**
+     * Validated the metdata against a given schema
+     *
+     * @param metadata the current metadata object that is validated
+     * @param jsonSchema the schema that is used to validate against
+     *
+     * @return a validation result with an optional error list
+     */
+    ValidationResult validateMetadataSchema(final Metadata metadata, String jsonSchema);
+
+    /**
+     * Checks if the message digest hashes of the metadatas {@link Data} and {@link Attachment}
+     * are correct after transmission
+     *
+     * @param metadata the current metadata object that is validated
+     *
+     * @return a validation result with an optional error list
+     */
+    ValidationResult validateMetadataHashValues(final Metadata metadata);
+}
diff --git a/api/src/main/java/fitconnect/api/validation/ValidationResult.java b/api/src/main/java/fitconnect/api/validation/ValidationResult.java
index d2a0e7fcc..08bb6eef6 100644
--- a/api/src/main/java/fitconnect/api/validation/ValidationResult.java
+++ b/api/src/main/java/fitconnect/api/validation/ValidationResult.java
@@ -1,4 +1,8 @@
 package fitconnect.api.validation;
 
-public class ValidationResult {
-}
+import java.util.List;
+
+/**
+ * Wrapper for validations including errors that occurred
+ */
+public record ValidationResult(boolean isValid, List<Exception> errors) { }
diff --git a/impl/src/main/java/fitconnect/impl/SubmissionSender.java b/impl/src/main/java/fitconnect/impl/SubmissionSender.java
index 7bdcde0f6..4275afff8 100644
--- a/impl/src/main/java/fitconnect/impl/SubmissionSender.java
+++ b/impl/src/main/java/fitconnect/impl/SubmissionSender.java
@@ -5,15 +5,20 @@ import fitconnect.api.auth.OAuthService;
 import fitconnect.api.auth.OAuthToken;
 import fitconnect.api.crypto.EncryptionService;
 import fitconnect.api.domain.metadata.Metadata;
+import fitconnect.api.domain.metadata.attachment.Attachment;
+import fitconnect.api.domain.metadata.data.Data;
 import fitconnect.api.metadata.MetadataService;
 import fitconnect.api.problems.EncryptionProblem;
+import fitconnect.api.validation.CertificateValidator;
+import fitconnect.api.validation.ValidationResult;
 
+import java.util.List;
 import java.util.Optional;
 
 /**
  * A technical system that creates a submission via the FIT-Co Submission API.
  */
-public class SubmissionSender implements OAuthService, EncryptionService, MetadataService {
+public class SubmissionSender implements OAuthService, EncryptionService, MetadataService, CertificateValidator {
 
     private final OAuthService authService;
     private final EncryptionService encryptionService;
@@ -39,7 +44,13 @@ public class SubmissionSender implements OAuthService, EncryptionService, Metada
     }
 
     @Override
-    public Metadata createMetadata() {
+    public Metadata createMetadata(Data data, List<Attachment> attachments, RSAKey publicKey) {
         throw new UnsupportedOperationException("not yet implemented");
     }
+
+    @Override
+    public ValidationResult validatePublicKey(final RSAKey publicKey) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
 }
diff --git a/impl/src/main/java/fitconnect/impl/SubmissionSubscriber.java b/impl/src/main/java/fitconnect/impl/SubmissionSubscriber.java
index e4e1e2f43..e271f2cbd 100644
--- a/impl/src/main/java/fitconnect/impl/SubmissionSubscriber.java
+++ b/impl/src/main/java/fitconnect/impl/SubmissionSubscriber.java
@@ -4,14 +4,17 @@ import com.nimbusds.jose.jwk.RSAKey;
 import fitconnect.api.auth.OAuthService;
 import fitconnect.api.auth.OAuthToken;
 import fitconnect.api.crypto.DecryptionService;
+import fitconnect.api.domain.metadata.Metadata;
 import fitconnect.api.problems.DecryptionProblem;
+import fitconnect.api.validation.MetadataValidator;
+import fitconnect.api.validation.ValidationResult;
 
 import java.util.Optional;
 
 /**
  * The technical system that accepts submissions on the administration side.
  */
-public class SubmissionSubscriber implements OAuthService, DecryptionService {
+public class SubmissionSubscriber implements OAuthService, DecryptionService, MetadataValidator {
 
     private final OAuthService authService;
     private final DecryptionService decryptionService;
@@ -36,4 +39,14 @@ public class SubmissionSubscriber implements OAuthService, DecryptionService {
         return decryptionService.decryptBytes(privateKey, encryptedData);
 
     }
+
+    @Override
+    public ValidationResult validateMetadataSchema(Metadata metadata, String jsonSchema) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public ValidationResult validateMetadataHashValues(Metadata metadata) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
 }
-- 
GitLab