Merge pull request #2024 from BogdanovKirill/webrequesttest
[mono.git] / mcs / class / System.Security / System.Security.Cryptography.Xml / XmlDecryptionTransform.cs
index a656454ac02aec44c59a3d19e28d47a99d9a7057..154061b1949adb39a9440c3b1b8277e33d52fa48 100644 (file)
@@ -6,11 +6,34 @@
 //
 // Copyright (C) Tim Coleman, 2004
 
-#if NET_2_0
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 
+using System.Collections;
+using System.IO;
 using System.Xml;
 
 namespace System.Security.Cryptography.Xml {
+
        public class XmlDecryptionTransform : Transform {
 
                #region Fields
@@ -18,14 +41,20 @@ namespace System.Security.Cryptography.Xml {
                EncryptedXml encryptedXml;
                Type[] inputTypes;
                Type[] outputTypes;
+               object inputObj;
+               ArrayList exceptUris;
+
+               const string NamespaceUri = "http://www.w3.org/2002/07/decrypt#";
 
                #endregion // Fields
 
                #region Constructors
        
                public XmlDecryptionTransform ()
-                       : base ()
                {
+                       Algorithm = XmlSignature.AlgorithmNamespaces.XmlDecryptionTransform;
+                       encryptedXml = new EncryptedXml ();
+                       exceptUris = new ArrayList ();
                }
        
                #endregion // Constructors
@@ -39,22 +68,18 @@ namespace System.Security.Cryptography.Xml {
 
                public override Type[] InputTypes {
                        get { 
-                               if (inputTypes == null) {
-                                       lock (this) {
-                                               inputTypes = new Type [3] {typeof (System.IO.Stream), typeof (System.Xml.XmlNodeList), typeof (System.Xml.XmlDocument)}; 
-                                       }
-                               }
+                               if (inputTypes == null)
+                                       inputTypes = new Type [2] {typeof (System.IO.Stream), typeof (System.Xml.XmlDocument)}; 
+
                                return inputTypes;
                        }
                }
 
                public override Type[] OutputTypes {
                        get { 
-                               if (outputTypes == null) {
-                                       lock (this) {
-                                               outputTypes = new Type [2] {typeof (System.Xml.XmlDocument), typeof (System.Xml.XmlNodeList)};
-                                       }
-                               }
+                               if (outputTypes == null)
+                                       outputTypes = new Type [1] {typeof (System.Xml.XmlDocument)};
+
                                return outputTypes;
                        }
                }
@@ -63,44 +88,107 @@ namespace System.Security.Cryptography.Xml {
 
                #region Methods
 
-               [MonoTODO]
+               public void AddExceptUri (string uri)
+               {
+                       exceptUris.Add (uri);
+               }
+
+               private void ClearExceptUris ()
+               {
+                       exceptUris.Clear ();
+               }
+
+               [MonoTODO ("Verify")]
                protected override XmlNodeList GetInnerXml ()
                {
-                       throw new NotImplementedException ();
+                       XmlDocument doc = new XmlDocument ();
+                       doc.AppendChild (doc.CreateElement ("DecryptionTransform"));
+
+                       foreach (object o in exceptUris) {
+                               XmlElement element = doc.CreateElement ("Except", NamespaceUri);
+                               element.Attributes.Append (doc.CreateAttribute ("URI", NamespaceUri));
+                               element.Attributes ["URI", NamespaceUri].Value = (string) o;
+                               doc.DocumentElement.AppendChild (element);
+                       }
+
+                       return doc.GetElementsByTagName ("Except", NamespaceUri);
                }
 
-               [MonoTODO]
+               [MonoTODO ("Verify processing of ExceptURIs")]
                public override object GetOutput ()
                {
-                       throw new NotImplementedException ();
+                       XmlDocument document;
+                       if (inputObj is Stream) {
+                               document = new XmlDocument ();
+                               document.PreserveWhitespace = true;
+                               document.XmlResolver = GetResolver ();
+                               document.Load (new XmlSignatureStreamReader (
+                                       new StreamReader (inputObj as Stream)));
+                       }
+                       else if (inputObj is XmlDocument) {
+                               document = inputObj as XmlDocument;
+                       }
+                       else
+                               throw new NullReferenceException ();
+
+                       XmlNodeList nodes = document.GetElementsByTagName ("EncryptedData", EncryptedXml.XmlEncNamespaceUrl);
+                       foreach (XmlNode node in nodes) {
+                               if (node == document.DocumentElement && exceptUris.Contains ("#xpointer(/)"))
+                                       break;
+
+                               // Need to exclude based on ExceptURI.  Only accept #id references.
+                               foreach (string uri in exceptUris) 
+                                       if (IsTargetElement ((XmlElement) node, uri.Substring (1)))
+                                               break;
+
+                               EncryptedData encryptedData = new EncryptedData ();
+                               encryptedData.LoadXml ((XmlElement) node);
+                               SymmetricAlgorithm symAlg = EncryptedXml.GetDecryptionKey (encryptedData, encryptedData.EncryptionMethod.KeyAlgorithm);
+                               EncryptedXml.ReplaceData ((XmlElement) node, EncryptedXml.DecryptData (encryptedData, symAlg));
+                       }
+
+                       return document;
                }
 
-               [MonoTODO]
                public override object GetOutput (Type type)
-               {
-                       throw new NotImplementedException ();
+               {       
+                       if (type == typeof (Stream))
+                               return GetOutput ();
+                       throw new ArgumentException ("type");
                }
 
-               [MonoTODO]
+               [MonoTODO ("verify")]
                protected virtual bool IsTargetElement (XmlElement inputElement, string idValue)
                {
-                       throw new NotImplementedException ();
+                       if ((inputElement == null) || (idValue == null))
+                               return false;
+                       return (inputElement.Attributes ["id"].Value == idValue);
                }
 
-               [MonoTODO]
+               [MonoTODO ("This doesn't seem to work in .NET")]
                public override void LoadInnerXml (XmlNodeList nodeList)
                {
-                       throw new NotImplementedException ();
+                       if (nodeList == null)
+                               throw new NullReferenceException ();
+
+                       ClearExceptUris ();
+                       foreach (XmlNode node in nodeList) {
+                               XmlElement element = node as XmlElement;
+                               if (element.NamespaceURI.Equals (NamespaceUri) && element.LocalName.Equals ("Except")) {
+                                       string uri = element.Attributes ["URI", NamespaceUri].Value;
+                                       if (!uri.StartsWith ("#"))
+                                               throw new CryptographicException ("A Uri attribute is required for a CipherReference element.");
+                                       AddExceptUri (uri);
+                               }
+                       }
                }
 
-               [MonoTODO]
                public override void LoadInput (object obj)
                {
-                       throw new NotImplementedException ();
+                       inputObj = obj;
                }
 
                #endregion // Methods
        }
 }
 
-#endif