| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 | using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Xml;using System.Diagnostics;using System.Reflection;using System.Security.Cryptography;using Aitex.Core.RT.Log;namespace Aitex.Core.Util{    /// <summary>    /// This class provides a set of static APIs that add digital signature to Xml files and verify if Xml files    /// or Xml memory streams have valid signature.    /// </summary>    public static class FileSigner    {        /* This API didn't pass unit test. Will be uncommented in the future.        /// <summary>        /// Checks to see if the memory stream is a valid xml stream with valid signature.        /// </summary>        /// <param name="stream"></param>        /// <returns>False if the stream is empty or null, or embedded signature doesn't match, or there is no the signature.</returns>        public static bool IsValid(Stream stream)        {            bool retVal = false;            try            {                Logger.LogTrace(MethodBase.GetCurrentMethod(), Logger.TraceEntry);                XmlDocument doc = new XmlDocument();                doc.Load(stream);                Debug.Assert(doc != null && doc.DocumentElement != null);                // Get root element                XmlElement elemRoot = doc.DocumentElement;                // Get signature element                XmlElement elemSignature = elemRoot["Signature"];                if (elemSignature == null)                {                    return false; // The stream was not signed.                }                // Remove signature element from document                elemRoot.RemoveChild(elemSignature);                // Calculate hash code from file (after removing Signature element)                UnicodeEncoding ue = new UnicodeEncoding();                SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();                char[] innerXMLArray = elemRoot.InnerXml.ToCharArray();                byte[] bytes = ue.GetBytes(innerXMLArray);                // byte[] signature = sha1.ComputeHash(ue.GetBytes(elemRoot.InnerXml));                byte[] signature = sha1.ComputeHash(bytes);                string strSignature = Convert.ToBase64String(signature);                // Add signature back to document                elemRoot.AppendChild(elemSignature);                // Compare embedded signature to calculated value                if (elemSignature.InnerText == strSignature)                {                    retVal = true;                }            }            catch (System.Exception ex)            {                retVal = false;                Logger.LogError(MethodBase.GetCurrentMethod(), ex);                throw;            }            finally            {                Logger.LogTrace(MethodBase.GetCurrentMethod(), Logger.TraceExit);            }            return retVal;        }        */        /// <summary>        /// Checks to see if the file is a valid xml file with valid signature.        /// </summary>        /// <param name="fileName"></param>        /// <returns>False if the embedded signature doesn't match, or there is no the signature.</returns>        public static bool IsValid(string fileName)        {            bool retVal = false;            try            {                XmlDocument doc = new XmlDocument();                doc.Load(fileName);                Debug.Assert(doc != null && doc.DocumentElement != null);                // Get root element                XmlElement elemRoot = doc.DocumentElement;                // Get signature element                XmlElement elemSignature = elemRoot["Signature"];                if (elemSignature == null)                {                    return false; // The file was not signed.                }                // Remove signature element from document                elemRoot.RemoveChild(elemSignature);                // Calculate hash code from file (after removing Signature element)                UnicodeEncoding ue = new UnicodeEncoding();                SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();                byte[] signature = sha1.ComputeHash(ue.GetBytes(elemRoot.InnerXml));                string strSignature = Convert.ToBase64String(signature);                // Add signature back to document                elemRoot.AppendChild(elemSignature);                // Compare embedded signature to calculated value                if (elemSignature.InnerText == strSignature)                {                    retVal = true;                }            }            catch (System.Exception e)            {                retVal = false;                LOG.WriteExeption(e);                throw;            }            finally            {            }            return retVal;        }        /* This API didn't pass unit test. Will be uncommented in the future.        /// <summary>        /// Add signature to the end of the xml memory stream        /// </summary>        /// <param name="stream"></param>        /// <returns></returns>        public static Stream Sign(Stream stream)        {            try            {                Logger.LogTrace(MethodBase.GetCurrentMethod(), Logger.TraceEntry);                XmlDocument doc = new XmlDocument();                if (stream == null || stream.Length == 0)                {                    throw new InvalidOperationException("Empty stream, no XML file to Sign");                }                else                {                    doc.Load(stream);                    XmlElement elemRoot = doc.DocumentElement;                    // Remove any existing signature                    XmlElement elemSignature = elemRoot["Signature"];                    if (elemSignature != null)                    {                        elemRoot.RemoveChild(elemSignature);                    }                    // Calculate hash code (after removing Signature element)                    UnicodeEncoding ue = new UnicodeEncoding();                    SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();                    char[] innerXMLArray = elemRoot.InnerXml.ToCharArray();                    byte[] bytes = ue.GetBytes(innerXMLArray);                    // byte[] nSignature = sha1.ComputeHash(ue.GetBytes(elemRoot.InnerXml));                    byte[] nSignature = sha1.ComputeHash(bytes);                    string strSignature = Convert.ToBase64String(nSignature);                    // Add signature to XML document                    elemSignature = doc.CreateElement("Signature");                    elemSignature.InnerText = strSignature;                    elemRoot.AppendChild(elemSignature);                    // memStream.Flush();                    stream.Seek(0, SeekOrigin.Begin);                    doc.Save(stream);                    return stream;                }            }            catch (Exception ex)            {                Logger.LogError(MethodBase.GetCurrentMethod(), ex);                throw;            }            finally            {                Logger.LogTrace(MethodBase.GetCurrentMethod(), Logger.TraceExit);            }        }        */        /// <summary>        /// Add signature to the end of the xml file.         /// </summary>        /// <param name="fileName"></param>        public static void Sign(string fileName)        {            try            {                XmlDocument doc = new XmlDocument();                bool writeable = true;                if (File.Exists(fileName) && (File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)                {                    writeable = false;                    File.SetAttributes(fileName, FileAttributes.Normal);                }                doc.Load(fileName);                XmlElement elemRoot = doc.DocumentElement;                // Remove any existing signature                XmlElement elemSignature = elemRoot["Signature"];                if (elemSignature != null)                {                    elemRoot.RemoveChild(elemSignature);                }                // Calculate hash code (after removing Signature element)                UnicodeEncoding ue = new UnicodeEncoding();                SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();                byte[] nSignature = sha1.ComputeHash(ue.GetBytes(elemRoot.InnerXml));                string strSignature = Convert.ToBase64String(nSignature);                // Add signature to XML document                elemSignature = doc.CreateElement("Signature");                elemSignature.InnerText = strSignature;                elemRoot.AppendChild(elemSignature);                doc.Save(fileName);                if (!writeable)                {                    File.SetAttributes(fileName, FileAttributes.ReadOnly);                }            }            catch (Exception ex)            {                LOG.WriteExeption(ex);                throw;            }            finally            {            }        }    }}
 |