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)); } }
/// <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)); }
public Task <StepResult> ExecuteAsync(MessagingContext messagingContext) { return(StepResult .Failed(messagingContext) .WithJournalAsync( JournalLogEntry.CreateFrom( messagingContext.AS4Message, "Log entry 3"))); }
/// <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))); }
/// <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)); }
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"))); }
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)); } }