Ejemplo n.º 1
0
        protected override void InitializeFromXml()
        {
            if (ScopeName == null)
            {
                throw new ArgumentNullException(nameof(ScopeName));
            }

            var namespaceManager = ParameterNode.GetNameSpaceManager();
            var name             = XmlHelpers.GetAttributeNode(ParameterNode, "SSIS:Name")?.Value;

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new InvalidXmlException("SSIS:Name attribute can not be null or empty", ParameterNode);
            }

            var propertiesXmlElement = ParameterNode.SelectSingleNode("./SSIS:Properties", namespaceManager) as XmlElement;

            if (propertiesXmlElement == null)
            {
                throw new InvalidXmlException("Could not find collection of parameter properties", ParameterNode);
            }

            var valueXmlElement = propertiesXmlElement.SelectSingleNode("./SSIS:Property[@SSIS:Name = \"Value\"]", namespaceManager) as XmlElement;
            var value           = valueXmlElement?.InnerText;

            Name          = $"{ScopeName}::{name}";
            Value         = value;
            ParentElement = propertiesXmlElement;
            ValueElement  = valueXmlElement;
            Sensitive     = ParentElement.SelectSingleNode("./SSIS:Property[@SSIS:Name = \"Sensitive\"]", ParentElement.GetNameSpaceManager())?.InnerText == "1";

            if (valueXmlElement == null)
            {
                ValueElement = ParentElement.GetDocument().CreateElement("SSIS:Property", XmlHelpers.Schemas.SSIS);
                ValueElement.SetAttribute("Name", XmlHelpers.Schemas.SSIS, "Value");
                if (Sensitive)
                {
                    ValueElement.SetAttribute("Sensitive", XmlHelpers.Schemas.SSIS, "1");
                }
            }
            else
            {
                ValueElement = valueXmlElement;
            }

            ParameterDataType = ExtractDataType();
        }
Ejemplo n.º 2
0
        protected override void EncryptElement(XmlElement element, string password)
        {
            var rgbSalt = new byte[7];

            new RNGCryptoServiceProvider().GetBytes(rgbSalt);
            var cryptoServiceProvider = new TripleDESCryptoServiceProvider();
            var passwordDeriveBytes   = new PasswordDeriveBytes(password, rgbSalt);

            cryptoServiceProvider.Key = passwordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, cryptoServiceProvider.IV);

            var exml = new EncryptedXml();

            var encryptedElement = exml.EncryptData(element, cryptoServiceProvider, false);

            var encryptedData = new EncryptedData
            {
                Type             = EncryptedXml.XmlEncElementUrl,
                EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncTripleDESUrl),
                CipherData       = { CipherValue = encryptedElement }
            };


            // first we add it as a child, then move forward. I did not want to call an internal method (why do they make all useful methods internal?)
            // It is inconsistent at this level. For connection managers, it encrypts the entire element and just replaces the element's outer xml with encrypted node
            // For package parameters they leave original element with DTS:Name attribute, remove all other attributes such as DTS:DataType and then add encrypted element
            // as an inner xml to original element. This is what I have observed, hopefully it is at least consistentl inconsistent, and there is no third way.
            EncryptedXml.ReplaceElement(element, encryptedData, true);
            var replacementElement = element.FirstChild as XmlElement;
            var parentNode         = element.ParentNode;

            if (replacementElement != null && parentNode != null)
            {
                replacementElement.SetAttribute("Salt", Convert.ToBase64String(rgbSalt));
                replacementElement.SetAttribute("IV", Convert.ToBase64String(cryptoServiceProvider.IV));

                // if parent node is marked as sensitive, then it needs to be replaced. Otherwise leave the encrypted node where it is.
                if (XmlHelpers.GetAttributeNode(parentNode, "Sensitive")?.Value == null)
                {
                    parentNode.RemoveChild(element);
                    parentNode.AppendChild(replacementElement);
                }
            }
        }
