Пример #1
0
        /// <summary>
        /// Signs a message and returns a MIME encoded array of bytes containing the signature.
        /// </summary>
        /// <param name="arMessage"></param>
        /// <param name="bPackageHeader"></param>
        /// <returns></returns>
        public static byte[] Sign(byte[] arMessage, string signerCert, string signerPassword, out string sContentType)
        {
            byte[] bInPKCS7 = new byte[0];

            // get a MIME boundary
            string sBoundary = MIMEBoundary();

            // Get the Headers for the entire message.
            sContentType = "multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=\"sha1\"; boundary=\"" + sBoundary + "\"";

            // Define the boundary byte array.
            byte[] bBoundary = ASCIIEncoding.ASCII.GetBytes(Environment.NewLine + "--" + sBoundary + Environment.NewLine);

            // Encode the header for the signature portion.
            byte[] bSignatureHeader = ASCIIEncoding.ASCII.GetBytes(MIMEHeader("application/pkcs7-signature; name=\"smime.p7s\"", "base64", "attachment; filename=smime.p7s"));

            // Get the signature.
            byte[] bSignature = AS2Encryption.Encode(arMessage, signerCert, signerPassword);

            // convert to base64
            string sig = Convert.ToBase64String(bSignature) + MESSAGE_SEPARATOR;

            bSignature = System.Text.ASCIIEncoding.ASCII.GetBytes(sig);

            // Calculate the final footer elements.
            byte[] bFinalFooter = ASCIIEncoding.ASCII.GetBytes("--" + sBoundary + "--" + Environment.NewLine);

            // Concatenate all the above together to form the message.
            bInPKCS7 = ConcatBytes(bBoundary, arMessage, bBoundary,
                                   bSignatureHeader, bSignature, bFinalFooter);

            return(bInPKCS7);
        }
