private async Task <StepResult> DecryptAS4MessageAsync(MessagingContext messagingContext)
        {
            try
            {
                Logger.Trace("Start decrypting AS4Message ...");
                X509Certificate2 decryptionCertificate = GetCertificate(messagingContext);
                messagingContext.AS4Message.Decrypt(decryptionCertificate);
                Logger.Info($"{messagingContext.LogTag} AS4Message is decrypted correctly");

                JournalLogEntry entry =
                    JournalLogEntry.CreateFrom(
                        messagingContext.AS4Message,
                        $"Decrypted using certificate {decryptionCertificate.FriendlyName}");

                return(await StepResult
                       .Success(messagingContext)
                       .WithJournalAsync(entry));
            }
            catch (Exception ex) when(ex is CryptoException || ex is CryptographicException)
            {
                Logger.Error(ex);

                messagingContext.ErrorResult = new ErrorResult(
                    description: "Decryption of message failed",
                    alias: ErrorAlias.FailedDecryption);

                Logger.Error(messagingContext.ErrorResult.Description);
                return(StepResult.Failed(messagingContext));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Sign the <see cref="AS4Message" />
        /// </summary>
        /// <param name="messagingContext"></param>
        /// <returns></returns>
        public async Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
        {
            if (messagingContext == null)
            {
                throw new ArgumentNullException(nameof(messagingContext));
            }

            if (messagingContext.AS4Message == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(SignAS4MessageStep)} requires an AS4Message to sign but no AS4Message is present in the MessagingContext");
            }

            if (messagingContext.AS4Message.IsEmpty)
            {
                Logger.Debug("No signing will be performed on the message because it's empty");
                return(await StepResult.SuccessAsync(messagingContext));
            }

            Signing signInfo = RetrieveSigningInformation(
                messagingContext.AS4Message,
                messagingContext.SendingPMode,
                messagingContext.ReceivingPMode);

            if (signInfo == null)
            {
                Logger.Trace("No signing will be performend on the message because no signing information was found in either Sending or Receiving PMode");
                return(await StepResult.SuccessAsync(messagingContext));
            }

            if (signInfo.IsEnabled == false)
            {
                Logger.Trace("No signing will be performend on the message because the PMode siging information is disabled");
                return(await StepResult.SuccessAsync(messagingContext));
            }

            Logger.Info($"(Outbound)[{messagingContext.AS4Message.GetPrimaryMessageId()}] Sign AS4Message with given signing information of the PMode");

            X509Certificate2 certificate = RetrieveCertificate(signInfo);
            var settings =
                new CalculateSignatureConfig(
                    signingCertificate: certificate,
                    referenceTokenType: signInfo.KeyReferenceMethod,
                    signingAlgorithm: signInfo.Algorithm,
                    hashFunction: signInfo.HashFunction);

            SignAS4Message(settings, messagingContext.AS4Message);

            JournalLogEntry logEntry = JournalLogEntry.CreateFrom(
                messagingContext.AS4Message,
                $"Signed with certificate {settings.SigningCertificate.FriendlyName} and reference {settings.ReferenceTokenType} "
                + $"using algorithm {settings.SigningAlgorithm} and hash {settings.HashFunction}");

            return(await StepResult
                   .Success(messagingContext)
                   .WithJournalAsync(logEntry));
        }
Beispiel #3
0
 public Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
 {
     return(StepResult
            .Failed(messagingContext)
            .WithJournalAsync(
                JournalLogEntry.CreateFrom(
                    messagingContext.AS4Message,
                    "Log entry 3")));
 }
Beispiel #4
0
        /// <summary>
        /// Promote the <see cref="StepResult"/> with a <see cref="JournalLogEntry"/>.
        /// </summary>
        /// <param name="entry">The entry containing information about the message.</param>
        public Task <StepResult> WithJournalAsync(JournalLogEntry entry)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            return(Task.FromResult(WithJournal(entry)));
        }
