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