Просмотр исходного кода

2004-03-26 Atsushi Enomoto <[email protected]>

	* SignedXml.cs :
	  - Use specified (or default) XmlResolver to get external resource,
	    instead of using WebRequest directly. Also modified it easier.
	  - ApplyTransform() : Clone only when it is required. Handle
	    transformation output other than Stream.
	  - Even if applicable key was not found in GetHash(), don't throw
	    crypto exception every time and just return false (MS does it).
	    Throw an exception only when no key was specified as KeyInfo.
	* XmlDsigEnvelopedSignatureTransform.cs : Fixed get_OutputTypes which
	  incorrectly set InputTypes internally.
	* XmlDsigXPathTransform.cs : Context namespace nodes in loaded
	  transform parameter (i.e. <XPath>..</XPath>) should be registered
	  to XsltContext. Otherwise prefix binding error occurs.
	  Just filter attribute node, instead of filtering attribute children.

svn path=/trunk/mcs/; revision=24636
Atsushi Eno 22 лет назад
Родитель
Сommit
da7c4adefd

+ 17 - 0
mcs/class/System.Security/System.Security.Cryptography.Xml/ChangeLog

@@ -1,3 +1,20 @@
+2004-03-26  Atsushi Enomoto <[email protected]>
+
+	* SignedXml.cs :
+	  - Use specified (or default) XmlResolver to get external resource,
+	    instead of using WebRequest directly. Also modified it easier.
+	  - ApplyTransform() : Clone only when it is required. Handle 
+	    transformation output other than Stream.
+	  - Even if applicable key was not found in GetHash(), don't throw
+	    crypto exception every time and just return false (MS does it).
+	    Throw an exception only when no key was specified as KeyInfo.
+	* XmlDsigEnvelopedSignatureTransform.cs : Fixed get_OutputTypes which
+	  incorrectly set InputTypes internally.
+	* XmlDsigXPathTransform.cs : Context namespace nodes in loaded 
+	  transform parameter (i.e. <XPath>..</XPath>) should be registered
+	  to XsltContext. Otherwise prefix binding error occurs.
+	  Just filter attribute node, instead of filtering attribute children.
+
 2004-03-25  Sebastien Pouliot  <[email protected]>
 
 	* SignedXml.cs: Added try/catch in CheckSignatureWithKey to return 

+ 27 - 32
mcs/class/System.Security/System.Security.Cryptography.Xml/SignedXml.cs