Beispiel #5
0
        /// <summary>
        /// Promote the <see cref="StepResult"/> with a <see cref="JournalLogEntry"/>.
        /// </summary>
        /// <param name="entry">The entry containing information about the message.</param>
        public StepResult WithJournal(JournalLogEntry entry)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            Logger.Trace($"Append log to message journal: {String.Join(", ", entry.LogEntries)}");
            return(new StepResult(Succeeded, CanProceed, MessagingContext, _journal.Concat(new[] { entry })));
        }
        /// <summary>
        /// Start Encrypting AS4 Message
        /// </summary>
        /// <param name="messagingContext"></param>
        /// <returns></returns>
        public async Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
        {
            if (messagingContext == null)
            {
                throw new ArgumentNullException(nameof(messagingContext));
            }

            if (messagingContext.AS4Message == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(EncryptAS4MessageStep)} requires an AS4Message to encrypt but no AS4Message is present in the MessagingContext");
            }

            if (messagingContext.SendingPMode == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(EncryptAS4MessageStep)} requires a SendingPMode to encrypt the AS4Message but no SendingPMode is present in the MessagingContext");
            }

            if (messagingContext.SendingPMode.Security?.Encryption == null ||
                messagingContext.SendingPMode.Security.Encryption.IsEnabled == false)
            {
                Logger.Trace(
                    "No encryption of the AS4Message will happen because the " +
                    $"SendingPMode {messagingContext.SendingPMode?.Id} Security.Encryption.IsEnabled is disabled");

                return(await StepResult.SuccessAsync(messagingContext));
            }

            Logger.Info(
                $"(Outbound)[{messagingContext.AS4Message.GetPrimaryMessageId()}] Encrypt AS4Message with given encryption information " +
                $"configured in the SendingPMode: {messagingContext.SendingPMode.Id}");

            KeyEncryptionConfiguration keyEncryptionConfig = RetrieveKeyEncryptionConfig(messagingContext.SendingPMode);
            Encryption encryptionSettings   = messagingContext.SendingPMode.Security.Encryption;
            var        dataEncryptionConfig = new DataEncryptionConfiguration(
                encryptionMethod: encryptionSettings.Algorithm,
                algorithmKeySize: encryptionSettings.AlgorithmKeySize);

            EncryptAS4Message(
                messagingContext.AS4Message,
                keyEncryptionConfig,
                dataEncryptionConfig);

            var journal = JournalLogEntry.CreateFrom(
                messagingContext.AS4Message,
                $"Encrypted using certificate {keyEncryptionConfig.EncryptionCertificate.FriendlyName} and "
                + $"key encryption method: {keyEncryptionConfig.EncryptionMethod}, key digest method: {keyEncryptionConfig.DigestMethod}, "
                + $"key mgf: {keyEncryptionConfig.Mgf} and Data encryption method: {dataEncryptionConfig.EncryptionMethod}, "
                + $" data encryption type: {dataEncryptionConfig.EncryptionType}, data transport algorithm: {dataEncryptionConfig.TransformAlgorithm}");

            return(await StepResult
                   .Success(messagingContext)
                   .WithJournalAsync(journal));
        }
Beispiel #7
0
 public Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
 {
     return(StepResult
            .Success(messagingContext)
            .WithJournalAsync(
                JournalLogEntry.CreateFrom(
                    AS4Message.Create(new Receipt(
                                          $"receipt-{Guid.NewGuid()}",
                                          messagingContext.AS4Message.PrimaryMessageUnit.MessageId)),
                    "Log entry 1")));
 }
