author | darcy |
Tue, 03 May 2016 10:40:54 -0700 | |
changeset 37782 | ad8fe7507ecc |
parent 27081 | 1ceee8d3844d |
permissions | -rw-r--r-- |
2 | 1 |
/* |
2 |
* reserved comment block |
|
3 |
* DO NOT REMOVE OR ALTER! |
|
4 |
*/ |
|
18240 | 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 |
|
2 | 13 |
* |
18240 | 14 |
* http://www.apache.org/licenses/LICENSE-2.0 |
2 | 15 |
* |
18240 | 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. |
|
2 | 22 |
*/ |
23 |
package com.sun.org.apache.xml.internal.security.c14n; |
|
24 |
||
25 |
import java.io.ByteArrayInputStream; |
|
18240 | 26 |
import java.io.InputStream; |
2 | 27 |
import java.io.OutputStream; |
28 |
import java.util.Map; |
|
29 |
import java.util.Set; |
|
18240 | 30 |
import java.util.concurrent.ConcurrentHashMap; |
2 | 31 |
|
18240 | 32 |
import javax.xml.XMLConstants; |
2 | 33 |
import javax.xml.parsers.DocumentBuilder; |
34 |
import javax.xml.parsers.DocumentBuilderFactory; |
|
35 |
||
18240 | 36 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments; |
37 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_WithComments; |
|
38 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclOmitComments; |
|
39 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315ExclWithComments; |
|
40 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments; |
|
41 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments; |
|
18780
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
42 |
import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerPhysical; |
2 | 43 |
import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException; |
27081 | 44 |
import com.sun.org.apache.xml.internal.security.utils.JavaUtils; |
2 | 45 |
import org.w3c.dom.Document; |
46 |
import org.w3c.dom.Node; |
|
47 |
import org.w3c.dom.NodeList; |
|
48 |
import org.xml.sax.InputSource; |
|
49 |
||
50 |
/** |
|
51 |
* |
|
52 |
* @author Christian Geuer-Pollmann |
|
53 |
*/ |
|
54 |
public class Canonicalizer { |
|
55 |
||
1337 | 56 |
/** The output encoding of canonicalized data */ |
57 |
public static final String ENCODING = "UTF8"; |
|
2 | 58 |
|
1337 | 59 |
/** |
18240 | 60 |
* XPath Expression for selecting every node and continuous comments joined |
1337 | 61 |
* in only one node |
2 | 62 |
*/ |
1337 | 63 |
public static final String XPATH_C14N_WITH_COMMENTS_SINGLE_NODE = |
64 |
"(.//. | .//@* | .//namespace::*)"; |
|
2 | 65 |
|
1337 | 66 |
/** |
2 | 67 |
* The URL defined in XML-SEC Rec for inclusive c14n <b>without</b> comments. |
68 |
*/ |
|
1337 | 69 |
public static final String ALGO_ID_C14N_OMIT_COMMENTS = |
70 |
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; |
|
71 |
/** |
|
72 |
* The URL defined in XML-SEC Rec for inclusive c14n <b>with</b> comments. |
|
73 |
*/ |
|
74 |
public static final String ALGO_ID_C14N_WITH_COMMENTS = |
|
75 |
ALGO_ID_C14N_OMIT_COMMENTS + "#WithComments"; |
|
76 |
/** |
|
77 |
* The URL defined in XML-SEC Rec for exclusive c14n <b>without</b> comments. |
|
78 |
*/ |
|
79 |
public static final String ALGO_ID_C14N_EXCL_OMIT_COMMENTS = |
|
80 |
"http://www.w3.org/2001/10/xml-exc-c14n#"; |
|
81 |
/** |
|
82 |
* The URL defined in XML-SEC Rec for exclusive c14n <b>with</b> comments. |
|
83 |
*/ |
|
84 |
public static final String ALGO_ID_C14N_EXCL_WITH_COMMENTS = |
|
85 |
ALGO_ID_C14N_EXCL_OMIT_COMMENTS + "WithComments"; |
|
86 |
/** |
|
87 |
* The URI for inclusive c14n 1.1 <b>without</b> comments. |
|
88 |
*/ |
|
89 |
public static final String ALGO_ID_C14N11_OMIT_COMMENTS = |
|
90 |
"http://www.w3.org/2006/12/xml-c14n11"; |
|
91 |
/** |
|
92 |
* The URI for inclusive c14n 1.1 <b>with</b> comments. |
|
93 |
*/ |
|
94 |
public static final String ALGO_ID_C14N11_WITH_COMMENTS = |
|
95 |
ALGO_ID_C14N11_OMIT_COMMENTS + "#WithComments"; |
|
18780
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
96 |
/** |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
97 |
* Non-standard algorithm to serialize the physical representation for XML Encryption |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
98 |
*/ |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
99 |
public static final String ALGO_ID_C14N_PHYSICAL = |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
100 |
"http://santuario.apache.org/c14n/physical"; |
2 | 101 |
|
18240 | 102 |
private static Map<String, Class<? extends CanonicalizerSpi>> canonicalizerHash = |
103 |
new ConcurrentHashMap<String, Class<? extends CanonicalizerSpi>>(); |
|
1337 | 104 |
|
18240 | 105 |
private final CanonicalizerSpi canonicalizerSpi; |
2 | 106 |
|
1337 | 107 |
/** |
108 |
* Constructor Canonicalizer |
|
109 |
* |
|
110 |
* @param algorithmURI |
|
111 |
* @throws InvalidCanonicalizerException |
|
112 |
*/ |
|
18240 | 113 |
private Canonicalizer(String algorithmURI) throws InvalidCanonicalizerException { |
1337 | 114 |
try { |
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
115 |
Class<? extends CanonicalizerSpi> implementingClass = |
18240 | 116 |
canonicalizerHash.get(algorithmURI); |
2 | 117 |
|
37782
ad8fe7507ecc
6850612: Deprecate Class.newInstance since it violates the checked exception language contract
darcy
parents:
27081
diff
changeset
|
118 |
@SuppressWarnings("deprecation") |
ad8fe7507ecc
6850612: Deprecate Class.newInstance since it violates the checked exception language contract
darcy
parents:
27081
diff
changeset
|
119 |
CanonicalizerSpi tmp = implementingClass.newInstance(); |
ad8fe7507ecc
6850612: Deprecate Class.newInstance since it violates the checked exception language contract
darcy
parents:
27081
diff
changeset
|
120 |
canonicalizerSpi = tmp; |
18240 | 121 |
canonicalizerSpi.reset = true; |
1337 | 122 |
} catch (Exception e) { |
123 |
Object exArgs[] = { algorithmURI }; |
|
124 |
throw new InvalidCanonicalizerException( |
|
18240 | 125 |
"signature.Canonicalizer.UnknownCanonicalizer", exArgs, e |
126 |
); |
|
1337 | 127 |
} |
128 |
} |
|
2 | 129 |
|
1337 | 130 |
/** |
131 |
* Method getInstance |
|
132 |
* |
|
133 |
* @param algorithmURI |
|
18240 | 134 |
* @return a Canonicalizer instance ready for the job |
1337 | 135 |
* @throws InvalidCanonicalizerException |
136 |
*/ |
|
137 |
public static final Canonicalizer getInstance(String algorithmURI) |
|
18240 | 138 |
throws InvalidCanonicalizerException { |
139 |
return new Canonicalizer(algorithmURI); |
|
1337 | 140 |
} |
2 | 141 |
|
1337 | 142 |
/** |
143 |
* Method register |
|
144 |
* |
|
145 |
* @param algorithmURI |
|
146 |
* @param implementingClass |
|
147 |
* @throws AlgorithmAlreadyRegisteredException |
|
27081 | 148 |
* @throws SecurityException if a security manager is installed and the |
149 |
* caller does not have permission to register the canonicalizer |
|
1337 | 150 |
*/ |
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
151 |
@SuppressWarnings("unchecked") |
1337 | 152 |
public static void register(String algorithmURI, String implementingClass) |
18240 | 153 |
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException { |
27081 | 154 |
JavaUtils.checkRegisterPermission(); |
18240 | 155 |
// check whether URI is already registered |
156 |
Class<? extends CanonicalizerSpi> registeredClass = |
|
157 |
canonicalizerHash.get(algorithmURI); |
|
158 |
||
159 |
if (registeredClass != null) { |
|
160 |
Object exArgs[] = { algorithmURI, registeredClass }; |
|
161 |
throw new AlgorithmAlreadyRegisteredException("algorithm.alreadyRegistered", exArgs); |
|
162 |
} |
|
2 | 163 |
|
18240 | 164 |
canonicalizerHash.put( |
165 |
algorithmURI, (Class<? extends CanonicalizerSpi>)Class.forName(implementingClass) |
|
166 |
); |
|
167 |
} |
|
168 |
||
169 |
/** |
|
170 |
* Method register |
|
171 |
* |
|
172 |
* @param algorithmURI |
|
173 |
* @param implementingClass |
|
174 |
* @throws AlgorithmAlreadyRegisteredException |
|
27081 | 175 |
* @throws SecurityException if a security manager is installed and the |
176 |
* caller does not have permission to register the canonicalizer |
|
18240 | 177 |
*/ |
27081 | 178 |
public static void register(String algorithmURI, Class<? extends CanonicalizerSpi> implementingClass) |
18240 | 179 |
throws AlgorithmAlreadyRegisteredException, ClassNotFoundException { |
27081 | 180 |
JavaUtils.checkRegisterPermission(); |
1337 | 181 |
// check whether URI is already registered |
18240 | 182 |
Class<? extends CanonicalizerSpi> registeredClass = canonicalizerHash.get(algorithmURI); |
2 | 183 |
|
1337 | 184 |
if (registeredClass != null) { |
185 |
Object exArgs[] = { algorithmURI, registeredClass }; |
|
18240 | 186 |
throw new AlgorithmAlreadyRegisteredException("algorithm.alreadyRegistered", exArgs); |
1337 | 187 |
} |
2 | 188 |
|
18240 | 189 |
canonicalizerHash.put(algorithmURI, implementingClass); |
190 |
} |
|
191 |
||
192 |
/** |
|
193 |
* This method registers the default algorithms. |
|
194 |
*/ |
|
195 |
public static void registerDefaultAlgorithms() { |
|
196 |
canonicalizerHash.put( |
|
197 |
Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS, |
|
198 |
Canonicalizer20010315OmitComments.class |
|
199 |
); |
|
200 |
canonicalizerHash.put( |
|
201 |
Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS, |
|
202 |
Canonicalizer20010315WithComments.class |
|
203 |
); |
|
204 |
canonicalizerHash.put( |
|
205 |
Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS, |
|
206 |
Canonicalizer20010315ExclOmitComments.class |
|
207 |
); |
|
208 |
canonicalizerHash.put( |
|
209 |
Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS, |
|
210 |
Canonicalizer20010315ExclWithComments.class |
|
211 |
); |
|
212 |
canonicalizerHash.put( |
|
213 |
Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS, |
|
214 |
Canonicalizer11_OmitComments.class |
|
215 |
); |
|
216 |
canonicalizerHash.put( |
|
217 |
Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS, |
|
218 |
Canonicalizer11_WithComments.class |
|
219 |
); |
|
18780
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
220 |
canonicalizerHash.put( |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
221 |
Canonicalizer.ALGO_ID_C14N_PHYSICAL, |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
222 |
CanonicalizerPhysical.class |
f47b920867e7
8011547: Update XML Signature implementation to Apache Santuario 1.5.4
mullan
parents:
18240
diff
changeset
|
223 |
); |
1337 | 224 |
} |
2 | 225 |
|
1337 | 226 |
/** |
227 |
* Method getURI |
|
228 |
* |
|
229 |
* @return the URI defined for this c14n instance. |
|
230 |
*/ |
|
231 |
public final String getURI() { |
|
18240 | 232 |
return canonicalizerSpi.engineGetURI(); |
1337 | 233 |
} |
2 | 234 |
|
1337 | 235 |
/** |
236 |
* Method getIncludeComments |
|
237 |
* |
|
238 |
* @return true if the c14n respect the comments. |
|
239 |
*/ |
|
240 |
public boolean getIncludeComments() { |
|
18240 | 241 |
return canonicalizerSpi.engineGetIncludeComments(); |
1337 | 242 |
} |
2 | 243 |
|
1337 | 244 |
/** |
245 |
* This method tries to canonicalize the given bytes. It's possible to even |
|
246 |
* canonicalize non-wellformed sequences if they are well-formed after being |
|
247 |
* wrapped with a <CODE>>a<...>/a<</CODE>. |
|
248 |
* |
|
249 |
* @param inputBytes |
|
18240 | 250 |
* @return the result of the canonicalization. |
1337 | 251 |
* @throws CanonicalizationException |
252 |
* @throws java.io.IOException |
|
253 |
* @throws javax.xml.parsers.ParserConfigurationException |
|
254 |
* @throws org.xml.sax.SAXException |
|
255 |
*/ |
|
256 |
public byte[] canonicalize(byte[] inputBytes) |
|
18240 | 257 |
throws javax.xml.parsers.ParserConfigurationException, |
258 |
java.io.IOException, org.xml.sax.SAXException, CanonicalizationException { |
|
259 |
InputStream bais = new ByteArrayInputStream(inputBytes); |
|
1337 | 260 |
InputSource in = new InputSource(bais); |
261 |
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); |
|
18240 | 262 |
dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); |
2 | 263 |
|
1337 | 264 |
dfactory.setNamespaceAware(true); |
2 | 265 |
|
18240 | 266 |
// needs to validate for ID attribute normalization |
1337 | 267 |
dfactory.setValidating(true); |
2 | 268 |
|
1337 | 269 |
DocumentBuilder db = dfactory.newDocumentBuilder(); |
2 | 270 |
|
1337 | 271 |
/* |
272 |
* for some of the test vectors from the specification, |
|
18240 | 273 |
* there has to be a validating parser for ID attributes, default |
1337 | 274 |
* attribute values, NMTOKENS, etc. |
18240 | 275 |
* Unfortunately, the test vectors do use different DTDs or |
1337 | 276 |
* even no DTD. So Xerces 1.3.1 fires many warnings about using |
277 |
* ErrorHandlers. |
|
278 |
* |
|
279 |
* Text from the spec: |
|
280 |
* |
|
281 |
* The input octet stream MUST contain a well-formed XML document, |
|
282 |
* but the input need not be validated. However, the attribute |
|
283 |
* value normalization and entity reference resolution MUST be |
|
284 |
* performed in accordance with the behaviors of a validating |
|
285 |
* XML processor. As well, nodes for default attributes (declared |
|
286 |
* in the ATTLIST with an AttValue but not specified) are created |
|
287 |
* in each element. Thus, the declarations in the document type |
|
288 |
* declaration are used to help create the canonical form, even |
|
289 |
* though the document type declaration is not retained in the |
|
290 |
* canonical form. |
|
291 |
*/ |
|
18240 | 292 |
db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils.IgnoreAllErrorHandler()); |
2 | 293 |
|
1337 | 294 |
Document document = db.parse(in); |
18240 | 295 |
return this.canonicalizeSubtree(document); |
1337 | 296 |
} |
2 | 297 |
|
1337 | 298 |
/** |
299 |
* Canonicalizes the subtree rooted by <CODE>node</CODE>. |
|
300 |
* |
|
18240 | 301 |
* @param node The node to canonicalize |
1337 | 302 |
* @return the result of the c14n. |
303 |
* |
|
304 |
* @throws CanonicalizationException |
|
305 |
*/ |
|
18240 | 306 |
public byte[] canonicalizeSubtree(Node node) throws CanonicalizationException { |
307 |
return canonicalizerSpi.engineCanonicalizeSubTree(node); |
|
1337 | 308 |
} |
2 | 309 |
|
1337 | 310 |
/** |
311 |
* Canonicalizes the subtree rooted by <CODE>node</CODE>. |
|
312 |
* |
|
313 |
* @param node |
|
314 |
* @param inclusiveNamespaces |
|
315 |
* @return the result of the c14n. |
|
316 |
* @throws CanonicalizationException |
|
317 |
*/ |
|
318 |
public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces) |
|
18240 | 319 |
throws CanonicalizationException { |
320 |
return canonicalizerSpi.engineCanonicalizeSubTree(node, inclusiveNamespaces); |
|
1337 | 321 |
} |
2 | 322 |
|
1337 | 323 |
/** |
324 |
* Canonicalizes an XPath node set. The <CODE>xpathNodeSet</CODE> is treated |
|
325 |
* as a list of XPath nodes, not as a list of subtrees. |
|
326 |
* |
|
327 |
* @param xpathNodeSet |
|
328 |
* @return the result of the c14n. |
|
329 |
* @throws CanonicalizationException |
|
330 |
*/ |
|
331 |
public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet) |
|
18240 | 332 |
throws CanonicalizationException { |
333 |
return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); |
|
1337 | 334 |
} |
2 | 335 |
|
1337 | 336 |
/** |
337 |
* Canonicalizes an XPath node set. The <CODE>xpathNodeSet</CODE> is treated |
|
338 |
* as a list of XPath nodes, not as a list of subtrees. |
|
339 |
* |
|
340 |
* @param xpathNodeSet |
|
341 |
* @param inclusiveNamespaces |
|
342 |
* @return the result of the c14n. |
|
343 |
* @throws CanonicalizationException |
|
344 |
*/ |
|
345 |
public byte[] canonicalizeXPathNodeSet( |
|
18240 | 346 |
NodeList xpathNodeSet, String inclusiveNamespaces |
347 |
) throws CanonicalizationException { |
|
348 |
return |
|
349 |
canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces); |
|
1337 | 350 |
} |
2 | 351 |
|
1337 | 352 |
/** |
353 |
* Canonicalizes an XPath node set. |
|
354 |
* |
|
355 |
* @param xpathNodeSet |
|
356 |
* @return the result of the c14n. |
|
357 |
* @throws CanonicalizationException |
|
358 |
*/ |
|
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
359 |
public byte[] canonicalizeXPathNodeSet(Set<Node> xpathNodeSet) |
18240 | 360 |
throws CanonicalizationException { |
361 |
return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); |
|
1337 | 362 |
} |
2 | 363 |
|
1337 | 364 |
/** |
365 |
* Canonicalizes an XPath node set. |
|
366 |
* |
|
367 |
* @param xpathNodeSet |
|
368 |
* @param inclusiveNamespaces |
|
369 |
* @return the result of the c14n. |
|
370 |
* @throws CanonicalizationException |
|
371 |
*/ |
|
18240 | 372 |
public byte[] canonicalizeXPathNodeSet( |
373 |
Set<Node> xpathNodeSet, String inclusiveNamespaces |
|
374 |
) throws CanonicalizationException { |
|
375 |
return |
|
376 |
canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces); |
|
1337 | 377 |
} |
2 | 378 |
|
1337 | 379 |
/** |
380 |
* Sets the writer where the canonicalization ends. ByteArrayOutputStream |
|
381 |
* if none is set. |
|
382 |
* @param os |
|
383 |
*/ |
|
384 |
public void setWriter(OutputStream os) { |
|
18240 | 385 |
canonicalizerSpi.setWriter(os); |
1337 | 386 |
} |
2 | 387 |
|
1337 | 388 |
/** |
389 |
* Returns the name of the implementing {@link CanonicalizerSpi} class |
|
390 |
* |
|
391 |
* @return the name of the implementing {@link CanonicalizerSpi} class |
|
392 |
*/ |
|
393 |
public String getImplementingCanonicalizerClass() { |
|
18240 | 394 |
return canonicalizerSpi.getClass().getName(); |
1337 | 395 |
} |
2 | 396 |
|
1337 | 397 |
/** |
398 |
* Set the canonicalizer behaviour to not reset. |
|
399 |
*/ |
|
400 |
public void notReset() { |
|
18240 | 401 |
canonicalizerSpi.reset = false; |
1337 | 402 |
} |
18240 | 403 |
|
2 | 404 |
} |