/* * Processes a signed Multipart. */ private void ProcessSignedMultipart(MultipartSigned signedMultipart, Node entityNode) { // Creating cryptographic context. using (var ctx = new GnuPrivacyContext()) { // Adding signatures. ProcessSignatures(entityNode, signedMultipart.Verify(ctx)); // Looping through all entities in Multipart, processing recursively. foreach (var idxEntity in signedMultipart) { ProcessEntity(idxEntity, entityNode); } } }
/* * Processes a signed multipart. */ void ProcessSignedMultipart(MultipartSigned signedMultipart, Node entityNode) { // Creating cryptographic context. using (var ctx = _context.RaiseEvent( ".p5.crypto.pgp-keys.context.create", new Node("", false)).Get <OpenPgpContext> (_context)) { // Adding signatures. ProcessSignatures(entityNode, signedMultipart.Verify(ctx)); // Looping through all entities in Multipart, processing recursively. foreach (var idxEntity in signedMultipart) { // Processing currently iterated MIME part. ProcessEntity(idxEntity, entityNode); } } }
protected ITransmissionResponse HandleResponse(HttpResponse httpResponse) { Trace span = this.root.Child(); // tracer.newChild(root.context()).name("response").start(); span.Record(Annotations.ServiceName("response")); span.Record(Annotations.ClientSend()); try { HttpResponse response = httpResponse; span.Record(Annotations.Tag("code", response.StatusCode.ToString())); // span.tag("code", String.valueOf(response.getStatusLine().getStatusCode())); if (response.StatusCode != HttpStatusCode.OK) { Logger.ErrorFormat( "AS2 HTTP POST expected HTTP OK, but got : {0} from {1}", response.StatusCode, this.transmissionRequest.GetEndpoint().Address); // Throws exception this.HandleFailedRequest(response); } // handle normal HTTP OK response Logger.DebugFormat( "AS2 transmission to {0} returned HTTP OK, verify MDN response", this.transmissionRequest.GetEndpoint().Address); string contentTypeHeader = response.Headers["Content-Type"]; if (string.IsNullOrWhiteSpace(contentTypeHeader)) { throw new HyperwayTransmissionException( "No Content-Type header in response, probably a server error."); } // Read MIME Message MimeMessage mimeMessage; using (var m = new MemoryStream()) { // Add headers to MIME Message foreach (var headerName in response.Headers.AllKeys) { var headerText = $"{headerName}: {response.Headers[headerName]}"; var headerData = Encoding.ASCII.GetBytes(headerText); m.Write(headerData, 0, headerData.Length); m.Write(new byte[] { 13, 10 }, 0, 2); } m.Write(new byte[] { 13, 10 }, 0, 2); var messageData = response.Entity.Content; m.Write(messageData, 0, messageData.Length); m.Seek(0, SeekOrigin.Begin); mimeMessage = MimeMessage.Load(m); mimeMessage.Headers[HeaderId.ContentType] = response.Headers["Content-Type"]; } SMimeReader sMimeReader = new SMimeReader(mimeMessage); // Timestamp of reception of MDN Timestamp t3 = this.timestampProvider.Generate(sMimeReader.GetSignature(), Direction.OUT); MultipartSigned signedMessage = mimeMessage.Body as MultipartSigned; using (this.secureMimeContext()) { Debug.Assert(signedMessage != null, nameof(signedMessage) + " != null"); var signatures = signedMessage.Verify(); var signature = signatures.First(); var mimeCertificate = signature.SignerCertificate as SecureMimeDigitalCertificate; // Verify if the certificate used by the receiving Access Point in // the response message does not match its certificate published by the SMP Debug.Assert(mimeCertificate != null, nameof(mimeCertificate) + " != null"); X509Certificate certificate = mimeCertificate.Certificate; if (!this.transmissionRequest.GetEndpoint().Certificate.Equals(certificate)) { throw new HyperwayTransmissionException( String.Format( "Certificate in MDN ('{0}') does not match certificate from SMP ('{1}').", certificate.SubjectDN, // .getSubjectX500Principal().getName(), this.transmissionRequest.GetEndpoint().Certificate.SubjectDN)); // .getSubjectX500Principal().getName())); } Logger.Debug("MDN signature was verified for : " + certificate.SubjectDN); } // Verifies the actual MDN MdnMimeMessageInspector mdnMimeMessageInspector = new MdnMimeMessageInspector(mimeMessage); String msg = mdnMimeMessageInspector.GetPlainTextPartAsText(); if (!mdnMimeMessageInspector.IsOkOrWarning(new Mic(this.outboundMic))) { Logger.ErrorFormat("AS2 transmission failed with some error message '{0}'.", msg); throw new HyperwayTransmissionException(String.Format("AS2 transmission failed : {0}", msg)); } // Read structured content MimeEntity mimeBodyPart = mdnMimeMessageInspector.GetMessageDispositionNotificationPart(); var internetHeaders = mimeBodyPart.Headers; // InternetHeaders internetHeaders = new InternetHeaders((InputStream)mimeBodyPart.getContent()); // Fetch timestamp if set DateTime date = t3.GetDate(); if (internetHeaders.Any(x => x.Field == MdnHeader.Date)) { var dateText = internetHeaders.First(x => x.Field == MdnHeader.Date).Value; date = As2DateUtil.Rfc822.Parse(dateText); } // Return TransmissionResponse return(new As2TransmissionResponse( this.transmissionIdentifier, this.transmissionRequest, this.outboundMic, MimeMessageHelper.ToBytes(mimeMessage), t3, date)); } catch (TimestampException e) { throw new HyperwayTransmissionException(e.Message, e); } catch (Exception e) { throw new HyperwayTransmissionException("Unable to parse received content.", e); } finally { span.Record(Annotations.ClientRecv()); } }
/* * extracts body parts from message and put into node */ private static void ExtractBody( IEnumerable <MimeEntity> entities, Node node, bool skipSignature, MimeMessage msg, string basePath, string attachmentDirectory, string linkedAttachmentDirectory) { foreach (MimeEntity idxBody in entities) { if (idxBody is TextPart) { TextPart tp = idxBody as TextPart; if (idxBody.ContentType.MediaType == "text") { if (idxBody.ContentType.MediaSubtype == "plain") { node["body"]["plain"].Value = tp.Text; } else if (idxBody.ContentType.MediaSubtype == "html") { node["body"]["html"].Value = CleanHtml(tp.Text); } } } else if (idxBody is ApplicationPkcs7Mime) { ApplicationPkcs7Mime pkcs7 = idxBody as ApplicationPkcs7Mime; if (pkcs7.SecureMimeType == SecureMimeType.EnvelopedData) { try { MimeEntity entity = pkcs7.Decrypt(); ExtractBody(new MimeEntity[] { entity }, node, false, msg, basePath, attachmentDirectory, linkedAttachmentDirectory); node["encrypted"].Value = true; } catch (Exception err) { // couldn't decrypt node["body"]["plain"].Value = "couldn't decrypt message, exceptions was; '" + err.Message + "'"; node["encrypted"].Value = true; } } } else if (!skipSignature && idxBody is MultipartSigned) { MultipartSigned signed = idxBody as MultipartSigned; bool valid = false; foreach (IDigitalSignature signature in signed.Verify()) { valid = signature.Verify(); if (!valid) { break; } } node["signed"].Value = valid; ExtractBody(new MimeEntity[] { signed }, node, true, msg, basePath, attachmentDirectory, linkedAttachmentDirectory); } else if (idxBody is Multipart) { Multipart mp = idxBody as Multipart; ExtractBody(mp, node, false, msg, basePath, attachmentDirectory, linkedAttachmentDirectory); } else if (idxBody is MimePart) { // this is an attachment ExtractAttachments(idxBody as MimePart, msg, node, basePath, attachmentDirectory, linkedAttachmentDirectory); } } }