Beispiel #8
0
        private static async Task <StepResult> TryVerifyingSignatureAsync(
            MessagingContext messagingContext,
            SigningVerification verification)
        {
            try
            {
                VerifySignatureConfig options =
                    CreateVerifyOptionsForAS4Message(messagingContext.AS4Message, verification);

                Logger.Debug($"Verify signature on the AS4Message {{AllowUnknownRootCertificateAuthority={options.AllowUnknownRootCertificateAuthority}}}");
                if (!messagingContext.AS4Message.VerifySignature(options))
                {
                    return(InvalidSignatureResult(
                               "The signature is invalid",
                               ErrorAlias.FailedAuthentication,
                               messagingContext));
                }

                Logger.Info($"{messagingContext.LogTag} AS4Message has a valid signature present");

                JournalLogEntry entry =
                    JournalLogEntry.CreateFrom(
                        messagingContext.AS4Message,
                        $"Signature verified with {(options.AllowUnknownRootCertificateAuthority ? "allowing" : "disallowing")} unknown certificate authorities");

                return(await StepResult
                       .Success(messagingContext)
                       .WithJournalAsync(entry));
            }
            catch (CryptographicException exception)
            {
                var description = "Signature verification failed";

                if (messagingContext.AS4Message.IsEncrypted)
                {
                    Logger.Error(
                        "Signature verification failed because the received message is still encrypted. "
                        + "Make sure that you specify <Decryption/> information in the <Security/> element of the "
                        + "ReceivingPMode so the ebMS MessagingHeader is first decrypted before it's signature gets verified");

                    description = "Signature verification failed because the message is still encrypted";
                }

                Logger.Error($"{messagingContext.LogTag} An exception occured while validating the signature: {exception.Message}");
                return(InvalidSignatureResult(
                           description,
                           ErrorAlias.FailedAuthentication,
                           messagingContext));
            }
        }
        /// <summary>
        /// Compress the <see cref="AS4Message" /> if required
        /// </summary>
        /// <param name="messagingContext"></param>
        /// <returns></returns>
        public async Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
        {
            if (messagingContext == null)
            {
                throw new ArgumentNullException(nameof(messagingContext));
            }

            if (messagingContext.AS4Message == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(CompressAttachmentsStep)} requires an AS4Message to compress it attachments but no AS4Message is present in the MessagingContext");
            }

            if (messagingContext.SendingPMode == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(CompressAttachmentsStep)} requires a Sending Processing Mode to use during the compression but no Sending Processing Mode is present in the MessagingContext");
            }

            if (messagingContext.SendingPMode.MessagePackaging?.UseAS4Compression == false)
            {
                Logger.Trace($"No compression will happen because the SendingPMode {messagingContext.SendingPMode.Id} MessagePackaging.UseAS4Compression is disabled");
                return(StepResult.Success(messagingContext));
            }

            try
            {
                Logger.Info($"(Outbound)[{messagingContext.AS4Message.GetPrimaryMessageId()}] Compress AS4Message attachments with GZip compression");
                messagingContext.AS4Message.CompressAttachments();
            }
            catch (SystemException exception)
            {
                const string description = "Attachments cannot be compressed because of an exception";
                Logger.Error(description);

                throw new InvalidDataException(description, exception);
            }

            JournalLogEntry journal =
                JournalLogEntry.CreateFrom(
                    messagingContext.AS4Message,
                    $"Compressed {messagingContext.AS4Message.Attachments.Count()} attachments with GZip compression");

            return(await StepResult
                   .Success(messagingContext)
                   .WithJournalAsync(journal));
        }
        /// <summary>
        /// Decompress any Attachments
        /// </summary>
        /// <param name="messagingContext"></param>
        /// <returns></returns>
        public async Task <StepResult> ExecuteAsync(MessagingContext messagingContext)
        {
            if (messagingContext == null)
            {
                throw new ArgumentNullException(nameof(messagingContext));
            }

            if (messagingContext.AS4Message == null)
            {
                throw new InvalidOperationException(
                          $"{nameof(DecompressAttachmentsStep)} requires a AS4Message but no AS4Message is present in the MessagingContext");
            }

            if (messagingContext.ReceivedMessageMustBeForwarded)
            {
                Logger.Debug("No decompression will happen because the incoming AS4Message must be forwarded unchanged");
                return(StepResult.Success(messagingContext));
            }

            if (messagingContext.AS4Message.HasAttachments == false)
            {
                Logger.Debug("No decompression will happen because the AS4Message hasn't got any attachments to decompress");
                return(StepResult.Success(messagingContext));
            }

            if (messagingContext.AS4Message.IsEncrypted)
            {
                Logger.Warn("Incoming attachmets are still encrypted will fail to decompress correctly");
            }

            try
            {
                messagingContext.AS4Message.DecompressAttachments();
                Logger.Info("(Receive) AS4Message is decompressed correctly");

                JournalLogEntry entry =
                    JournalLogEntry.CreateFrom(
                        messagingContext.AS4Message,
                        $"Decompressed {messagingContext.AS4Message.Attachments.Count()} with GZip compression");

                return(await StepResult
                       .Success(messagingContext)
                       .WithJournalAsync(entry));
            }
            catch (Exception exception)
                when(exception is ArgumentException ||
                     exception is ObjectDisposedException ||
                     exception is InvalidDataException)
                {
                    var description = "Decompression failed due to an exception";

                    if (messagingContext.AS4Message.IsEncrypted)
                    {
                        Logger.Error(
                            "Decompression failed because the incoming attachments are still encrypted. "
                            + "Make sure that you specify <Decryption/> information in the <Security/> element of the "
                            + "ReceivingPMode so the attachments are first decrypted before decompressed");

                        description = "Decompression failed because the incoming attachments are still encrypted";
                    }

                    messagingContext.ErrorResult = new ErrorResult(
                        description,
                        ErrorAlias.DecompressionFailure);

                    return(StepResult.Failed(messagingContext));
                }
        }