예제 #1
0
 /// <summary>
 /// Simple wrapper around peppol-sbdh module.
 /// </summary>
 /// <param name="inputStream">the inputstream containing the XML</param>
 /// <returns>an instance of Header if found, otherwise null.</returns>
 public static Header Parse(Stream inputStream)
 {
     try
     {
         using (SbdReader sbdReader = SbdReader.NewInstance(inputStream))
         {
             return(sbdReader.Header);
         }
     }
     catch (Exception ex) when(ex is SbdhException || ex is IOException)
     {
         throw new InvalidOperationException(ex.Message, ex);
     }
     finally
     {
         inputStream.Seek(0, SeekOrigin.Begin);
     }
 }
예제 #2
0
        private ITransmissionMessage Perform(Stream inputStream, Trace root)
        {
            PeekingInputStream peekingInputStream = new PeekingInputStream(inputStream);

            // Read header from content to send.
            Header header;

            try
            {
                // Read header from SBDH.
                var span = root.Child();
                span.Record(Annotations.ServiceName("Reading SBDH"));
                span.Record(Annotations.ClientSend());
                try {
                    using (SbdReader sbdReader = SbdReader.NewInstance(peekingInputStream))
                    {
                        header = sbdReader.Header;
                        span.Record(Annotations.Tag("identifier", header.Identifier.Identifier));
                    }
                } catch (SbdhException e) {
                    span.Record(Annotations.Tag("exception", e.Message));
                    throw;
                } finally {
                    span.Record(Annotations.ClientRecv());
                }

                // Create transmission request.
                return(new DefaultTransmissionMessage(header, peekingInputStream.NewInputStream()));
            }
            catch (SbdhException)
            {
                byte[] payload = peekingInputStream.GetContent();

                // Detect header from content.
                Trace span = root.Child();
                span.Record(Annotations.ServiceName("Detect SBDH from content"));
                span.Record(Annotations.ClientSend());
                try
                {
                    header = this.contentDetector.Parse(payload.ToStream());
                    span.Record(Annotations.Tag("identifier", header.Identifier.Identifier));
                }
                catch (HyperwayContentException ex)
                {
                    span.Record(Annotations.Tag("exception", ex.Message));
                    throw new HyperwayContentException(ex.Message, ex);
                }
                finally
                {
                    span.Record(Annotations.ClientRecv());
                }

                // Wrap content in SBDH.
                span = root.Child();
                span.Record(Annotations.ServiceName("Wrap content in SBDH"));
                span.Record(Annotations.ClientSend());
                Stream wrappedContent;
                try
                {
                    wrappedContent = this.contentWrapper.Wrap(payload.ToStream(), header);
                }
                catch (HyperwayContentException ex)
                {
                    span.Record(Annotations.Tag("exception", ex.Message));
                    throw;
                }
                finally
                {
                    span.Record(Annotations.ClientRecv());
                }

                // Create transmission request.
                return(new DefaultTransmissionMessage(header, wrappedContent));
            }
        }
예제 #3
0
        /// <summary>
        /// Receives an AS2 Message in the form of a map of headers together with the payload,
        /// which is made available in an input stream
        /// <p>If persisting message to the Message Repository fails, we have to return negative MDN.</p>
        /// </summary>
        /// <param name="httpHeaders">the http headers received</param>
        /// <param name="mimeMessage">supplies the MIME message</param>
        /// <returns>MDN object to signal if everything is ok or if some error occurred while receiving</returns>
        public MimeMessage Receive(IHeaderDictionary httpHeaders, MimeMessage mimeMessage)
        {
            Logger.Debug("Receiving message ..");

            SMimeReader sMimeReader = new SMimeReader(mimeMessage);

            // Get timestamp using signature as input
            Timestamp t2 = this.timestampProvider.Generate(sMimeReader.GetSignature(), Direction.IN);

            // Initiate MDN
            MdnBuilder mdnBuilder = MdnBuilder.NewInstance(mimeMessage);

            mdnBuilder.AddHeader(MdnHeader.Date, t2.GetDate());


            // Extract Message-ID
            TransmissionIdentifier transmissionIdentifier =
                TransmissionIdentifier.FromHeader(httpHeaders[As2Header.MessageId]);

            mdnBuilder.AddHeader(MdnHeader.OriginalMessageId, httpHeaders[As2Header.MessageId]);


            // Extract signed digest and digest algorithm
            SMimeDigestMethod digestMethod = sMimeReader.GetDigestMethod();

            // Extract content headers
            byte[] headerBytes = sMimeReader.GetBodyHeader();
            Stream bodyStream  = sMimeReader.GetBodyInputStream();

            byte[] bodyBytes = bodyStream.ToBuffer();

            mdnBuilder.AddHeader(MdnHeader.OriginalContentHeader, headerBytes);


            // Extract SBDH
            Mx.Peppol.Common.Model.Header header;
            bodyStream.Seek(0, SeekOrigin.Begin);
            using (var sbdReader = SbdReader.NewInstance(bodyStream))
            {
                header = sbdReader.Header;

                // Perform validation of SBDH
                this.transmissionVerifier.Verify(header, Direction.IN);

                // Extract "fresh" InputStream
                using (Stream payloadInputStream = sMimeReader.GetBodyInputStream())
                {
                    // Persist content
                    this.persisterHandler.Persist(
                        transmissionIdentifier,
                        header,
                        new UnclosableInputStream(payloadInputStream));
                }

                // Fetch calculated digest
                var    s                = SHA1.Create();
                var    hash             = s.ComputeHash(headerBytes.Concat(bodyBytes).ToArray());
                Digest calculatedDigest = Digest.Of(DigestMethod.Sha1, hash);
                mdnBuilder.AddHeader(MdnHeader.ReceivedContentMic, new Mic(calculatedDigest));

                var check = this.VerifySignature(mimeMessage.Body as MultipartSigned, out var signatures);
                if (!check || signatures.Count != 1)
                {
                    throw new NotSupportedException("Firma non valida");
                }

                var signature   = signatures[0];
                var certificate = signature.SignerCertificate as SecureMimeDigitalCertificate;
                Debug.Assert(certificate != null, nameof(certificate) + " != null");
                this.certificateValidator.Validate(Service.Ap, certificate.Certificate);

                // Create receipt (MDN)
                mdnBuilder.AddHeader(MdnHeader.Disposition, Disposition.Processed);
                MimeMessage mdn = this.sMimeMessageFactory.CreateSignedMimeMessage(mdnBuilder.Build(), digestMethod);
                mdn.Headers.Add(As2Header.As2Version, As2Header.Version);
                mdn.Headers.Add(As2Header.As2From, httpHeaders[As2Header.As2To]);
                mdn.Headers.Add(As2Header.As2To, httpHeaders[As2Header.As2From]);

                return(mdn);
            }
        }