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.crypto.JAXBData;
026: import com.sun.xml.ws.security.opt.crypto.StreamWriterData;
027: import com.sun.xml.ws.security.opt.impl.crypto.OctectStreamData;
028: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
029: import com.sun.xml.wss.XWSSecurityException;
030: import com.sun.xml.wss.impl.MessageConstants;
031: import com.sun.xml.wss.logging.LogDomainConstants;
032: import java.util.Iterator;
033: import java.util.logging.Level;
034: import java.util.logging.Logger;
035: import javax.xml.crypto.Data;
036: import javax.xml.crypto.URIDereferencer;
037: import javax.xml.crypto.URIReference;
038: import javax.xml.crypto.URIReferenceException;
039: import javax.xml.crypto.XMLCryptoContext;
040: import javax.xml.namespace.NamespaceContext;
041: import javax.xml.stream.XMLStreamException;
042: import javax.xml.stream.XMLStreamWriter;
043: import org.jvnet.staxex.NamespaceContextEx;
044: import com.sun.xml.wss.logging.impl.opt.signature.LogStringsMessages;
045:
046: /**
047: *
048: * @author K.Venugopal@sun.com
049: */
050: public class StAXSTRTransformWriter implements XMLStreamWriter,
051: StreamWriterData {
052: private static final Logger logger = Logger.getLogger(
053: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN,
054: LogDomainConstants.IMPL_OPT_SIGNATURE_DOMAIN_BUNDLE);
055:
056: private XMLStreamWriter nextWriter = null;
057: private boolean ignore = false;
058: private boolean derefSAMLKeyIdentifier = false;
059:
060: private Data data = null;
061: private int index = 0;
062: private NamespaceContextEx ns = null;
063: private boolean directReference = false;
064: private String directReferenceValue = "";
065: private XMLCryptoContext xMLCryptoContext;
066: private String strId = "";
067: private JAXBFilterProcessingContext filterContext;
068:
069: /** Creates a new instance of StAXEnvelopedTransformWriter */
070: public StAXSTRTransformWriter(XMLStreamWriter writer, Data data,
071: XMLCryptoContext xMLCryptoContext) {
072: this .nextWriter = writer;
073: this .data = data;
074: if (data instanceof JAXBData) {
075: ns = ((JAXBData) data).getNamespaceContext();
076: } else if (data instanceof StreamWriterData) {
077: ns = ((StreamWriterData) data).getNamespaceContext();
078: }
079: this .xMLCryptoContext = xMLCryptoContext;
080: filterContext = (JAXBFilterProcessingContext) xMLCryptoContext
081: .get(MessageConstants.WSS_PROCESSING_CONTEXT);
082: }
083:
084: public StAXSTRTransformWriter(Data data,
085: XMLCryptoContext xMLCryptoContext, String refId) {
086: this .data = data;
087: if (data instanceof JAXBData) {
088: ns = ((JAXBData) data).getNamespaceContext();
089: } else if (data instanceof StreamWriterData) {
090: ns = ((StreamWriterData) data).getNamespaceContext();
091: }
092: this .xMLCryptoContext = xMLCryptoContext;
093: this .strId = refId;
094: filterContext = (JAXBFilterProcessingContext) xMLCryptoContext
095: .get(MessageConstants.WSS_PROCESSING_CONTEXT);
096: }
097:
098: public NamespaceContextEx getNamespaceContext() {
099: return ns;
100: }
101:
102: public void close() throws XMLStreamException {
103: nextWriter.close();
104: }
105:
106: public void flush() throws XMLStreamException {
107: nextWriter.flush();
108: }
109:
110: public void writeEndDocument() throws XMLStreamException {
111: if (index > 0) {
112: int size = index;
113: for (int i = 0; i < size; i++) {
114: writeEndElement();
115: }
116: }
117: nextWriter.writeEndDocument();
118: }
119:
120: public void writeEndElement() throws XMLStreamException {
121: if (index == 1 && !ignore) {
122: nextWriter.writeEndElement();
123: }
124: if (index > 0) {
125: index--;
126: }
127: if (index == 0) {
128: if (ignore) {
129: ignore = false;
130: derefernceSTR();
131:
132: nextWriter.writeEndElement();
133: }
134: if (derefSAMLKeyIdentifier) {
135: derefSAMLKeyIdentifier = false;
136: }
137: if (directReference) {
138: directReference = false;
139: }
140:
141: return;
142: }
143: }
144:
145: public void writeStartDocument() throws XMLStreamException {
146: if (!ignore) {
147: nextWriter.writeStartDocument();
148: }
149: }
150:
151: public void writeCharacters(char[] c, int index, int len)
152: throws XMLStreamException {
153: if (!ignore) {
154: nextWriter.writeCharacters(c, index, len);
155: } else {
156: if (derefSAMLKeyIdentifier) {
157: this .strId = String.valueOf(c, index, len);
158: if (this .strId == null) {
159: throw new XMLStreamException(
160: "SAML Key Identifier is empty in SecurityTokenReference");
161: }
162: }
163: }
164: }
165:
166: public void setDefaultNamespace(String string)
167: throws XMLStreamException {
168: if (!ignore) {
169: nextWriter.setDefaultNamespace(string);
170: }
171: }
172:
173: public void writeCData(String string) throws XMLStreamException {
174: if (!ignore) {
175: nextWriter.writeCData(string);
176: }
177: }
178:
179: public void writeCharacters(String string)
180: throws XMLStreamException {
181: if (!ignore) {
182: nextWriter.writeCharacters(string);
183: } else {
184: if (derefSAMLKeyIdentifier) {
185: this .strId = string;
186: if (this .strId == null) {
187: throw new XMLStreamException(
188: "SAML Key Identifier is empty in SecurityTokenReference");
189: }
190: }
191: }
192: }
193:
194: public void writeComment(String string) throws XMLStreamException {
195: if (!ignore) {
196: nextWriter.writeComment(string);
197: }
198: }
199:
200: public void writeDTD(String string) throws XMLStreamException {
201: if (!ignore) {
202: nextWriter.writeDTD(string);
203: }
204: }
205:
206: public void writeDefaultNamespace(String string)
207: throws XMLStreamException {
208: if (!ignore) {
209: nextWriter.writeDefaultNamespace(string);
210: }
211: }
212:
213: public void writeEmptyElement(String string)
214: throws XMLStreamException {
215: if (!ignore) {
216: nextWriter.writeEmptyElement(string);
217: }
218: }
219:
220: public void writeEntityRef(String string) throws XMLStreamException {
221: if (!ignore) {
222: nextWriter.writeEntityRef(string);
223: }
224: }
225:
226: public void writeProcessingInstruction(String string)
227: throws XMLStreamException {
228: if (!ignore) {
229: nextWriter.writeProcessingInstruction(string);
230: }
231: }
232:
233: public void writeStartDocument(String string)
234: throws XMLStreamException {
235: if (!ignore) {
236: nextWriter.writeStartDocument(string);
237: }
238: }
239:
240: public void writeStartElement(String string)
241: throws XMLStreamException {
242: if (!ignore) {
243: nextWriter.writeStartElement(string);
244: }
245: }
246:
247: public void setNamespaceContext(NamespaceContext namespaceContext)
248: throws XMLStreamException {
249: if (!ignore) {
250: nextWriter.setNamespaceContext(namespaceContext);
251: }
252: }
253:
254: public Object getProperty(String string)
255: throws IllegalArgumentException {
256: return nextWriter.getProperty(string);
257: }
258:
259: public String getPrefix(String string) throws XMLStreamException {
260: return nextWriter.getPrefix(string);
261: }
262:
263: public void setPrefix(String string, String string0)
264: throws XMLStreamException {
265: if (!ignore) {
266: nextWriter.setPrefix(string, string0);
267: }
268: }
269:
270: public void writeAttribute(String localname, String value)
271: throws XMLStreamException {
272: if (!ignore) {
273: nextWriter.writeAttribute(localname, value);
274: } else {
275: if (directReference) {
276: if (localname == MessageConstants.WSSE_REFERENCE_ATTR_URI) {
277: directReferenceValue = value;
278: }
279: } else if (MessageConstants.WSSE_SAML_KEY_IDENTIFIER_VALUE_TYPE
280: .equals(value)
281: || MessageConstants.WSSE_SAML_v2_0_KEY_IDENTIFIER_VALUE_TYPE
282: .equals(value)) {
283: derefSAMLKeyIdentifier = true;
284: }
285: }
286: }
287:
288: public void writeEmptyElement(String string, String string0)
289: throws XMLStreamException {
290: if (!ignore) {
291: nextWriter.writeEmptyElement(string, string0);
292: }
293: }
294:
295: public void writeNamespace(String string, String string0)
296: throws XMLStreamException {
297: if (!ignore) {
298: nextWriter.writeNamespace(string, string0);
299: }
300: }
301:
302: public void writeProcessingInstruction(String string, String string0)
303: throws XMLStreamException {
304: if (!ignore) {
305: nextWriter.writeProcessingInstruction(string, string0);
306: }
307: }
308:
309: public void writeStartDocument(String string, String string0)
310: throws XMLStreamException {
311: if (!ignore) {
312: nextWriter.writeStartDocument(string, string0);
313: }
314: }
315:
316: public void writeStartElement(String namespaceURI, String localName)
317: throws XMLStreamException {
318: if (!ignore) {
319: if (localName == MessageConstants.WSSE_SECURITY_TOKEN_REFERENCE_LNAME
320: && namespaceURI == MessageConstants.WSSE_NS) {
321: ignore = true;
322: index++;
323: return;
324: }
325: nextWriter.writeStartElement(namespaceURI, localName);
326: } else {
327: index++;
328: }
329: }
330:
331: public void writeAttribute(String uri, String localname,
332: String value) throws XMLStreamException {
333: if (!ignore) {
334: nextWriter.writeAttribute(uri, localname, value);
335: } else {
336: if (directReference) {
337: if (localname == MessageConstants.WSSE_REFERENCE_ATTR_URI) {
338: directReferenceValue = value;
339: }
340: }
341: }
342: }
343:
344: public void writeEmptyElement(String string, String string0,
345: String string1) throws XMLStreamException {
346: if (!ignore) {
347: nextWriter.writeEmptyElement(string, string0, string1);
348: }
349: }
350:
351: public void writeStartElement(String prefix, String localName,
352: String namespaceURI) throws XMLStreamException {
353: if (!ignore) {
354: if (localName == MessageConstants.WSSE_SECURITY_TOKEN_REFERENCE_LNAME
355: && namespaceURI == MessageConstants.WSSE_NS) {
356: ignore = true;
357: index++;
358: return;
359: } else if (localName == MessageConstants.WSSE_REFERENCE_LNAME
360: && namespaceURI == MessageConstants.WSSE_NS) {
361: ignore = true;
362: index++;
363: directReference = true;
364: nextWriter.writeNamespace(prefix, namespaceURI);
365: return;
366: } else if (localName == MessageConstants.KEYIDENTIFIER
367: && namespaceURI == MessageConstants.WSSE_NS) {
368: ignore = true;
369: index++;
370: nextWriter.writeNamespace(prefix, namespaceURI);
371: } else {
372: nextWriter.writeStartElement(prefix, localName,
373: namespaceURI);
374: }
375: } else {
376: if (localName == MessageConstants.WSSE_REFERENCE_LNAME
377: && namespaceURI == MessageConstants.WSSE_NS) {
378: index++;
379: directReference = true;
380: } else if (localName == MessageConstants.KEYIDENTIFIER
381: && namespaceURI == MessageConstants.WSSE_NS) {
382: index++;
383: nextWriter.writeNamespace(prefix, namespaceURI);
384: } else {
385: nextWriter.writeStartElement(prefix, localName,
386: namespaceURI);
387: }
388: }
389: }
390:
391: public void writeAttribute(String prefix, String uri,
392: String localName, String value) throws XMLStreamException {
393: if (!ignore) {
394: nextWriter.writeNamespace(prefix, uri);
395: nextWriter.writeAttribute(prefix, uri, localName, value);
396: } else {
397: if (directReference) {
398: if (localName == MessageConstants.WSSE_REFERENCE_ATTR_URI) {
399: directReferenceValue = value;
400: }
401: }
402: }
403: }
404:
405: public void write(XMLStreamWriter writer) throws XMLStreamException {
406: this .nextWriter = writer;
407:
408: if (data instanceof JAXBData) {
409: try {
410: ((JAXBData) data).writeTo(this );
411: NamespaceContextEx nc = ((JAXBData) data)
412: .getNamespaceContext();
413: Iterator<NamespaceContextEx.Binding> itr = nc
414: .iterator();
415:
416: while (itr.hasNext()) {
417: final NamespaceContextEx.Binding nd = itr.next();
418:
419: nextWriter.writeNamespace(nd.getPrefix(), nd
420: .getNamespaceURI());
421:
422: }
423: } catch (XWSSecurityException ex) {
424: logger.log(Level.SEVERE, LogStringsMessages
425: .WSS_1706_ERROR_ENVELOPED_SIGNATURE());
426: throw new XMLStreamException(
427: "Error occurred while performing Enveloped Signature");
428: }
429: } else if (data instanceof StreamWriterData) {
430: StreamWriterData swd = (StreamWriterData) data;
431: NamespaceContextEx nc = swd.getNamespaceContext();
432: Iterator<NamespaceContextEx.Binding> itr = nc.iterator();
433:
434: while (itr.hasNext()) {
435: final NamespaceContextEx.Binding nd = itr.next();
436:
437: nextWriter.writeNamespace(nd.getPrefix(), nd
438: .getNamespaceURI());
439:
440: }
441: ((StreamWriterData) data).write(this );
442: } else if (data instanceof OctectStreamData) {
443: ((OctectStreamData) data).write(this );
444: }
445: }
446:
447: void derefernceSTR() throws XMLStreamException {
448: Data token = null;
449: URIDereferencer deRef = xMLCryptoContext.getURIDereferencer();
450: final String uri;
451: if (directReference) {
452: uri = directReferenceValue;
453: } else if (strId != null && strId.length() > 0) {
454: uri = strId;
455: } else {
456: uri = "";
457: }
458:
459: URIReference ref = new URIReference() {
460: public String getType() {
461: return "";
462: }
463:
464: public String getURI() {
465: return uri;
466: }
467: };
468:
469: try {
470: token = deRef.dereference(ref, xMLCryptoContext);
471: } catch (URIReferenceException ue) {
472: logger.log(Level.SEVERE, LogStringsMessages
473: .WSS_1716_ERROR_DEREFERENCE_STR_TRANSFORM());
474: throw new XMLStreamException(
475: "Error occurred while dereferencing STR-Transform's Reference Element",
476: ue);
477: }
478:
479: if (token != null) {
480: if (token instanceof JAXBData) {
481: try {
482: ((JAXBData) token).writeTo(this );
483: } catch (XWSSecurityException ex) {
484: logger.log(Level.SEVERE, LogStringsMessages
485: .WSS_1706_ERROR_ENVELOPED_SIGNATURE());
486: throw new XMLStreamException(
487: "Error occurred while performing Enveloped Signature");
488: }
489: } else if (token instanceof StreamWriterData) {
490: ((StreamWriterData) token).write(this );
491: } else if (token instanceof OctectStreamData) {
492: ((OctectStreamData) token).write(this);
493: }
494: }
495: }
496: }
|