You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by ra...@apache.org on 2006/08/07 14:46:16 UTC

svn commit: r429317 - in /xml/security/trunk: CHANGELOG.txt src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java src/org/apache/xml/security/signature/XMLSignatureInput.java

Author: raul
Date: Mon Aug  7 05:46:14 2006
New Revision: 429317

URL: http://svn.apache.org/viewvc?rev=429317&view=rev
Log:
Optimization in RetrievelMethod handling don't reparse the bytes into a DOM tree if not needed thanks David Garcia.

Added:
    xml/security/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
Modified:
    xml/security/trunk/CHANGELOG.txt
    xml/security/trunk/src/org/apache/xml/security/signature/XMLSignatureInput.java

Modified: xml/security/trunk/CHANGELOG.txt
URL: http://svn.apache.org/viewvc/xml/security/trunk/CHANGELOG.txt?rev=429317&r1=429316&r2=429317&view=diff
==============================================================================
--- xml/security/trunk/CHANGELOG.txt (original)
+++ xml/security/trunk/CHANGELOG.txt Mon Aug  7 05:46:14 2006
@@ -35,6 +35,7 @@
 	Optimization in c14n in node-sets.
 	Optimization for the xml:* inheritance in inclusive the c14n.
 	Added ECDSA signature thanks Markus Lindner 
+	Optimization in RetrievelMethod handling don't reparse the bytes into a DOM tree if not needed thanks David Garcia.
 	    
 		
 New in v1.3

