View Javadoc
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 }