001: /*
002:
003: * The contents of this file are subject to the terms
004:
005: * of the Common Development and Distribution License
006:
007: * (the License). You may not use this file except in
008:
009: * compliance with the License.
010:
011: *
012:
013: * You can obtain a copy of the license at
014:
015: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
016:
017: * See the License for the specific language governing
018:
019: * permissions and limitations under the License.
020:
021: *
022:
023: * When distributing Covered Code, include this CDDL
024:
025: * Header Notice in each file and include the License file
026:
027: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
028:
029: * If applicable, add the following below the CDDL Header,
030:
031: * with the fields enclosed by brackets [] replaced by
032:
033: * you own identifying information:
034:
035: * "Portions Copyrighted [year] [name of copyright owner]"
036:
037: *
038:
039: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
040:
041: */
042:
043: package com.sun.xml.ws.security.opt.impl.incoming;
044:
045: import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
046:
047: import com.sun.xml.stream.buffer.XMLStreamBuffer;
048:
049: import com.sun.xml.stream.buffer.XMLStreamBufferMark;
050:
051: import com.sun.xml.stream.buffer.stax.StreamReaderBufferCreator;
052:
053: import com.sun.xml.ws.security.opt.api.SecurityElementWriter;
054:
055: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
056:
057: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
058:
059: import com.sun.xml.ws.security.opt.impl.enc.CryptoProcessor;
060:
061: import com.sun.xml.ws.security.opt.impl.incoming.processor.CipherDataProcessor;
062:
063: import com.sun.xml.ws.security.opt.impl.incoming.processor.KeyInfoProcessor;
064:
065: import com.sun.xml.ws.security.opt.impl.util.CheckedInputStream;
066:
067: import com.sun.xml.ws.security.opt.impl.util.DecryptedInputStream;
068:
069: import com.sun.xml.ws.security.opt.impl.util.FilteredXMLStreamReader;
070:
071: import com.sun.xml.ws.security.opt.impl.util.StreamUtil;
072:
073: import com.sun.xml.wss.XWSSecurityException;
074:
075: import com.sun.xml.wss.impl.MessageConstants;
076:
077: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
078:
079: import java.io.BufferedInputStream;
080:
081: import java.io.ByteArrayInputStream;
082:
083: import java.io.ByteArrayOutputStream;
084:
085: import java.io.IOException;
086:
087: import java.io.InputStream;
088:
089: import java.io.OutputStream;
090:
091: import java.security.Key;
092:
093: import java.util.HashMap;
094:
095: import javax.crypto.Cipher;
096:
097: import javax.xml.crypto.KeySelector.Purpose;
098:
099: import javax.xml.stream.XMLOutputFactory;
100:
101: import javax.xml.stream.XMLStreamException;
102:
103: import javax.xml.stream.XMLStreamReader;
104:
105: import javax.xml.stream.XMLStreamWriter;
106:
107: import javax.xml.stream.XMLInputFactory;
108:
109: import com.sun.xml.wss.logging.impl.opt.crypto.LogStringsMessages;
110:
111: import java.util.logging.Level;
112:
113: import java.util.logging.Logger;
114:
115: import com.sun.xml.wss.logging.LogDomainConstants;
116:
117: /**
118:
119: *
120:
121: * @author Ashutosh.Shahi@sun.com
122:
123: */
124:
125: public class EncryptedData implements SecurityHeaderElement,
126: SecurityElementWriter {
127:
128: private static final Logger logger = Logger.getLogger(
129: LogDomainConstants.IMPL_OPT_CRYPTO_DOMAIN,
130:
131: LogDomainConstants.IMPL_OPT_CRYPTO_DOMAIN_BUNDLE);
132:
133: private static final String ENCRYPTION_METHOD = "EncryptionMethod"
134: .intern();
135:
136: private static final String CIPHER_DATA = "CipherData".intern();
137:
138: private static final String KEY_INFO = "KeyInfo".intern();
139:
140: private static final int KEYINFO_ELEMENT = 1;
141:
142: private static final int ENCRYPTIONMETHOD_ELEMENT = 2;
143:
144: private static final int CIPHER_DATA_ELEMENT = 5;
145:
146: private JAXBFilterProcessingContext pc = null;
147:
148: private String id = "";
149:
150: private String namespaceURI = "";
151:
152: private String localName = "";
153:
154: private String encryptionMethod = "";
155:
156: private Key dataEncKey = null;
157:
158: private InputStream cin = null;
159:
160: private CryptoProcessor cp = null;
161:
162: CipherDataProcessor cdp = null;
163:
164: private WSSPolicy inferredKB = null;
165:
166: HashMap<String, String> parentNS = null;
167:
168: /** Creates a new instance of EncryptedData */
169:
170: public EncryptedData(XMLStreamReader reader,
171: JAXBFilterProcessingContext pc,
172: HashMap<String, String> parentNS)
173: throws XMLStreamException, XWSSecurityException {
174:
175: this .pc = pc;
176:
177: this .parentNS = parentNS;
178:
179: process(reader);
180:
181: }
182:
183: public EncryptedData(XMLStreamReader reader, Key dataEncKey,
184: JAXBFilterProcessingContext pc,
185: HashMap<String, String> parentNS)
186: throws XMLStreamException, XWSSecurityException {
187:
188: this .dataEncKey = dataEncKey;
189:
190: this .pc = pc;
191:
192: this .parentNS = parentNS;
193:
194: process(reader);
195:
196: }
197:
198: private void process(XMLStreamReader reader)
199: throws XMLStreamException, XWSSecurityException {
200:
201: id = reader.getAttributeValue(null, "Id");
202:
203: namespaceURI = reader.getNamespaceURI();
204:
205: localName = reader.getLocalName();
206:
207: if (StreamUtil.moveToNextElement(reader)) {
208:
209: int refElement = getEventType(reader);
210:
211: while (reader.getEventType() != reader.END_DOCUMENT) {
212:
213: switch (refElement) {
214:
215: case ENCRYPTIONMETHOD_ELEMENT: {
216:
217: encryptionMethod = reader.getAttributeValue(null,
218: "Algorithm");
219:
220: if (encryptionMethod == null
221: || encryptionMethod.length() == 0) {
222:
223: if (pc.isBSP()) {
224:
225: logger
226: .log(
227: Level.SEVERE,
228: com.sun.xml.wss.logging.LogStringsMessages
229: .BSP_5601_ENCRYPTEDDATA_ENCRYPTIONMETHOD(id));
230:
231: throw new XWSSecurityException(
232: com.sun.xml.wss.logging.LogStringsMessages
233: .BSP_5601_ENCRYPTEDDATA_ENCRYPTIONMETHOD(id));
234:
235: }
236:
237: logger.log(Level.SEVERE, LogStringsMessages
238: .WSS_1925_EMPTY_ENCMETHOD_ED());
239:
240: throw new XWSSecurityException(
241: LogStringsMessages
242: .WSS_1925_EMPTY_ENCMETHOD_ED());
243:
244: }
245:
246: if (pc.isBSP()
247: && !(encryptionMethod
248: .equals("http://www.w3.org/2001/04/xmlenc#tripledes-cbc")
249: ||
250:
251: encryptionMethod
252: .equals("http://www.w3.org/2001/04/xmlenc#aes128-cbc") ||
253:
254: encryptionMethod
255: .equals("http://www.w3.org/2001/04/xmlenc#aes256-cbc"))) {
256:
257: logger
258: .log(
259: Level.SEVERE,
260: com.sun.xml.wss.logging.LogStringsMessages
261: .BSP_5626_KEYENCRYPTIONALGO());
262:
263: throw new XWSSecurityException(
264: com.sun.xml.wss.logging.LogStringsMessages
265: .BSP_5626_KEYENCRYPTIONALGO());
266:
267: }
268:
269: reader.next();
270:
271: break;
272:
273: }
274:
275: case KEYINFO_ELEMENT: {
276:
277: pc.getSecurityContext().setInferredKB(null);
278:
279: KeyInfoProcessor kip = new KeyInfoProcessor(pc,
280: Purpose.DECRYPT);
281:
282: dataEncKey = kip.getKey(reader);
283:
284: inferredKB = (WSSPolicy) pc.getSecurityContext()
285: .getInferredKB();
286:
287: pc.getSecurityContext().setInferredKB(null);
288:
289: if (!kip.hasSTR() && pc.isBSP()) {
290:
291: logger
292: .log(
293: Level.SEVERE,
294: com.sun.xml.wss.logging.LogStringsMessages
295: .BSP_5426_ENCRYPTEDKEYINFO(id));
296:
297: throw new XWSSecurityException(
298: com.sun.xml.wss.logging.LogStringsMessages
299: .BSP_5426_ENCRYPTEDKEYINFO(id));
300:
301: }
302:
303: break;
304:
305: }
306:
307: case CIPHER_DATA_ELEMENT: {
308:
309: cdp = new CipherDataProcessor();
310:
311: cdp.process(reader);
312:
313: break;
314:
315: }
316:
317: default: {
318:
319: // throw new XWSSecurityException("Element name "+reader.getName()+" is not recognized under EncryptedData");
320:
321: }
322:
323: }
324:
325: if (shouldBreak(reader)) {
326:
327: break;
328:
329: }
330:
331: if (reader.getEventType() == XMLStreamReader.START_ELEMENT) {
332:
333: if (getEventType(reader) == -1)
334:
335: reader.next();
336:
337: } else {
338:
339: reader.next();
340:
341: }
342:
343: refElement = getEventType(reader);
344:
345: }
346:
347: }
348:
349: if (reader.hasNext()) {
350:
351: reader.next();
352:
353: }
354:
355: }
356:
357: public boolean shouldBreak(XMLStreamReader reader)
358: throws XMLStreamException {
359:
360: if (StreamUtil._break(reader, "EncryptedData",
361: MessageConstants.XENC_NS)) {
362:
363: return true;
364:
365: }
366:
367: if (reader.getEventType() == XMLStreamReader.END_DOCUMENT) {
368:
369: return true;
370:
371: }
372:
373: return false;
374:
375: }
376:
377: public String getEncryptionAlgorithm() {
378:
379: return encryptionMethod;
380:
381: }
382:
383: public Key getKey() {
384:
385: return dataEncKey;
386:
387: }
388:
389: public InputStream getCipherInputStream()
390: throws XWSSecurityException {
391:
392: if (dataEncKey == null) {
393:
394: logger.log(Level.SEVERE, LogStringsMessages
395: .WSS_1926_ED_KEY_NOTSET());
396:
397: throw new XWSSecurityException(LogStringsMessages
398: .WSS_1926_ED_KEY_NOTSET());
399:
400: }
401:
402: cp = new CryptoProcessor(Cipher.DECRYPT_MODE, encryptionMethod,
403: dataEncKey);
404:
405: try {
406:
407: cin = cp.decryptData(cdp.readAsStream());
408:
409: } catch (IOException ex) {
410:
411: logger.log(Level.SEVERE, LogStringsMessages
412: .WSS_1927_ERROR_DECRYPT_ED("EncryptedData"));
413:
414: throw new XWSSecurityException(LogStringsMessages
415: .WSS_1927_ERROR_DECRYPT_ED("EncryptedData"), ex);
416:
417: }
418:
419: return cin;
420:
421: }
422:
423: public InputStream getCipherInputStream(Key key)
424: throws XWSSecurityException {
425:
426: dataEncKey = key;
427:
428: return getCipherInputStream();
429:
430: }
431:
432: public XMLStreamReader getDecryptedData()
433: throws XMLStreamException, XWSSecurityException {
434:
435: if (cin == null) {
436:
437: cin = getCipherInputStream();
438:
439: }
440:
441: if (logger.isLoggable(Level.FINEST)) {
442:
443: ByteArrayOutputStream decryptedContent = new ByteArrayOutputStream();
444:
445: byte[] buf = new byte[4096];
446:
447: try {
448:
449: for (int len = -1; (len = cin.read(buf)) != -1;) {
450:
451: decryptedContent.write(buf, 0, len);
452:
453: }
454:
455: logger.log(Level.FINEST, LogStringsMessages
456: .WSS_1951_ENCRYPTED_DATA_VALUE(new String(
457: decryptedContent.toByteArray())));
458:
459: cin = new ByteArrayInputStream(decryptedContent
460: .toByteArray());
461:
462: } catch (IOException ex) {
463:
464: ex.printStackTrace();
465:
466: }
467:
468: }
469:
470: CheckedInputStream ccin = null;
471:
472: try {
473:
474: ccin = new CheckedInputStream(cin);
475:
476: if (ccin.isEmpty()) {
477:
478: return null;
479:
480: }
481:
482: } catch (IOException ioe) {
483:
484: throw new XWSSecurityException(ioe);
485:
486: }
487:
488: DecryptedInputStream decryptedStream = new DecryptedInputStream(
489: ccin, parentNS);
490:
491: XMLInputFactory xif = XMLInputFactory.newInstance();
492:
493: XMLStreamReader reader = xif
494: .createXMLStreamReader(decryptedStream);
495:
496: return new FilteredXMLStreamReader(reader);
497:
498: }
499:
500: public XMLStreamReader getDecryptedData(Key key)
501: throws XMLStreamException, XWSSecurityException {
502:
503: if (cin == null) {
504:
505: cin = getCipherInputStream(key);
506:
507: }
508:
509: return getDecryptedData();
510:
511: }
512:
513: public String getId() {
514:
515: return id;
516:
517: }
518:
519: public void setId(final String id) {
520:
521: throw new UnsupportedOperationException();
522:
523: }
524:
525: public String getNamespaceURI() {
526:
527: return namespaceURI;
528:
529: }
530:
531: public String getLocalPart() {
532:
533: return localName;
534:
535: }
536:
537: public XMLStreamReader readHeader() throws XMLStreamException {
538:
539: throw new UnsupportedOperationException();
540:
541: }
542:
543: public void writeTo(OutputStream os) {
544:
545: throw new UnsupportedOperationException();
546:
547: }
548:
549: public void writeTo(XMLStreamWriter streamWriter)
550: throws XMLStreamException {
551:
552: throw new UnsupportedOperationException();
553:
554: }
555:
556: private int getEventType(XMLStreamReader reader) {
557:
558: if (reader.getEventType() == XMLStreamReader.START_ELEMENT) {
559:
560: if (reader.getLocalName() == ENCRYPTION_METHOD) {
561:
562: return ENCRYPTIONMETHOD_ELEMENT;
563:
564: }
565:
566: if (reader.getLocalName() == KEY_INFO) {
567:
568: return KEYINFO_ELEMENT;
569:
570: }
571:
572: if (reader.getLocalName() == CIPHER_DATA) {
573:
574: return CIPHER_DATA_ELEMENT;
575:
576: }
577:
578: }
579:
580: return -1;
581:
582: }
583:
584: public boolean refersToSecHdrWithId(final String id) {
585:
586: throw new UnsupportedOperationException();
587:
588: }
589:
590: public void writeTo(javax.xml.stream.XMLStreamWriter streamWriter,
591: HashMap props) throws javax.xml.stream.XMLStreamException {
592:
593: throw new UnsupportedOperationException();
594:
595: }
596:
597: public WSSPolicy getInferredKB() {
598:
599: return inferredKB;
600:
601: }
602:
603: }
|