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.incoming;
024:
025: import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
026: import com.sun.xml.ws.security.impl.DerivedKeyTokenImpl;
027: import com.sun.xml.ws.security.opt.api.NamespaceContextInfo;
028: import com.sun.xml.ws.security.opt.api.SecurityElementWriter;
029: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
030: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
031: import com.sun.xml.ws.security.opt.impl.incoming.processor.SecurityTokenProcessor;
032: import com.sun.xml.ws.security.opt.impl.util.StreamUtil;
033: import com.sun.xml.wss.XWSSecurityException;
034: import com.sun.xml.wss.impl.MessageConstants;
035: import com.sun.xml.wss.impl.misc.Base64;
036: import com.sun.xml.wss.impl.misc.SecurityUtil;
037: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
038: import com.sun.xml.wss.logging.LogDomainConstants;
039: import java.io.OutputStream;
040: import java.security.Key;
041: import java.util.HashMap;
042: import java.util.logging.Level;
043: import java.util.logging.Logger;
044:
045: import javax.xml.stream.XMLStreamException;
046: import javax.xml.stream.XMLStreamReader;
047: import javax.xml.stream.XMLStreamWriter;
048: import org.jvnet.staxex.Base64Data;
049: import org.jvnet.staxex.XMLStreamReaderEx;
050: import com.sun.xml.wss.logging.impl.opt.token.LogStringsMessages;
051:
052: /**
053: *
054: * @author Ashutosh.Shahi@sun.com
055: */
056: public class DerivedKeyToken implements SecurityHeaderElement,
057: NamespaceContextInfo, SecurityElementWriter {
058: private static final Logger logger = Logger.getLogger(
059: LogDomainConstants.IMPL_OPT_TOKEN_DOMAIN,
060: LogDomainConstants.IMPL_OPT_TOKEN_DOMAIN_BUNDLE);
061:
062: private static final String SECURITY_TOKEN_REFERENCE = "SecurityTokenReference"
063: .intern();
064: private static final String LENGTH = "Length".intern();
065: private static final String OFFSET = "Offset".intern();
066: private static final String GENERATION = "Generation".intern();
067: private static final String NONCE = "Nonce".intern();
068:
069: private static final int SECURITY_TOKEN_REFERENCE_ELEMENT = 3;
070: private static final int LENGTH_ELEMENT = 4;
071: private static final int OFFSET_ELEMENT = 5;
072: private static final int GENERATION_ELEMENT = 6;
073: private static final int NONCE_ELEMENT = 7;
074:
075: private String id = "";
076: private String namespaceURI = "";
077: private String localName = "";
078: private long offset = 0;
079: private long length = 32;
080: private String nonce = null;
081: private byte[] decodedNonce = null;
082: //private long generation = -1;
083: private HashMap<String, String> nsDecls;
084:
085: private Key originalKey = null;
086:
087: private JAXBFilterProcessingContext pc = null;
088: private WSSPolicy inferredKB = null;
089:
090: /** Creates a new instance of DerivedKeyTokenProcessor */
091: public DerivedKeyToken(XMLStreamReader reader,
092: JAXBFilterProcessingContext pc, HashMap nsDecls)
093: throws XMLStreamException, XWSSecurityException {
094: this .pc = pc;
095: this .nsDecls = nsDecls;
096: process(reader);
097:
098: }
099:
100: public Key getKey() throws XWSSecurityException {
101: String dataEncAlgo = null;
102: if (pc.getAlgorithmSuite() != null) {
103: dataEncAlgo = ((JAXBFilterProcessingContext) pc)
104: .getAlgorithmSuite().getEncryptionAlgorithm();
105: } else {
106: logger.log(Level.SEVERE, LogStringsMessages
107: .WSS_1818_ALGORITHM_NOTSET_DERIVEDKEY());
108: throw new XWSSecurityException(LogStringsMessages
109: .WSS_1818_ALGORITHM_NOTSET_DERIVEDKEY());
110: }
111:
112: try {
113: byte[] secret = originalKey.getEncoded();
114: com.sun.xml.ws.security.DerivedKeyToken dkt = new DerivedKeyTokenImpl(
115: offset, length, secret, decodedNonce);
116: String jceAlgo = SecurityUtil
117: .getSecretKeyAlgorithm(dataEncAlgo);
118:
119: return dkt.generateSymmetricKey(jceAlgo);
120:
121: } catch (Exception ex) {
122: logger.log(Level.SEVERE, LogStringsMessages
123: .WSS_1819_ERROR_SYMMKEY_DERIVEDKEY());
124: throw new XWSSecurityException(LogStringsMessages
125: .WSS_1819_ERROR_SYMMKEY_DERIVEDKEY(), ex);
126: }
127:
128: }
129:
130: public boolean refersToSecHdrWithId(final String id) {
131: throw new UnsupportedOperationException();
132: }
133:
134: public String getId() {
135: return id;
136: }
137:
138: public void setId(final String id) {
139: throw new UnsupportedOperationException();
140: }
141:
142: public String getNamespaceURI() {
143: return namespaceURI;
144: }
145:
146: public String getLocalPart() {
147: return localName;
148: }
149:
150: public XMLStreamReader readHeader() throws XMLStreamException {
151: throw new UnsupportedOperationException();
152: }
153:
154: public void writeTo(OutputStream os) {
155: throw new UnsupportedOperationException();
156: }
157:
158: public void writeTo(XMLStreamWriter streamWriter)
159: throws XMLStreamException {
160: throw new UnsupportedOperationException();
161: }
162:
163: private void process(XMLStreamReader reader)
164: throws XMLStreamException, XWSSecurityException {
165: id = reader.getAttributeValue(MessageConstants.WSU_NS, "Id");
166: namespaceURI = reader.getNamespaceURI();
167: localName = reader.getLocalName();
168:
169: boolean offsetSpecified = false;
170: boolean genSpecified = false;
171: boolean invalidToken = false;
172:
173: if (StreamUtil.moveToNextElement(reader)) {
174: int refElement = getEventType(reader);
175: while (reader.getEventType() != reader.END_DOCUMENT) {
176: switch (refElement) {
177: case SECURITY_TOKEN_REFERENCE_ELEMENT: {
178: pc.getSecurityContext().setInferredKB(null);
179: SecurityTokenProcessor stp = new SecurityTokenProcessor(
180: pc, null);
181: originalKey = stp.resolveReference(reader);
182: inferredKB = (WSSPolicy) pc.getSecurityContext()
183: .getInferredKB();
184: pc.getSecurityContext().setInferredKB(null);
185: break;
186: }
187: case LENGTH_ELEMENT: {
188: length = Integer.parseInt(reader.getElementText());
189: break;
190: }
191: case OFFSET_ELEMENT: {
192: offset = Integer.parseInt(reader.getElementText());
193: offsetSpecified = true;
194: break;
195: }
196: case GENERATION_ELEMENT: {
197: //generation = Integer.parseInt(reader.getElementText());
198: genSpecified = true;
199: break;
200: }
201: case NONCE_ELEMENT: {
202: if (reader instanceof XMLStreamReaderEx) {
203: reader.next();
204: StringBuffer sb = null;
205: if (reader.getEventType() == XMLStreamReader.CHARACTERS
206: && reader.getEventType() != reader.END_ELEMENT) {
207: CharSequence charSeq = ((XMLStreamReaderEx) reader)
208: .getPCDATA();
209: if (charSeq instanceof Base64Data) {
210: Base64Data bd = (Base64Data) ((XMLStreamReaderEx) reader)
211: .getPCDATA();
212: decodedNonce = bd.getExact();
213: } else {
214: if (sb == null) {
215: sb = new StringBuffer();
216: }
217: for (int i = 0; i < charSeq.length(); i++) {
218: sb.append(charSeq.charAt(i));
219: }
220: }
221: reader.next();
222: }
223: if (sb != null) {
224: nonce = sb.toString();
225: try {
226: decodedNonce = Base64.decode(nonce);
227: } catch (Base64DecodingException dec) {
228: logger
229: .log(
230: Level.SEVERE,
231: LogStringsMessages
232: .WSS_1820_ERROR_NONCE_DERIVEDKEY(id));
233: throw new XWSSecurityException(
234: LogStringsMessages
235: .WSS_1820_ERROR_NONCE_DERIVEDKEY(id),
236: dec);
237: }
238: }/*else{
239: reader.next();
240: }*/
241: } else {
242: nonce = reader.getElementText();
243: try {
244: decodedNonce = Base64.decode(nonce);
245: } catch (Base64DecodingException ex) {
246: logger
247: .log(
248: Level.SEVERE,
249: LogStringsMessages
250: .WSS_1820_ERROR_NONCE_DERIVEDKEY(id));
251: throw new XWSSecurityException(
252: LogStringsMessages
253: .WSS_1820_ERROR_NONCE_DERIVEDKEY(id),
254: ex);
255: }
256: }
257:
258: break;
259: }
260: default: {
261: throw new XWSSecurityException(
262: "Element name "
263: + reader.getName()
264: + " is not recognized under DerivedKeyToken");
265: }
266: }
267:
268: if (!StreamUtil.isStartElement(reader)
269: && StreamUtil
270: .moveToNextStartOREndElement(reader)
271: && StreamUtil._break(reader, "DerivedKeyToken",
272: MessageConstants.WSSC_NS)) {
273: StreamUtil.moveToNextStartOREndElement(reader);
274: break;
275: } else {
276: if (reader.getEventType() != XMLStreamReader.START_ELEMENT) {
277: StreamUtil.moveToNextStartOREndElement(reader);
278: boolean isBreak = false;
279: while (reader.getEventType() == XMLStreamReader.END_ELEMENT) {
280: if (StreamUtil._break(reader,
281: "DerivedKeyToken",
282: MessageConstants.WSSC_NS)) {
283: isBreak = true;
284: StreamUtil
285: .moveToNextStartOREndElement(reader);
286: break;
287: }
288: StreamUtil
289: .moveToNextStartOREndElement(reader);
290: }
291: if (isBreak)
292: break;
293: }
294: }
295: refElement = getEventType(reader);
296: }
297: }
298:
299: //Verify if the DKT is correct
300: if (offsetSpecified && genSpecified) {
301: invalidToken = true;
302: }
303:
304: if (invalidToken) {
305: logger.log(Level.SEVERE, LogStringsMessages
306: .WSS_1821_INVALID_DKT_TOKEN());
307: throw new XWSSecurityException(LogStringsMessages
308: .WSS_1821_INVALID_DKT_TOKEN());
309: }
310: }
311:
312: private int getEventType(XMLStreamReader reader) {
313: if (reader.getEventType() == XMLStreamReader.START_ELEMENT) {
314: if (reader.getLocalName() == SECURITY_TOKEN_REFERENCE) {
315: return SECURITY_TOKEN_REFERENCE_ELEMENT;
316: }
317:
318: if (reader.getLocalName() == LENGTH) {
319: return LENGTH_ELEMENT;
320: }
321:
322: if (reader.getLocalName() == OFFSET) {
323: return OFFSET_ELEMENT;
324: }
325:
326: if (reader.getLocalName() == GENERATION) {
327: return GENERATION_ELEMENT;
328: }
329:
330: if (reader.getLocalName() == NONCE) {
331: return NONCE_ELEMENT;
332: }
333: }
334: return -1;
335: }
336:
337: public HashMap<String, String> getInscopeNSContext() {
338: return nsDecls;
339: }
340:
341: public void writeTo(javax.xml.stream.XMLStreamWriter streamWriter,
342: HashMap props) throws javax.xml.stream.XMLStreamException {
343: throw new UnsupportedOperationException();
344: }
345:
346: public WSSPolicy getInferredKB() {
347: return inferredKB;
348: }
349:
350: }
|