1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright  1999-2004 The Apache Software Foundation.
   7  *
   8  *  Licensed under the Apache License, Version 2.0 (the "License");
   9  *  you may not use this file except in compliance with the License.
  10  *  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  *  Unless required by applicable law or agreed to in writing, software
  15  *  distributed under the License is distributed on an "AS IS" BASIS,
  16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  *  See the License for the specific language governing permissions and
  18  *  limitations under the License.
  19  *
  20  */
  21 package com.sun.org.apache.xml.internal.security.utils.resolver.implementations;
  22 
  23 
  24 
  25 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
  26 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
  27 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
  28 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
  29 import org.w3c.dom.Attr;
  30 import org.w3c.dom.Document;
  31 import org.w3c.dom.Element;
  32 import org.w3c.dom.Node;
  33 
  34 
  35 /**
  36  * This resolver is used for resolving same-document URIs like URI="" of URI="#id".
  37  *
  38  * @author $Author: mullan $
  39  * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#sec-ReferenceProcessingModel">The Reference processing model in the XML Signature spec</A>
  40  * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#sec-Same-Document">Same-Document URI-References in the XML Signature spec</A>
  41  * @see <A HREF="http://www.ietf.org/rfc/rfc2396.txt">Section 4.2 of RFC 2396</A>
  42  */
  43 public class ResolverFragment extends ResourceResolverSpi {
  44 
  45    /** {@link java.util.logging} logging facility */
  46     static java.util.logging.Logger log =
  47         java.util.logging.Logger.getLogger(
  48                             ResolverFragment.class.getName());
  49    public boolean engineIsThreadSafe() {
  50            return true;
  51    }
  52    /**
  53     * Method engineResolve
  54     *
  55     * @inheritDoc
  56     * @param uri
  57     * @param baseURI
  58     */
  59    public XMLSignatureInput engineResolve(Attr uri, String baseURI)
  60        throws ResourceResolverException
  61    {
  62         String uriNodeValue = uri.getNodeValue();
  63         Document doc = uri.getOwnerElement().getOwnerDocument();
  64 
  65         Node selectedElem = null;
  66         if (uriNodeValue.equals("")) {
  67 
  68            /*
  69             * Identifies the node-set (minus any comment nodes) of the XML
  70             * resource containing the signature
  71             */
  72 
  73             log.log(java.util.logging.Level.FINE, "ResolverFragment with empty URI (means complete document)");
  74             selectedElem = doc;
  75         } else {
  76 
  77             /*
  78              * URI="#chapter1"
  79              * Identifies a node-set containing the element with ID attribute
  80              * value 'chapter1' of the XML resource containing the signature.
  81              * XML Signature (and its applications) modify this node-set to
  82              * include the element plus all descendents including namespaces and
  83              * attributes -- but not comments.
  84              */
  85             String id = uriNodeValue.substring(1);
  86 
  87             selectedElem = doc.getElementById(id);
  88             if (selectedElem == null) {
  89                 Object exArgs[] = { id };
  90                 throw new ResourceResolverException(
  91                     "signature.Verification.MissingID", exArgs, uri, baseURI);
  92             }
  93             if (secureValidation) {
  94                 Element start = uri.getOwnerDocument().getDocumentElement();
  95                 if (!XMLUtils.protectAgainstWrappingAttack(start, id)) {
  96                     Object exArgs[] = { id };
  97                     throw new ResourceResolverException(
  98                         "signature.Verification.MultipleIDs", exArgs,
  99                         uri, baseURI);
 100                 }
 101             }
 102             if (log.isLoggable(java.util.logging.Level.FINE))
 103                 log.log(java.util.logging.Level.FINE, "Try to catch an Element with ID " + id + " and Element was " + selectedElem);
 104         }
 105 
 106         XMLSignatureInput result = new XMLSignatureInput(selectedElem);
 107         result.setExcludeComments(true);
 108 
 109         result.setMIMEType("text/xml");
 110         if (baseURI != null && baseURI.length() > 0) {
 111             result.setSourceURI(baseURI.concat(uri.getNodeValue()));
 112         } else {
 113             result.setSourceURI(uri.getNodeValue());
 114         }
 115         return result;
 116     }
 117 
 118    /**
 119     * Method engineCanResolve
 120     * @inheritDoc
 121     * @param uri
 122     * @param BaseURI
 123     *
 124     */
 125    public boolean engineCanResolve(Attr uri, String BaseURI) {
 126 
 127       if (uri == null) {
 128          log.log(java.util.logging.Level.FINE, "Quick fail for null uri");
 129          return false;
 130       }
 131 
 132       String uriNodeValue = uri.getNodeValue();
 133 
 134       if  (uriNodeValue.equals("") ||
 135              (
 136             (uriNodeValue.charAt(0)=='#')
 137               && !((uriNodeValue.charAt(1)=='x') && uriNodeValue.startsWith("#xpointer("))
 138               )
 139            ){
 140          if (log.isLoggable(java.util.logging.Level.FINE))
 141                 log.log(java.util.logging.Level.FINE, "State I can resolve reference: \"" + uriNodeValue + "\"");
 142          return true;
 143       }
 144       if (log.isLoggable(java.util.logging.Level.FINE))
 145         log.log(java.util.logging.Level.FINE, "Do not seem to be able to resolve reference: \"" + uriNodeValue + "\"");
 146       return false;
 147    }
 148 
 149 }