1 // 2 // Unit tests for XmlDecryptionTransform 3 // 4 // Author: 5 // Sebastien Pouliot <sebastien@ximian.com> 6 // 7 // Copyright (C) 2008 Novell, Inc (http://www.novell.com) 8 // 9 // Licensed to the .NET Foundation under one or more agreements. 10 // See the LICENSE file in the project root for more information. 11 12 using System.IO; 13 using System.Xml; 14 using Xunit; 15 16 namespace System.Security.Cryptography.Xml.Tests 17 { 18 19 public class UnprotectedXmlDecryptionTransform : XmlDecryptionTransform 20 { UnprotectedIsTargetElement(XmlElement inputElement, string idValue)21 public bool UnprotectedIsTargetElement(XmlElement inputElement, string idValue) 22 { 23 return base.IsTargetElement(inputElement, idValue); 24 } 25 UnprotectedGetInnerXml()26 public XmlNodeList UnprotectedGetInnerXml() 27 { 28 return base.GetInnerXml(); 29 } 30 } 31 32 public class XmlDecryptionTransformTest 33 { 34 private UnprotectedXmlDecryptionTransform transform; 35 XmlDecryptionTransformTest()36 public XmlDecryptionTransformTest() 37 { 38 transform = new UnprotectedXmlDecryptionTransform(); 39 } 40 41 [Fact] IsTargetElement_XmlElementNull()42 public void IsTargetElement_XmlElementNull() 43 { 44 Assert.False(transform.UnprotectedIsTargetElement(null, "value")); 45 } 46 47 [Fact] IsTargetElement_StringNull()48 public void IsTargetElement_StringNull() 49 { 50 XmlDocument doc = new XmlDocument(); 51 Assert.False(transform.UnprotectedIsTargetElement(doc.DocumentElement, null)); 52 } 53 54 [Theory] 55 [InlineData("<a id=\"1\" />", "1", true)] 56 [InlineData("<a ID=\"1\" />", "1", true)] 57 [InlineData("<a Id=\"1\" />", "1", true)] 58 [InlineData("<a iD=\"1\" />", "1", false)] 59 [InlineData("<a id=\"1\" />", "2", false)] IsTargetElement_ValidXml(string xml, string id, bool expectedResult)60 public void IsTargetElement_ValidXml(string xml, string id, bool expectedResult) 61 { 62 XmlDocument doc = new XmlDocument(); 63 doc.LoadXml(xml); 64 65 Assert.Equal(expectedResult, transform.UnprotectedIsTargetElement(doc.DocumentElement, id)); 66 } 67 68 [Fact] AddExceptUri_Null()69 public void AddExceptUri_Null() 70 { 71 Assert.Throws<ArgumentNullException>(() => transform.AddExceptUri(null)); 72 } 73 74 [Fact] EncryptedXml_NotNull()75 public void EncryptedXml_NotNull() 76 { 77 Assert.NotNull(transform.EncryptedXml); 78 } 79 80 [Fact] InputTypes()81 public void InputTypes() 82 { 83 Type[] inputTypes = transform.InputTypes; 84 85 Assert.Equal(2, inputTypes.Length); 86 Assert.Contains(typeof(Stream), inputTypes); 87 Assert.Contains(typeof(XmlDocument), inputTypes); 88 } 89 90 [Fact] OutputTypes()91 public void OutputTypes() 92 { 93 Type[] outputTypes = transform.OutputTypes; 94 95 Assert.Equal(1, outputTypes.Length); 96 Assert.Contains(typeof(XmlDocument), outputTypes); 97 } 98 99 [Fact] LoadInnerXml_XmlNull()100 public void LoadInnerXml_XmlNull() 101 { 102 Assert.Throws<CryptographicException>(() => transform.LoadInnerXml(null)); 103 } 104 105 [Fact] LoadInnerXml_XmlNoExcept()106 public void LoadInnerXml_XmlNoExcept() 107 { 108 XmlDocument doc = new XmlDocument(); 109 doc.LoadXml("<a />"); 110 111 transform.LoadInnerXml(doc.ChildNodes); 112 113 Assert.Null(transform.UnprotectedGetInnerXml()); 114 } 115 116 [Fact] LoadInnerXml_XmlNoUriForExcept()117 public void LoadInnerXml_XmlNoUriForExcept() 118 { 119 XmlDocument doc = new XmlDocument(); 120 doc.LoadXml(@"<dcrpt:Except xmlns:dcrpt=""http://www.w3.org/2002/07/decrypt#""/>"); 121 122 Assert.Throws<CryptographicException>(() => transform.LoadInnerXml(doc.ChildNodes)); 123 } 124 125 [Fact] LoadInnerXml_XmlValidUriForExcept()126 public void LoadInnerXml_XmlValidUriForExcept() 127 { 128 XmlDocument doc = new XmlDocument(); 129 doc.LoadXml(@"<dcrpt:Except URI=""#item1"" xmlns:dcrpt=""http://www.w3.org/2002/07/decrypt#""/>"); 130 131 transform.LoadInnerXml(doc.ChildNodes); 132 133 Assert.NotNull(transform.UnprotectedGetInnerXml()); 134 } 135 136 [Fact] 137 [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "https://github.com/dotnet/corefx/issues/16798")] LoadStreamInput_CorrectXml()138 public void LoadStreamInput_CorrectXml() 139 { 140 XmlDocument doc = new XmlDocument(); 141 string xml = "<root><a /><b /></root>"; 142 doc.LoadXml(xml); 143 144 using (MemoryStream memoryStream = new MemoryStream()) 145 using (StreamWriter streamWriter = new StreamWriter(memoryStream, Text.Encoding.Unicode)) 146 { 147 streamWriter.Write(xml); 148 streamWriter.Flush(); 149 memoryStream.Position = 0; 150 151 transform.LoadInput(memoryStream); 152 XmlDocument output = (XmlDocument)transform.GetOutput(); 153 154 Assert.Equal(xml, output.OuterXml); 155 } 156 } 157 158 [Fact] GetOutput_WrongType()159 public void GetOutput_WrongType() 160 { 161 XmlDocument doc = new XmlDocument(); 162 string xml = "<test />"; 163 doc.LoadXml(xml); 164 165 transform.LoadInput(doc); 166 AssertExtensions.Throws<ArgumentException>("type", () => transform.GetOutput(typeof(string))); 167 } 168 169 [Fact] 170 [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "https://github.com/dotnet/corefx/issues/16798")] GetOutput_XmlNoEncryptedData()171 public void GetOutput_XmlNoEncryptedData() 172 { 173 XmlDocument doc = new XmlDocument(); 174 string xml = "<test />"; 175 doc.LoadXml(xml); 176 177 transform.LoadInput(doc); 178 XmlDocument transformedDocument = (XmlDocument)transform.GetOutput(typeof(XmlDocument)); 179 180 Assert.Equal(xml, transformedDocument.OuterXml); 181 } 182 183 [Fact] 184 [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "https://github.com/dotnet/corefx/issues/16798")] GetOutput_XmlWithEncryptedData()185 public void GetOutput_XmlWithEncryptedData() 186 { 187 XmlDocument doc = new XmlDocument(); 188 string xml = "<root><a /><b /><c>To Be Encrypted</c><d /></root>"; 189 doc.LoadXml(xml); 190 191 XmlDocument transformedDocument = GetTransformedOutput(doc, "c"); 192 193 Assert.NotNull(transformedDocument); 194 Assert.Equal(xml, transformedDocument.OuterXml); 195 } 196 197 [Fact] 198 [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "https://github.com/dotnet/corefx/issues/16798")] GetOutput_XmlWithEncryptedDataInRoot()199 public void GetOutput_XmlWithEncryptedDataInRoot() 200 { 201 XmlDocument doc = new XmlDocument(); 202 string xml = "<root>To Be Encrypted</root>"; 203 doc.LoadXml(xml); 204 205 XmlDocument transformedDocument = GetTransformedOutput(doc, "//root"); 206 207 Assert.NotNull(transformedDocument); 208 Assert.Equal(xml, transformedDocument.OuterXml); 209 } 210 211 [Fact] 212 [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "https://github.com/dotnet/corefx/issues/16798")] GetOutput_XmlWithEncryptedDataAndExcept()213 public void GetOutput_XmlWithEncryptedDataAndExcept() 214 { 215 XmlDocument doc = new XmlDocument(); 216 string xml = "<root><a /><b /><c>To Be Encrypted</c><d /></root>"; 217 doc.LoadXml(xml); 218 219 transform.AddExceptUri("#_notfound"); 220 transform.AddExceptUri("#_0"); 221 XmlDocument transformedDocument = GetTransformedOutput(doc, "c"); 222 223 XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(doc.NameTable); 224 xmlNamespaceManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); 225 Assert.NotNull(transformedDocument.DocumentElement.SelectSingleNode("//enc:EncryptedData", xmlNamespaceManager)); 226 Assert.NotEqual(xml, transformedDocument.OuterXml); 227 } 228 GetTransformedOutput(XmlDocument doc, string nodeToEncrypt)229 private XmlDocument GetTransformedOutput(XmlDocument doc, string nodeToEncrypt) 230 { 231 using (var aesAlgo = Aes.Create()) 232 { 233 var encryptedXml = new EncryptedXml(); 234 encryptedXml.AddKeyNameMapping("aes", aesAlgo); 235 XmlElement elementToEncrypt = (XmlElement)doc.DocumentElement.SelectSingleNode(nodeToEncrypt); 236 EncryptedData encryptedData = encryptedXml.Encrypt(elementToEncrypt, "aes"); 237 EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); 238 239 XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(doc.NameTable); 240 xmlNamespaceManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); 241 XmlElement encryptedNode = (XmlElement)doc.DocumentElement.SelectSingleNode("//enc:EncryptedData", xmlNamespaceManager); 242 encryptedNode.SetAttribute("ID", "#_0"); 243 244 transform.LoadInput(doc); 245 transform.EncryptedXml = encryptedXml; 246 XmlDocument transformedDocument = (XmlDocument)transform.GetOutput(); 247 248 transform.EncryptedXml = null; 249 250 return transformedDocument; 251 } 252 } 253 } 254 } 255 256