001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the License). You may not use this file except in
005: * compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * Header Notice in each file and include the License file
014: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * If applicable, add the following below the CDDL Header,
016: * with the fields enclosed by brackets [] replaced by
017: * you own identifying information:
018: * "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
021: */
022:
023: package com.sun.xml.ws.security.opt.impl.dsig;
024:
025: import com.sun.xml.ws.security.opt.api.SecurityElement;
026: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
027: import com.sun.xml.ws.security.opt.impl.crypto.SSBData;
028: import com.sun.xml.ws.security.opt.impl.message.SOAPBody;
029: import com.sun.xml.ws.security.opt.impl.message.SecuredMessage;
030: import java.util.ArrayList;
031: import javax.xml.crypto.Data;
032: import javax.xml.crypto.URIDereferencer;
033: import javax.xml.crypto.URIReference;
034: import javax.xml.crypto.URIReferenceException;
035: import javax.xml.crypto.XMLCryptoContext;
036: import com.sun.xml.ws.security.opt.crypto.JAXBData;
037:
038: import javax.xml.stream.XMLStreamException;
039: import javax.xml.bind.JAXBContext;
040: import javax.xml.bind.JAXBElement;
041: import javax.xml.bind.JAXBException;
042: import java.util.logging.Logger;
043: import java.util.logging.Level;
044: import java.util.HashMap;
045: import com.sun.xml.ws.security.opt.impl.crypto.JAXBDataImpl;
046: import com.sun.xml.wss.impl.MessageConstants;
047: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
048: import com.sun.xml.wss.logging.LogDomainConstants;
049: import com.sun.xml.wss.logging.impl.opt.signature.LogStringsMessages;
050: import com.sun.xml.ws.security.opt.impl.util.JAXBUtil;
051: import com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader;
052: import com.sun.xml.wss.XWSSecurityException;
053: import com.sun.xml.ws.api.message.Header;
054:
055: /**
056: * Implementation of JSR 105 URIDereferencer interface for optimized path
057: *
058: * @author Ashutosh.Shahi@Sun.com
059: */
060:
061: public class DSigResolver implements URIDereferencer {
062:
063: private static DSigResolver resolver = new DSigResolver();
064: private static final Logger logger = Logger.getLogger(
065: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN,
066: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN_BUNDLE);
067:
068: /**
069: *
070: * create a new instance of this class
071: * @return URI Dereferencer instance.
072: */
073:
074: public static URIDereferencer getInstance() {
075: return resolver;
076: }
077:
078: /**
079: * resolve the URI of type "cid:" , "attachmentRef:", "http:", "#xyz".
080: * @param uriRef {@inheritDoc}
081: * @param context{@inheritDoc}
082: * @throws URIReferenceException {@inheritDoc}
083: * @return {@inheritDoc}
084: */
085:
086: public Data dereference(final URIReference uriRef,
087: final XMLCryptoContext context)
088: throws URIReferenceException {
089: String uri = null;
090: uri = uriRef.getURI();
091: if (logger.isLoggable(Level.FINEST)) {
092: logger.log(Level.FINEST, LogStringsMessages
093: .WSS_1750_URI_TOBE_DEREFERENCED(uri));
094: }
095: return dereferenceURI(uri, context);
096: }
097:
098: private Data dereferenceURI(final String uri,
099: final XMLCryptoContext context)
100: throws URIReferenceException {
101: try {
102:
103: if (uri == null || uri.equals("")) {
104: throw new UnsupportedOperationException(
105: "Empty Reference URI not supported");
106: } else if (uri.charAt(0) == '#') {
107: return dereferenceFragment(getIdFromFragmentRef(uri),
108: context);
109: } else if (uri.startsWith("cid:")
110: || uri.startsWith("attachmentRef:")) {
111: throw new UnsupportedOperationException(
112: "Not supported in optimized path");
113: } else if (uri.startsWith("http")) {
114: throw new UnsupportedOperationException(
115: "Not supported in optimized path");
116: } else {
117: return dereferenceFragment(uri, context);
118: }
119: } catch (Exception e) {
120: throw new URIReferenceException(e);
121: }
122: }
123:
124: Data dereferenceFragment(final String uri,
125: final XMLCryptoContext context) throws XWSSecurityException {
126: JAXBFilterProcessingContext filterContext = (JAXBFilterProcessingContext) context
127: .get(MessageConstants.WSS_PROCESSING_CONTEXT);
128: HashMap elementCache = filterContext.getElementCache();
129: try {
130: if (elementCache.size() > 0) {
131: Object obj = elementCache.get(uri);
132: if (obj != null && obj instanceof Header) {
133: Header reqdHeader = (Header) obj;
134: JAXBContext jaxbContext = JAXBUtil.getJAXBContext();
135: JAXBElement jb = reqdHeader.readAsJAXB(jaxbContext
136: .createUnmarshaller());
137: JAXBData jData = new JAXBDataImpl(jb, jaxbContext,
138: filterContext.getNamespaceContext());
139: return jData;
140: }
141: }
142:
143: return getDataById(filterContext, uri);
144: } catch (JAXBException jbe) {
145: throw new XWSSecurityException(jbe);
146: } catch (XMLStreamException sxe) {
147: throw new XWSSecurityException(sxe);
148: }
149: }
150:
151: private static String getIdFromFragmentRef(final String ref) {
152: char start = ref.charAt(0);
153: if (start == '#') {
154: return ref.substring(1);
155: }
156: return ref;
157: }
158:
159: private Data getDataById(final JAXBFilterProcessingContext context,
160: final String uri) throws JAXBException, XMLStreamException,
161: XWSSecurityException {
162: SecuredMessage secMessage = context.getSecuredMessage();
163: ArrayList headerList = secMessage.getHeaders();
164: // Look for Id or wsu:Id attribute in all elements
165: SecurityHeaderElement reqdHeader = null;
166: for (int i = 0; i < headerList.size(); i++) {
167: Object header = headerList.get(i);
168: if (header instanceof SecurityHeaderElement) {
169: // header already wrapped by a SecurityheaderElement
170: SecurityHeaderElement she = (SecurityHeaderElement) header;
171: if (uri.equals(she.getId())) {
172: reqdHeader = she;
173: break;
174: }
175: }
176: }
177:
178: // check inside the Securityheader
179: if (reqdHeader == null) {
180: SecurityHeader secHeader = context.getSecurityHeader();
181: SecurityHeaderElement she = secHeader.getChildElement(uri);
182: if (she != null
183: && !(she.getLocalPart() == MessageConstants.WSSE_SECURITY_TOKEN_REFERENCE_LNAME && she
184: .getNamespaceURI() == MessageConstants.WSSE_NS)) {
185: reqdHeader = she;
186: }
187: }
188:
189: // if matches, convert the element to JAXBData
190: if (reqdHeader != null) {
191: // how to get contentOnly???
192: return new JAXBDataImpl(reqdHeader, context
193: .getNamespaceContext(), false);
194: } else {
195: try {
196: Object body = secMessage.getBody();
197: if (body instanceof SecurityElement) {
198: SecurityElement se = (SecurityElement) body;
199: if (uri.equals(se.getId())) {
200: return new JAXBDataImpl(se, context
201: .getNamespaceContext(), false);
202: }
203: } else if (body instanceof SOAPBody) {
204: SOAPBody soapBody = (SOAPBody) body;
205: if (uri.equals(soapBody.getId())) {
206: return new SSBData(soapBody, false, context
207: .getNamespaceContext());
208: //write to streamwriter data and return
209: } else if (uri.equals(soapBody.getBodyContentId())) {
210: return new SSBData(soapBody, true, context
211: .getNamespaceContext());
212: }
213: }
214: } catch (XWSSecurityException ex) {
215: logger.log(Level.SEVERE, LogStringsMessages
216: .WSS_1704_ERROR_RESOLVING_ID(uri));
217: throw new XWSSecurityException(ex);
218: }
219: }
220: Data data = null;
221: data = (Data) context.getElementCache().get(uri);
222: return data;
223: }
224:
225: }
|