Пример #2
0
        /// <summary>
        /// Processes AS2 wrapped EDI message
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="dropLocation">The drop location.</param>
        public void Process(HttpRequest request, string dropLocation)
        {
            string sTo             = request.Headers["AS2-To"];
            string sFrom           = request.Headers["AS2-From"];
            string dtf             = $"{sFrom}_{sTo}_" + DateTime.Now.ToString("ddMMyyyy_hh_mm_ss") + ".txt";
            string filename        = $"AS2_transaction_{dtf}";
            string extractfilename = $"AS2_transaction_extract_{dtf}";

            byte[] data        = request.BinaryRead(request.TotalBytes);
            bool   isEncrypted = request.ContentType.Contains("application/pkcs7-mime");
            bool   isSigned    = request.ContentType.Contains("application/pkcs7-signature");

            string message = string.Empty;

            Log.DebugFormat($"Process\n" +
                            $"\tFrom : {sFrom}\n" +
                            $"\tTo : {sTo}\n" +
                            $"\tIs Signed : {isSigned}\n" +
                            $"\tIs Encrypted : {isEncrypted}\n" +
                            $"\tContentType string : {request.ContentType}\n" +
                            $"Dump file name : {filename}\n");

            if (!isSigned && !isEncrypted) // not signed and not encrypted
            {
                message = System.Text.ASCIIEncoding.ASCII.GetString(data);
            }
            if (isEncrypted) // encrypted and signed inside
            {
                byte[] decryptedData;

                try
                {
                    Log.Debug("Decrypting......");
                    decryptedData = AS2Encryption.Decrypt(data);
                    Log.Debug("Decrypting SUCCESS.");
                }
                catch (Exception ex)
                {
                    Log.Error($"Exception during decrypting {ex.Message}");

                    if (ex.InnerException != null)
                    {
                        Log.Error($"Inner Exception during decoding {ex.InnerException.Message}");
                    }

                    throw;
                }

                string messageWithContentTypeLineAndMIMEHeaders = System.Text.ASCIIEncoding.ASCII.GetString(decryptedData);

                // when encrypted, the Content-Type line is actually stored in the start of the message
                // Require multi split done by 'ExtractPayload'
                // First segment is data payload - THIS IS EDIFACT/XML data
                // Second payload is a public key file [Not essential]
                int    firstBlankLineInMessage = messageWithContentTypeLineAndMIMEHeaders.IndexOf(Environment.NewLine + Environment.NewLine);
                string contentType             = messageWithContentTypeLineAndMIMEHeaders.Substring(0, firstBlankLineInMessage);

                message = AS2MIMEUtilities.ExtractPayload(messageWithContentTypeLineAndMIMEHeaders, contentType);

                try
                {
                    System.IO.File.WriteAllText($"{Util.ConfigValues.DropLocation}\\{extractfilename}", message);
                    Log.Debug($"Message Extract written to file {Util.ConfigValues.DropLocation}\\{extractfilename}");
                }
                catch (Exception ex)
                {
                    Log.Error($"Failed to write message extract to file : {Util.ConfigValues.DropLocation}\\{extractfilename}\n" +
                              $"Exception : {ex.Message}\n");
                }

                string signature = "";

                if (isSigned)
                {
                    //int SecondBlankLineInMessage = message.IndexOf(Environment.NewLine + Environment.NewLine);
                    int    signatureHeaderStart = message.IndexOf(Environment.NewLine + "--_");
                    string messageWithSignature = message;
                    Log.DebugFormat($"Message with embedded signature\n" +
                                    $"\tSignature start found at : {signatureHeaderStart}\n" +
                                    $"\tSignature start found invalid format : {message.IndexOf('\n' + "--_")}\n");

                    message = message.Substring(0, signatureHeaderStart);

                    string signaturePart  = messageWithSignature.Substring(signatureHeaderStart);
                    int    signatureStart = signaturePart.IndexOf(Environment.NewLine + Environment.NewLine);

                    signature = signaturePart.Substring(signatureStart + 4);

                    Log.Debug($"\n----------------------------------------------------------------------------------------------------------------------------------\n" +
                              $"Extracted EDI Message\n {message}\n" +
                              $"----------------------------------------------------------------------------------------------------------------------------------\n");

                    //TODO :: Kavisha - uncomment after testing
                    if (AS2Encryption.validateSignature(signature) == false)
                    {
                        Log.Error($"Invalid signature {signature}");
                        return;
                    }
                }
                else
                {
                    int signatureHeaderStart = message.IndexOf(Environment.NewLine + "--_");
                    // Check if it is marked inside the mesage payload
                    if (signatureHeaderStart >= 0)
                    {
                        //int SecondBlankLineInMessage = message.IndexOf(Environment.NewLine + Environment.NewLine);

                        string messageWithSignature = message;
                        Log.DebugFormat($"Message with embedded signature\n" +
                                        $"\tSignature start found at : {signatureHeaderStart}\n" +
                                        $"\tSignature start found invalid format : {message.IndexOf('\n' + "--_")}\n");

                        message = message.Substring(0, signatureHeaderStart);

                        string signaturePart  = messageWithSignature.Substring(signatureHeaderStart);
                        int    signatureStart = signaturePart.IndexOf(Environment.NewLine + Environment.NewLine);

                        signature = signaturePart.Substring(signatureStart + 4);

                        Log.Debug($"\n----------------------------------------------------------------------------------------------------------------------------------\n" +
                                  $"Extracted EDI Message\n {message}\n" +
                                  $"----------------------------------------------------------------------------------------------------------------------------------\n");

                        //TODO :: Kavisha - uncomment after testing
                        if (AS2Encryption.validateSignature(signature) == false)
                        {
                            Log.Error($"Invalid signature {signature}");
                            return;
                        }
                    }
                    else
                    {
                        Log.Error("Invalid payload [Not signed]");
                    }
                }
            }
            else
            {
                Log.Debug("Non-Encrypted..");
                if (isSigned)
                {
                    Log.Debug("Non-Encrypted signed..");
                    string messageWithMIMEHeaders = System.Text.ASCIIEncoding.ASCII.GetString(data);
                    message = AS2MIMEUtilities.ExtractPayload(messageWithMIMEHeaders, request.Headers["Content-Type"]);
                    Log.Debug($"Extracted message {message}");

                    string signaturePart = messageWithMIMEHeaders.Substring(message.Length);
                    string signature     = AS2MIMEUtilities.ExtractPayload(signaturePart, request.Headers["Content-Type"]);

                    Log.Debug($"Extracted signature {signature}");

                    if (AS2Encryption.validateSignature(signature) == false)
                    {
                        Log.Error($"Invalid signature {signature}");
                        return;
                    }
                }
            }

            try
            {
                System.IO.File.WriteAllText($"{Util.ConfigValues.DropLocation}\\{filename}", message);
            }
            catch (Exception ex)
            {
                Log.Error($"Failed to write dump to file : {Util.ConfigValues.DropLocation}\\{filename}\n" +
                          $"Exception : {ex.Message}\n");
            }

            var grammar     = EdiGrammar.NewEdiFact();
            var interchange = default(Interchange);

            using (var stream = new StreamReader($"{Util.ConfigValues.DropLocation}\\{filename}"))
            {
                Quote quoteMessage = null;
                try
                {
                    interchange  = new EdiSerializer().Deserialize <Interchange>(stream, grammar);
                    quoteMessage = interchange.QuoteMessage;
                }
                catch (Exception ex)
                {
                    Log.Error($"Content to EDI deserialization error : {ex.Message}\n" +
                              $"Payload File : {Util.ConfigValues.DropLocation}\\{filename}\n");
                    throw;
                }
                try
                {
                    if (quoteMessage != null)
                    {
                        if (quoteMessage.MessageName != "220")
                        {
                            return;
                        }

                        WebOrderHeaderModel webOrder = new WebOrderHeaderModel();
                        webOrder.AS2Identifier = request.Headers["AS2-From"];
                        quoteMessage.fillWebOrder(webOrder, interchange);
                        InsertOrderToDB(webOrder);
                        Log.Info("Order inserted ----------------");
                        Log.Info(webOrder.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Log.Error($"Order insertion error : {ex.Message}");
                    if (ex.InnerException != null)
                    {
                        Log.Error($"\tInner Exception : {ex.InnerException.Message}");
                    }
                    throw;
                }
            }
        }
Пример #3
0
        public HttpStatusCode SendFile(Uri uri, string filename, byte[] fileData, string from, string to, ProxySettings proxySettings
                                       , int timeoutMs, string signingCertFilename, string signingCertPassword, string recipientPubCertFilename /*with public key*/)
        {
            if (String.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }

            if (fileData.Length == 0)
            {
                throw new ArgumentException("filedata");
            }

            byte[] content = fileData;

            //Initialise the request
            HttpWebRequest http = (HttpWebRequest)WebRequest.Create(uri);

            if (!String.IsNullOrEmpty(proxySettings.Name))
            {
                WebProxy proxy = new WebProxy(proxySettings.Name);

                NetworkCredential proxyCredential = new NetworkCredential();
                proxyCredential.Domain   = proxySettings.Domain;
                proxyCredential.UserName = proxySettings.Username;
                proxyCredential.Password = proxySettings.Password;

                proxy.Credentials = proxyCredential;

                http.Proxy = proxy;
            }

            //Define the standard request objects
            http.Method = "POST";

            http.AllowAutoRedirect = true;

            http.KeepAlive = true;

            http.PreAuthenticate = false; //Means there will be two requests sent if Authentication required.
            http.SendChunked     = false;

            http.UserAgent = "PEERCORE AGENT";

            //These Headers are common to all transactions
            http.Headers.Add("Mime-Version", "1.0");
            http.Headers.Add("AS2-Version", "1.2");

            http.Headers.Add("AS2-From", from);
            http.Headers.Add("AS2-To", to);
            http.Headers.Add("Subject", filename);
            http.Headers.Add("Message-Id", "<AS2_" + DateTime.Now.ToString("hhmmssddd") + ">");
            http.Timeout = timeoutMs;

            string contentType = (Path.GetExtension(filename) == ".xml") ? "application/xml" : "application/EDIFACT";

            bool encrypt = !string.IsNullOrEmpty(recipientPubCertFilename);
            bool sign    = !string.IsNullOrEmpty(signingCertFilename);

            if (!sign && !encrypt)
            {
                http.Headers.Add("Content-Transfer-Encoding", "binary");
                http.Headers.Add("Content-Disposition", "inline; filename=\"" + filename + "\"");
            }
            if (sign)
            {
                // Wrap the file data with a mime header
                content = AS2MIMEUtilities.CreateMessage(contentType, "binary", "", content);

                content = AS2MIMEUtilities.Sign(content, signingCertFilename, signingCertPassword, out contentType);

                http.Headers.Add("EDIINT-Features", "multiple-attachments");
            }
            if (encrypt)
            {
                if (string.IsNullOrEmpty(recipientPubCertFilename))
                {
                    throw new ArgumentNullException(recipientPubCertFilename, "if encrytionAlgorithm is specified then recipientCertFilename must be specified");
                }

                byte[] signedContentTypeHeader           = System.Text.ASCIIEncoding.ASCII.GetBytes("Content-Type: " + contentType + Environment.NewLine);
                byte[] contentWithContentTypeHeaderAdded = AS2MIMEUtilities.ConcatBytes(signedContentTypeHeader, content);

                string ba2Str = System.Text.Encoding.Default.GetString(content);
                string s1     = System.Text.Encoding.Default.GetString(signedContentTypeHeader);
                string s2     = System.Text.Encoding.Default.GetString(contentWithContentTypeHeaderAdded);
                content = AS2Encryption.Encrypt(contentWithContentTypeHeaderAdded, recipientPubCertFilename, EncryptionAlgorithm.DES3);


                contentType += "application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
            }

            http.ContentType  += contentType;
            http.ContentLength = content.Length;

            SendWebRequest(http, content);

            return(HandleWebResponse(http));
        }
Пример #4
0
        public HttpStatusCode SendMDN(HttpRequest request, int timeoutMs, string signingCertFilename, string signingCertPassword)
        {
            try
            {
                string fileData = "This is an automated MDN";
                byte[] content  = Encoding.ASCII.GetBytes(fileData);


                OrderDataService      OrderDataServ = new OrderDataService();
                AS2CommunicationModel commDetails   = OrderDataServ.GetAS2CommunicationDetials(request.Headers["AS2-From"]);

                //Initialise the request
                HttpWebRequest http = (HttpWebRequest)WebRequest.Create(commDetails.AS2MDNURL);
                string         recipientPubCertFilename = commDetails.CertificateName;

                //Define the standard request objects
                http.Method = "POST";

                http.AllowAutoRedirect = true;

                http.KeepAlive = true;

                http.PreAuthenticate = false; //Means there will be two requests sent if Authentication required.
                http.SendChunked     = false;

                //http.UserAgent = "PEERCORE AGENT";

                //These Headers are common to all transactions
                http.Headers.Add("Mime-Version", "1.0");
                http.Headers.Add("AS2-Version", "1.2");
                //http.Headers.Add("Date", DateTime.Now.ToString());

                http.Headers.Add("AS2-From", request.Headers["AS2-To"]);
                http.Headers.Add("AS2-To", request.Headers["AS2-From"]);
                http.Headers.Add("Subject", "PO MDN");
                http.Headers.Add("Message-Id", request.Headers["Message-Id"] != null? request.Headers["Message-Id"]:"0");
                http.Timeout = timeoutMs;

                string contentType = "message/disposition-notification";

                bool encrypt = !string.IsNullOrEmpty(recipientPubCertFilename);
                bool sign    = !string.IsNullOrEmpty(signingCertFilename);

                if (!sign && !encrypt)
                {
                    http.Headers.Add("Content-Transfer-Encoding", "binary");
                    http.Headers.Add("Content-Disposition", "inline");
                }
                if (sign)
                {
                    // Wrap the file data with a mime header
                    content = AS2MIMEUtilities.CreateMessage(contentType, "binary", "", content);

                    content = AS2MIMEUtilities.Sign(content, signingCertFilename, signingCertPassword, out contentType);

                    http.Headers.Add("EDIINT-Features", "multiple-attachments");
                }
                if (encrypt)
                {
                    string certificateFullPath = "";
                    if (string.IsNullOrEmpty(recipientPubCertFilename))
                    {
                        throw new ArgumentNullException(recipientPubCertFilename, "if encrytionAlgorithm is specified then recipientCertFilename must be specified");
                    }
                    else
                    {
                        certificateFullPath = ConfigValues.CertificateFilePath + recipientPubCertFilename;
                    }

                    byte[] signedContentTypeHeader           = System.Text.ASCIIEncoding.ASCII.GetBytes("Content-Type: " + contentType + Environment.NewLine);
                    byte[] contentWithContentTypeHeaderAdded = AS2MIMEUtilities.ConcatBytes(signedContentTypeHeader, content);

                    string ba2Str = System.Text.Encoding.Default.GetString(content);
                    string s1     = System.Text.Encoding.Default.GetString(signedContentTypeHeader);
                    string s2     = System.Text.Encoding.Default.GetString(contentWithContentTypeHeaderAdded);
                    content = AS2Encryption.EncryptMDN(contentWithContentTypeHeaderAdded, certificateFullPath, EncryptionAlgorithm.DES3);

                    //  contentType += "multipart/report; report-type=disposition-notification; boundary=\"fredi.boundary.mult.sig.mdn\"; charset=utf-8";
                }

                http.ContentType  += contentType;
                http.ContentLength = content.Length;

                SendWebRequest(http, content);

                return(HandleWebResponse(http));
            }
            catch (Exception ex)
            {
                Log.Error($"Exception during sending MDN :: {ex.Message}");
                throw;
            }
        }