Ejemplo n.º 3
0
        protected override void DecryptElement(XmlElement element, string password)
        {
            var saltXmlAttribute = XmlHelpers.GetAttributeNode(element, "Salt");

            if (string.IsNullOrEmpty(saltXmlAttribute?.Value))
            {
                throw new InvalidXmlException($"Encrypted node {element.Name} does not contain required Attribute \"Salt\"", element);
            }
            byte[] rgbSalt;
            try
            {
                rgbSalt = Convert.FromBase64String(saltXmlAttribute.Value);
            }
            catch (FormatException)
            {
                throw new InvalidXmlException($"Invalid value of Attribute \"Salt\" ({saltXmlAttribute.Value}) in encrypted node {element.Name} ", element);
            }
            var ivXmlAttribute = XmlHelpers.GetAttributeNode(element, "IV");

            if (string.IsNullOrEmpty(ivXmlAttribute?.Value))
            {
                throw new InvalidXmlException($"Encrypted node {element.Name} does not contain required Attribute \"IV\"", element);
            }
            byte[] numArray;
            try
            {
                numArray = Convert.FromBase64String(ivXmlAttribute.Value);
            }
            catch (FormatException)
            {
                throw new InvalidXmlException($"Invalid value of Attribute \"IV\" ({ivXmlAttribute.Value}) in encrypted node {element.Name} ", element);
            }
            var cryptoServiceProvider = new TripleDESCryptoServiceProvider {
                IV = numArray
            };

            var passwordDeriveBytes = new PasswordDeriveBytes(password, rgbSalt);

            var encryptedData = new EncryptedData();

            encryptedData.LoadXml(element);


            cryptoServiceProvider.Key = passwordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192,
                                                                           cryptoServiceProvider.IV);

            // weird edge case - if this is a parameter value, then it must replace one more parent level up
            var elementToReplace = element.ParentNode?.Name == "DTS:Property" && (element.ParentNode as XmlElement) != null && element.ParentNode?.ParentNode?.Name == "DTS:PackageParameter"
                ? (XmlElement)element.ParentNode
                : element;

            var exml = new EncryptedXml();

            try
            {
                var output = exml.DecryptData(encryptedData, cryptoServiceProvider);
                exml.ReplaceData(elementToReplace, output);
            }
            catch (CryptographicException)
            {
                throw new InvalidPaswordException();
            }
        }
Ejemplo n.º 4
0
        protected virtual void DecryptElement(XmlElement element, string password)
        {
            var saltXmlAttributeNode = XmlHelpers.GetAttributeNode(element, "Salt");

            if (string.IsNullOrEmpty(saltXmlAttributeNode?.Value))
            {
                throw new InvalidXmlException($"Encrypted element {element.Name} does not contain required Attribute \"Salt\", or its contents is empty", element);
            }
            byte[] rgbSalt;
            try
            {
                rgbSalt = Convert.FromBase64String(saltXmlAttributeNode.Value);
            }
            catch (FormatException)
            {
                throw new InvalidXmlException($"Invalid value of Attribute \"Salt\" ({saltXmlAttributeNode.Value}) in encrypted element {element.Name}", element);
            }
            var ivXmlAttributeNode = XmlHelpers.GetAttributeNode(element, "IV");

            if (string.IsNullOrEmpty(ivXmlAttributeNode?.Value))
            {
                throw new InvalidXmlException($"Encrypted element {element.Name} does not contain required Attribute \"IV\", or its contents is empty", element);
            }
            byte[] iv;
            try
            {
                iv = Convert.FromBase64String(ivXmlAttributeNode.Value);
            }
            catch (FormatException)
            {
                throw new InvalidXmlException($"Invalid value of Attribute \"IV\" ({ivXmlAttributeNode.Value}) in encrypted element {element.Name} ", element);
            }
            var cryptoServiceProvider = new TripleDESCryptoServiceProvider {
                IV = iv
            };

            var passwordDeriveBytes = new PasswordDeriveBytes(password, rgbSalt);

            cryptoServiceProvider.Key = passwordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192,
                                                                           cryptoServiceProvider.IV);
            string xml;

            byte[] buffer;
            try
            {
                buffer = Convert.FromBase64String(element.InnerText);
            }
            catch (FormatException)
            {
                throw new InvalidXmlException($"Invalid value of encrypted element {element.Name}.", element);
            }
            try
            {
                using (var memoryStream = new MemoryStream(buffer))
                {
                    using (
                        var cryptoStream = new CryptoStream(memoryStream, cryptoServiceProvider.CreateDecryptor(),
                                                            CryptoStreamMode.Read))
                    {
                        using (var streamReader = new StreamReader(cryptoStream, Encoding.UTF8))
                            xml = streamReader.ReadToEnd();
                    }
                }
            }
            catch (CryptographicException)
            {
                throw new InvalidPaswordException();
            }

            var xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(xml);

            // The reason to not simply import the new node is because namespace declaration will also be imported with the node.
            element.Attributes.Remove(saltXmlAttributeNode);
            element.Attributes.Remove(ivXmlAttributeNode);

            foreach (XmlNode childNode in element.ChildNodes)
            {
                element.RemoveChild(childNode);
            }
            element.InnerXml = xmlDocument.DocumentElement?.InnerXml;
        }