diff --git a/FitConnect/Services/Models/v1/Api/Problems.cs b/FitConnect/Services/Models/v1/Api/Problems.cs index 68ecf380554e21a50e4952d799b13008373a2075..b423f6a4feaf64f6dc399a2eb6caf4630da7df1a 100644 --- a/FitConnect/Services/Models/v1/Api/Problems.cs +++ b/FitConnect/Services/Models/v1/Api/Problems.cs @@ -23,6 +23,9 @@ public class Problems { public const string TitleMissingData = "Fachdatensatz fehlt"; public const string DetailMissingData = "Der Fachdatensatz fehlt."; + public const string TitleHashMismatch = "Prüfsumme stimmt nicht"; + public const string DetailDataHashMismatch = "Die Prüfsumme des Fachdatensatzes stimmt nicht."; + public const string TitleMissingSchema = "Schema-Referenz fehlt"; public const string DetailMissingSchema = "Die Schema-Referenz fehlt im Metadatensatz."; @@ -33,7 +36,9 @@ public class Problems { public const string DetailUnsupportedService = "Die angegebene Verwaltungsleistung wird nicht unterstützt."; public const string TitleSyntaxViolation = "Syntax-Fehler"; - public const string DetailSyntaxViolation = "Der Metadatensatz ist kein valides JSON."; + public const string DetailSyntaxViolationMetadata = "Der Metadatensatz ist kein valides JSON."; + public const string DetailSyntaxViolationDataJson = "Der Fachdatensatz ist kein valides JSON."; + public const string DetailSyntaxViolationDataXml = "Der Fachdatensatz ist kein valides XML."; public const string TitleServiceMismatch = "Verwaltungsleistung stimmt nicht überein"; public const string DetailServiceMismatch = "Die Verwaltungsleistung in Submission und Metadatensatz stimmen nicht überein."; diff --git a/FitConnect/Subscriber.cs b/FitConnect/Subscriber.cs index 6cd6563add82f75a3fb615c767c3615c8308302c..61eb96685057f94dec9936c9e36d9b544dd91d43 100644 --- a/FitConnect/Subscriber.cs +++ b/FitConnect/Subscriber.cs @@ -1,4 +1,5 @@ using System.Security; +using System.Xml; using Autofac; using FitConnect.Encryption; using FitConnect.Interfaces.Subscriber; @@ -134,7 +135,7 @@ public class Subscriber : FitConnectClient, // SuccessCriteria:3.3 if (submission.Metadata == null) { var problem = new Problems(Problems.ProblemTypeEnum.SyntaxViolation, - Problems.DetailSyntaxViolation); + Problems.DetailSyntaxViolationMetadata); RejectSubmission(submission, problem); throw new SecurityEventException(problem); } @@ -167,6 +168,8 @@ public class Subscriber : FitConnectClient, try { var (dataString, _, dataHash) = Encryption.Decrypt(submission.EncryptedData); submission.Data = dataString; + + // SuccessCriteria: 4.3 (Wrong problem?!) VerifyDataHash(submission, dataString); } catch (Exception e) { @@ -189,7 +192,6 @@ public class Subscriber : FitConnectClient, // SuccessCriteria:3.11 - // TODO No test for data schema implemented, missing schema url var dataSchema = GetSchemaUrlFromJson(submission.Data); if (dataSchema == null) { Logger?.LogWarning("No data schema found for submission {SubmissionId}", submissionId); @@ -205,7 +207,35 @@ public class Subscriber : FitConnectClient, } // SuccessCriteria:4.5 - CheckDataSchema(dataSchema, submission); + if (submission.DataMimeType == "application/json") { + if (JsonConvert.DeserializeObject(submission.Data) == null) { + var problem = new Problems( + Problems.ProblemTypeEnum.SyntaxViolation, + Problems.TitleSyntaxViolation, + Problems.DetailSyntaxViolationDataJson, + problemInstance: Problems.ProblemInstanceEnum.Data); + RejectSubmission(submission, problem); + throw new SecurityEventException(problem); + } + + CheckDataSchema(dataSchema, submission); + } + + if (submission.DataMimeType == "application/xml") { + try { + var doc = new XmlDocument(); + doc.LoadXml(submission.Data); + } + catch (Exception e) { + var problem = new Problems( + Problems.ProblemTypeEnum.SyntaxViolation, + Problems.TitleSyntaxViolation, + Problems.DetailSyntaxViolationDataXml, + problemInstance: Problems.ProblemInstanceEnum.Data); + RejectSubmission(submission, problem); + throw new SecurityEventException(problem, e); + } + } } @@ -250,10 +280,10 @@ public class Subscriber : FitConnectClient, submission.Metadata?.ContentStructure.Data.Hash.Content, FitEncryption.CalculateHash(dataString)); - // SuccessCriteria: 4.1 - var problem = new Problems(Problems.ProblemTypeEnum.IncorrectAuthenticationTag, - Problems.TitleAuthenticationTagInvalid, - detail: Problems.DetailAuthenticationTagDataInvalid, Problems.ProblemInstanceEnum.Data); + // SuccessCriteria: 4.3 + var problem = new Problems(Problems.ProblemTypeEnum.HashMismatch, + Problems.TitleHashMismatch, + detail: Problems.DetailDataHashMismatch, Problems.ProblemInstanceEnum.Data); RejectSubmission(submission, Problems.EncryptionIssue); throw new SecurityEventException(problem); } @@ -307,15 +337,16 @@ public class Subscriber : FitConnectClient, metadataSignature = authenticationTag?.metadata?.ToString() ?? ""; if (submission.EncryptedData?.Split('.').Last() != dataSignature) { - RejectSubmission(submission, - new Problems(Problems.ProblemTypeEnum.IncorrectAuthenticationTag, - Problems.DetailAuthenticationTagMissing)); - throw new AggregateException("Data signature mismatch"); + // SuccessCriteria: 4.1 + var problem = new Problems(Problems.ProblemTypeEnum.IncorrectAuthenticationTag, + Problems.DetailDataHashMismatch); + RejectSubmission(submission, problem); + throw new SecurityEventException(problem); } if (submission.EncryptedMetadata?.Split('.').Last() != metadataSignature) { RejectSubmission(submission, Problems.IncorrectAuthenticationTag); - throw new AggregateException("Metadata signature mismatch"); + throw new SecurityEventException(Problems.IncorrectAuthenticationTag); } return submitEvent;