Added: xml/security/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java?rev=429317&view=auto
==============================================================================
--- xml/security/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java (added)
+++ xml/security/trunk/src/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java Mon Aug  7 05:46:14 2006
@@ -0,0 +1,314 @@
+/*
+ * Copyright  1999-2004 The Apache Software Foundation.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.xml.security.keys.keyresolver.implementations;
+
+
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xml.security.c14n.CanonicalizationException;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.content.RetrievalMethod;
+import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
+import org.apache.xml.security.keys.keyresolver.KeyResolver;
+import org.apache.xml.security.keys.keyresolver.KeyResolverException;
+import org.apache.xml.security.keys.keyresolver.KeyResolverSpi;
+import org.apache.xml.security.keys.storage.StorageResolver;
+import org.apache.xml.security.signature.XMLSignatureInput;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.apache.xml.security.utils.resolver.ResourceResolver;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+
+/**
+ * The RetrievalMethodResolver can retrieve public keys and certificates from
+ * other locations. The location is specified using the ds:RetrievalMethod
+ * element which points to the location. This includes the handling of raw
+ * (binary) X.509 certificate which are not encapsulated in an XML structure.
+ * If the retrieval process encounters an element which the
+ * RetrievalMethodResolver cannot handle itself, resolving of the extracted
+ * element is delegated back to the KeyResolver mechanism.
+ *
+ * @author $Author: raul $ modified by Dave Garcia
+ */
+public class RetrievalMethodResolver extends KeyResolverSpi {
+
+   /** {@link org.apache.commons.logging} logging facility */
+    static org.apache.commons.logging.Log log = 
+        org.apache.commons.logging.LogFactory.getLog(
+                        RetrievalMethodResolver.class.getName());
+
+   /**
+    * Method engineResolvePublicKey
+    * @inheritDoc
+    * @param element
+    * @param BaseURI
+    * @param storage
+    *
+    */
+   public PublicKey engineResolvePublicKey(
+           Element element, String BaseURI, StorageResolver storage)
+              {
+	   if  (!XMLUtils.elementIsInSignatureSpace(element,
+               Constants._TAG_RETRIEVALMETHOD)) {      
+		   return null;
+	   }
+
+      try {
+		   //Create a retrieval method over the given element
+		   RetrievalMethod rm = new RetrievalMethod(element, BaseURI);
+	       String type = rm.getType();		   
+		   XMLSignatureInput resource=this.resolveInput(rm,BaseURI);			
+           if (RetrievalMethod.TYPE_RAWX509.equals(type)) {
+                //a raw certificate, direct parsing is done!
+            	X509Certificate cert=this.getRawCertificate(resource);
+				if (cert != null) {
+			         return cert.getPublicKey();
+			    }
+				return null;
+            };
+			Element e = obtainRefrenceElement(resource);
+			return this.resolveKey(e,BaseURI,storage);
+	  } catch (XMLSecurityException ex) {
+         log.debug("XMLSecurityException", ex);
+      } catch (CertificateException ex) {
+         log.debug("CertificateException", ex);
+      } catch (IOException ex) {
+         log.debug("IOException", ex);
+      } catch (ParserConfigurationException e) {
+		  log.debug("ParserConfigurationException", e);
+	  } catch (SAXException e) {
+		 log.debug("SAXException", e);
+	  } 
+      return null;
+   }
+
+   private Element obtainRefrenceElement(XMLSignatureInput resource) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException, KeyResolverException {
+	   Element e;
+	   if (resource.isElement()){
+		   e=(Element) resource.getSubNode();
+	   } else if (resource.isNodeSet()) {
+		   //Retrieved resource is a nodeSet
+		   e=getDocumentElement(resource.getNodeSet());							   
+	   } else {
+		   //Retrieved resource is an inputStream
+		   byte inputBytes[] = resource.getBytes();
+		   e = this.getDocFromBytes(inputBytes);						
+		   //otherwise, we parse the resource, create an Element and delegate
+		   if (log.isDebugEnabled()) 
+			   log.debug("we have to parse " + inputBytes.length + " bytes");
+	   }
+	   return e;
+   }
+
+   /**
+    * Method engineResolveX509Certificate
+    * @inheritDoc
+    * @param element
+    * @param BaseURI
+    * @param storage
+    *
+    */
+   public X509Certificate engineResolveX509Certificate(
+           Element element, String BaseURI, StorageResolver storage)
+              {
+	   if  (!XMLUtils.elementIsInSignatureSpace(element,
+               Constants._TAG_RETRIEVALMETHOD)) {      
+		   return null;
+	   }
+
+	   try {
+         RetrievalMethod rm = new RetrievalMethod(element, BaseURI);
+		 String type = rm.getType();		   
+		 XMLSignatureInput resource=this.resolveInput(rm,BaseURI);			         
+		 if (RetrievalMethod.TYPE_RAWX509.equals(type)) {
+        	X509Certificate cert=this.getRawCertificate(resource);
+            return cert;
+		 } 
+		 Element e = obtainRefrenceElement(resource);
+		 return this.resolveCertificate(e,BaseURI,storage);
+      } catch (XMLSecurityException ex) {
+         log.debug("XMLSecurityException", ex);
+      } catch (CertificateException ex) {
+         log.debug("CertificateException", ex);
+      } catch (IOException ex) {
+         log.debug("IOException", ex);
+	  } catch (ParserConfigurationException e) {
+		  log.debug("ParserConfigurationException", e);
+	  } catch (SAXException e) {
+		 log.debug("SAXException", e);
+	  } 
+      return null;
+   }
+   
+   /**
+    * Retrieves a x509Certificate from the given information
+    * @param e
+    * @param BaseURI
+    * @param storage
+    * @return
+    * @throws KeyResolverException 
+    */
+   private X509Certificate resolveCertificate(Element e,String BaseURI,StorageResolver storage) throws KeyResolverException{
+		  if (log.isDebugEnabled()) 
+			  log.debug("Now we have a {" + e.getNamespaceURI() + "}"+ e.getLocalName() + " Element");
+		  //An element has been provided
+       	  if (e != null) { 
+			  return KeyResolver.getX509Certificate(e,BaseURI, storage);		  	  
+   		  }
+		  return null;
+   } 
+   
+   /**
+    * Retrieves a x509Certificate from the given information
+    * @param e
+    * @param BaseURI
+    * @param storage
+    * @return
+    * @throws KeyResolverException 
+    */
+   private PublicKey resolveKey(Element e,String BaseURI,StorageResolver storage) throws KeyResolverException{
+		  if (log.isDebugEnabled()) 
+			  log.debug("Now we have a {" + e.getNamespaceURI() + "}"+ e.getLocalName() + " Element");
+		  //An element has been provided
+       	  if (e != null) { 
+			  return KeyResolver.getPublicKey(e,BaseURI, storage);		  	  
+   		  }
+		  return null;
+   }
+
+   private X509Certificate getRawCertificate(XMLSignatureInput resource) throws CanonicalizationException, IOException, CertificateException{
+	   byte inputBytes[] = resource.getBytes();	   
+       // if the resource stores a raw certificate, we have to handle it
+       CertificateFactory certFact =CertificateFactory.getInstance(XMLX509Certificate.JCA_CERT_ID);
+       X509Certificate cert =(X509Certificate) certFact.generateCertificate(new ByteArrayInputStream(inputBytes));
+       return cert;
+   }
+   /**
+    * Resolves the input from the given retrieval method 
+    * @return
+    * @throws XMLSecurityException 
+    */
+   private XMLSignatureInput resolveInput(RetrievalMethod rm,String BaseURI) throws XMLSecurityException{
+       Attr uri = rm.getURIAttr();
+	   //Apply the trnasforms
+       Transforms transforms = rm.getTransforms();
+       ResourceResolver resRes = ResourceResolver.getInstance(uri, BaseURI);
+       if (resRes != null) {
+          XMLSignatureInput resource = resRes.resolve(uri, BaseURI);
+          if (transforms != null) {
+        	  log.debug("We have Transforms");
+			  resource = transforms.performTransforms(resource);
+          }		  
+		  return resource;
+       }
+	   return null;
+   }
+   
+   /**
+    * Parses a byte array and returns the parsed Element.
+    *
+    * @param bytes
+    * @return the Document Element after parsing bytes 
+    * @throws KeyResolverException if something goes wrong
+    */
+   Element getDocFromBytes(byte[] bytes) throws KeyResolverException {
+      try {
+         javax.xml.parsers.DocumentBuilderFactory dbf =javax.xml.parsers.DocumentBuilderFactory.newInstance();
+         dbf.setNamespaceAware(true);
+         javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
+         org.w3c.dom.Document doc =
+            db.parse(new java.io.ByteArrayInputStream(bytes));
+         return doc.getDocumentElement();
+      } catch (org.xml.sax.SAXException ex) {
+         throw new KeyResolverException("empty", ex);
+      } catch (java.io.IOException ex) {
+         throw new KeyResolverException("empty", ex);
+      } catch (javax.xml.parsers.ParserConfigurationException ex) {
+         throw new KeyResolverException("empty", ex);
+      }
+   }
+
+   /**
+    * Method engineResolveSecretKey
+    * @inheritDoc
+    * @param element
+    * @param BaseURI
+    * @param storage
+    *
+    */
+   public javax.crypto.SecretKey engineResolveSecretKey(
+           Element element, String BaseURI, StorageResolver storage)
+   {
+      return null;
+   }
+   
+   static Element getDocumentElement(Set set) {
+	   Iterator it=set.iterator();
+	   Element e=null;
+	   while (it.hasNext()) {
+		   Node currentNode=(Node)it.next();
+		   if (currentNode instanceof Element) {
+			   e=(Element)currentNode;
+			   break;
+		   }
+		   
+	   }
+	   List parents=new ArrayList(10);
+  		
+  		//Obtain all the parents of the elemnt
+  		Element parent=e;
+  		while (parent!=null) {
+  			parents.add(parent);
+  			Node n=parent.getParentNode();
+  			if (!(n instanceof Element )) {
+  				break;
+  			}
+  			parent=(Element)n;
+  		}
+  		//Visit them in reverse order.
+  		boolean firstFound=false;
+  		ListIterator it2=parents.listIterator(parents.size());
+  		while (it2.hasPrevious()) {
+  			Element ele=(Element)it2.previous();
+  			if (set.contains(ele)) {
+  				if (firstFound)
+  					return ele;
+  				firstFound=true;
+  			}
+     	}
+		return null;
+   }
+}
+

Modified: xml/security/trunk/src/org/apache/xml/security/signature/XMLSignatureInput.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src/org/apache/xml/security/signature/XMLSignatureInput.java?rev=429317&r1=429316&r2=429317&view=diff
==============================================================================
--- xml/security/trunk/src/org/apache/xml/security/signature/XMLSignatureInput.java (original)
+++ xml/security/trunk/src/org/apache/xml/security/signature/XMLSignatureInput.java Mon Aug  7 05:46:14 2006
@@ -235,7 +235,7 @@
       if (this._inputNodeSet!=null) {
       	  return this._inputNodeSet;
       }
-   	  if (this.isElement()) {
+   	  if ((this._inputOctetStreamProxy==null)&& (this._subNode!=null) ) {
             
    	  	    if (circunvent) {           
    	  	    	XMLUtils.circumventBug2650(XMLUtils.getOwnerDocument(_subNode));