@@ -28,6 +28,7 @@ namespace System.Security.Cryptography.Xml {
 		private IEnumerator pkEnumerator;
 		private XmlElement signatureElement;
 		private Hashtable hashes;
+		private XmlResolver xmlResolver = new XmlUrlResolver ();
 
 		public SignedXml () 
 		{
@@ -108,12 +109,17 @@ namespace System.Security.Cryptography.Xml {
 
 		private Stream ApplyTransform (Transform t, XmlDocument input) 
 		{
-			XmlDocument doc = (XmlDocument) input.Clone ();
+			// These transformer modify input document, which should
+			// not affect to the input itself.
+			if (t is XmlDsigXPathTransform ||
+				t is XmlDsigEnvelopedSignatureTransform)
+				input = (XmlDocument) input.Clone ();
+
+			t.LoadInput (input);
 
-			t.LoadInput (doc);
 			if (t is XmlDsigEnvelopedSignatureTransform) {
 				// It returns XmlDocument for XmlDocument input.
-				doc = (XmlDocument) t.GetOutput ();
+				XmlDocument doc = (XmlDocument) t.GetOutput ();
 				Transform c14n = GetC14NMethod ();
 				c14n.LoadInput (doc);
 				return (Stream) c14n.GetOutput ();
@@ -122,10 +128,20 @@ namespace System.Security.Cryptography.Xml {
 			object obj = t.GetOutput ();
 			if (obj is Stream)
 				return (Stream) obj;
+			else if (obj is XmlDocument) {
+				MemoryStream ms = new MemoryStream ();
+				XmlTextWriter xtw = new XmlTextWriter (ms, Encoding.UTF8);
+				((XmlDocument) obj).WriteTo (xtw);
+				return ms;
+			}
+			else if (obj == null) {
+				throw new NotImplementedException ("Should not occur. Transform is " + t + ".");
+			}
 			else {
 				// e.g. XmlDsigXPathTransform returns XmlNodeList
-				// TODO - fix
-				return null;
+				Transform c14n = GetC14NMethod ();
+				c14n.LoadInput (obj);
+				return (Stream) c14n.GetOutput ();
 			}
 		}
 
@@ -151,14 +167,12 @@ namespace System.Security.Cryptography.Xml {
 				}
 				else {
 					if (r.Uri.EndsWith (".xml")) {
-#if ! NET_1_0
 						doc.XmlResolver = xmlResolver;
-#endif						
 						doc.Load (r.Uri);
 					}
 					else {
-						WebRequest req = WebRequest.Create (r.Uri);
-						s = req.GetResponse ().GetResponseStream ();
+						if (xmlResolver != null)
+							s = (Stream) xmlResolver.GetEntity (new Uri (r.Uri), null, typeof (Stream));
 					}
 				}
 			}
@@ -252,25 +266,6 @@ namespace System.Security.Cryptography.Xml {
 			return (Stream) t.GetOutput ();
 		}
 
-/*
-		private void CollectDescendants (XmlNode n, ArrayList al)
-		{
-			switch (n.NodeType) {
-			case XmlNodeType.EntityReference:
-				break;
-			default:
-				al.Add (n);
-				break;
-			}
-
-			if (n.Attributes != null)
-				foreach (XmlAttribute a in n.Attributes)
-					al.Add (a);
-			foreach (XmlNode c in n.ChildNodes)
-				CollectDescendants (c, al);
-		}
-*/
-
 		// reuse hash - most document will always use the same hash
 		private HashAlgorithm GetHash (string algorithm) 
 		{
@@ -322,16 +317,18 @@ namespace System.Security.Cryptography.Xml {
 					return null;
 			}
 			else {
+				if (Signature.KeyInfo == null)
+					throw new CryptographicException ("At least one KeyInfo is required.");
 				// no supplied key, iterates all KeyInfo
 				while ((key = GetPublicKey ()) != null) {
 					if (CheckSignatureWithKey (key)) {
 						break;
 					}
 				}
+				pkEnumerator = null;
 				if (key == null)
-					throw new CryptographicException ("No public key found to verify the signature.");
+					return null;
 			}
-
 			// some parts may need to be downloaded
 			// so where doing it last
 			return (CheckReferenceIntegrity () ? key : null);
@@ -522,8 +519,6 @@ namespace System.Security.Cryptography.Xml {
 		}
 
 #if ! NET_1_0
-		private XmlResolver xmlResolver;
-
 		[MonoTODO("property not (yet) used in class")]
 		[ComVisible(false)]
 		public XmlResolver Resolver {

+ 6 - 3
mcs/class/System.Security/System.Security.Cryptography.Xml/XmlDsigEnvelopedSignatureTransform.cs

@@ -56,8 +56,8 @@ namespace System.Security.Cryptography.Xml {
 					lock (this) {
 						// this way the result is cached if called multiple time
 						output = new Type [2];
-						input[0] = typeof (System.Xml.XmlDocument);
-						input[1] = typeof (System.Xml.XmlNodeList);
+						output [0] = typeof (System.Xml.XmlDocument);
+						output [1] = typeof (System.Xml.XmlNodeList);
 					}
 				}
 				return output;
@@ -69,7 +69,10 @@ namespace System.Security.Cryptography.Xml {
 			return null; // THIS IS DOCUMENTED AS SUCH
 		}
 
-		[MonoTODO ("Is it really spec-compliant??")]
+		// NOTE: This method never supports the requirements written
+		// in xmldsig spec that says its input is canonicalized before
+		// transforming. This method just removes Signature element.
+		// Canonicalization is done in SignedXml.
 		public override object GetOutput ()
 		{
 			XmlDocument doc = null;

+ 9 - 1
mcs/class/System.Security/System.Security.Cryptography.Xml/XmlDsigXPathTransform.cs

@@ -95,6 +95,13 @@ namespace System.Security.Cryptography.Xml
 			}
 
 			ctx = new XmlDsigXPathContext (doc);
+			foreach (XmlNode n in xpath) {
+				XPathNavigator nav = n.CreateNavigator ();
+				XPathNodeIterator iter = nav.Select ("namespace::*");
+				while (iter.MoveNext ())
+					if (iter.Current.LocalName != "xml")
+						ctx.AddNamespace (iter.Current.LocalName, iter.Current.Value);
+			}
 			return EvaluateMatch (doc, x);
 		}
 
@@ -125,7 +132,8 @@ namespace System.Security.Cryptography.Xml
 				al.Add (n);
 			if (n.Attributes != null)
 				for (int i = 0; i < n.Attributes.Count; i++)
-					EvaluateMatch (n.Attributes [i], exp, al);
+					if (NodeMatches (n.Attributes [i], exp))
+						al.Add (n.Attributes [i]);
 			for (int i = 0; i < n.ChildNodes.Count; i++)
 				EvaluateMatch (n.ChildNodes [i], exp, al);
 		}