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/* 24 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 25 */ 26/* 27 * $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $ 28 */ 29package org.jcp.xml.dsig.internal.dom; 30 31import org.w3c.dom.Attr; 32import org.w3c.dom.Element; 33import org.w3c.dom.Node; 34 35import com.sun.org.apache.xml.internal.security.Init; 36import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 37import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver; 38import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; 39 40import javax.xml.crypto.*; 41import javax.xml.crypto.dom.*; 42 43/** 44 * DOM-based implementation of URIDereferencer. 45 * 46 * @author Sean Mullan 47 */ 48public class DOMURIDereferencer implements URIDereferencer { 49 50 static final URIDereferencer INSTANCE = new DOMURIDereferencer(); 51 52 private DOMURIDereferencer() { 53 // need to call com.sun.org.apache.xml.internal.security.Init.init() 54 // before calling any apache security code 55 Init.init(); 56 } 57 58 public Data dereference(URIReference uriRef, XMLCryptoContext context) 59 throws URIReferenceException { 60 61 if (uriRef == null) { 62 throw new NullPointerException("uriRef cannot be null"); 63 } 64 if (context == null) { 65 throw new NullPointerException("context cannot be null"); 66 } 67 68 DOMURIReference domRef = (DOMURIReference) uriRef; 69 Attr uriAttr = (Attr) domRef.getHere(); 70 String uri = uriRef.getURI(); 71 DOMCryptoContext dcc = (DOMCryptoContext) context; 72 String baseURI = context.getBaseURI(); 73 74 boolean secVal = Utils.secureValidation(context); 75 76 if (secVal && Policy.restrictReferenceUriScheme(uri)) { 77 throw new URIReferenceException( 78 "Uri " + uri + " is forbidden when secure validation is enabled"); 79 } 80 81 // Check if same-document URI and already registered on the context 82 if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') { 83 String id = uri.substring(1); 84 85 if (id.startsWith("xpointer(id(")) { 86 int i1 = id.indexOf('\''); 87 int i2 = id.indexOf('\'', i1+1); 88 id = id.substring(i1+1, i2); 89 } 90 91 // check if element is registered by Id 92 Node referencedElem = uriAttr.getOwnerDocument().getElementById(id); 93 if (referencedElem == null) { 94 // see if element is registered in DOMCryptoContext 95 referencedElem = dcc.getElementById(id); 96 } 97 if (referencedElem != null) { 98 if (secVal && Policy.restrictDuplicateIds()) { 99 Element start = referencedElem.getOwnerDocument().getDocumentElement(); 100 if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) { 101 String error = "Multiple Elements with the same ID " 102 + id + " detected when secure validation" 103 + " is enabled"; 104 throw new URIReferenceException(error); 105 } 106 } 107 108 XMLSignatureInput result = new XMLSignatureInput(referencedElem); 109 if (!uri.substring(1).startsWith("xpointer(id(")) { 110 result.setExcludeComments(true); 111 } 112 113 result.setMIMEType("text/xml"); 114 if (baseURI != null && baseURI.length() > 0) { 115 result.setSourceURI(baseURI.concat(uriAttr.getNodeValue())); 116 } else { 117 result.setSourceURI(uriAttr.getNodeValue()); 118 } 119 return new ApacheNodeSetData(result); 120 } 121 } 122 123 try { 124 ResourceResolver apacheResolver = 125 ResourceResolver.getInstance(uriAttr, baseURI, false); 126 XMLSignatureInput in = apacheResolver.resolve(uriAttr, 127 baseURI, false); 128 if (in.isOctetStream()) { 129 return new ApacheOctetStreamData(in); 130 } else { 131 return new ApacheNodeSetData(in); 132 } 133 } catch (Exception e) { 134 throw new URIReferenceException(e); 135 } 136 } 137} 138