コード例 #1
0
        public static XElement?EncryptIfNecessary(this IXmlEncryptor encryptor, XElement element)
        {
            // If no encryption is necessary, return null.
            if (!DoesElementOrDescendentRequireEncryption(element))
            {
                return(null);
            }

            // Deep copy the element (since we're going to mutate) and put
            // it into a document to guarantee it has a parent.
            var doc = new XDocument(new XElement(element));

            // We remove elements from the document as we encrypt them and perform
            // fix-up later. This keeps us from going into an infinite loop in
            // the case of a null encryptor (which returns its original input which
            // is still marked as 'requires encryption').
            var placeholderReplacements = new Dictionary <XElement, EncryptedXmlInfo>();

            while (true)
            {
                var elementWhichRequiresEncryption = doc.Descendants().FirstOrDefault(DoesSingleElementRequireEncryption);
                if (elementWhichRequiresEncryption == null)
                {
                    // All encryption is finished.
                    break;
                }

                // Encrypt the clone so that the encryptor doesn't inadvertently modify
                // the original document or other data structures.
                var clonedElementWhichRequiresEncryption = new XElement(elementWhichRequiresEncryption);
                var innerDoc         = new XDocument(clonedElementWhichRequiresEncryption);
                var encryptedXmlInfo = encryptor.Encrypt(clonedElementWhichRequiresEncryption);
                CryptoUtil.Assert(encryptedXmlInfo != null, "IXmlEncryptor.Encrypt returned null.");

                // Put a placeholder into the original document so that we can continue our
                // search for elements which need to be encrypted.
                var newPlaceholder = new XElement("placeholder");
                placeholderReplacements[newPlaceholder] = encryptedXmlInfo;
                elementWhichRequiresEncryption.ReplaceWith(newPlaceholder);
            }

            // Finally, perform fixup.
            Debug.Assert(placeholderReplacements.Count > 0);
            foreach (var entry in placeholderReplacements)
            {
                // <enc:encryptedSecret decryptorType="{type}" xmlns:enc="{ns}">
                //   <element />
                // </enc:encryptedSecret>
                entry.Key.ReplaceWith(
                    new XElement(XmlConstants.EncryptedSecretElementName,
                                 new XAttribute(XmlConstants.DecryptorTypeAttributeName, entry.Value.DecryptorType.AssemblyQualifiedName !),
                                 entry.Value.EncryptedElement));
            }
            return(doc.Root);
        }
コード例 #2
0
        public void Store(Guid keyId, XElement element)
        {
            // Encrypt the key element to the escrow encryptor.
            var encryptedXmlInfo = _escrowEncryptor.Encrypt(element);

            // A real implementation would save the escrowed key to a
            // write-only file share or some other stable storage, but
            // in this sample we'll just write it out to the console.
            Console.WriteLine($"Escrowing key {keyId}");
            Console.WriteLine(encryptedXmlInfo.EncryptedElement);

            // Note: We cannot read the escrowed key material ourselves.
            // We need to get a member of CONTOSO\Domain Admins to read
            // it for us in the event we need to recover it.
        }
コード例 #3
0
        private XElement EncryptSecret(IXmlEncryptor encryptor)
        {
            // First, create the inner <secret> element.
            XElement secretElement;

            byte[] plaintextSecret = new byte[_secret.Length];
            try
            {
                _secret.WriteSecretIntoBuffer(new ArraySegment <byte>(plaintextSecret));
                secretElement = new XElement(SecretElementName, Convert.ToBase64String(plaintextSecret));
            }
            finally
            {
                Array.Clear(plaintextSecret, 0, plaintextSecret.Length);
            }

            // Then encrypt it and wrap it in another <secret> element.
            var encryptedSecretElement = encryptor.Encrypt(secretElement);

            CryptoUtil.Assert(!String.IsNullOrEmpty((string)encryptedSecretElement.Attribute("decryptor")),
                              @"TODO: <secret> encryption was invalid.");

            return(new XElement(SecretElementName, encryptedSecretElement));
        }