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.xml.ws.security.opt.api.NamespaceContextInfo;
026: import com.sun.xml.ws.security.opt.api.PolicyBuilder;
027: import com.sun.xml.ws.security.opt.api.SecurityElementWriter;
028: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
029: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
030: import com.sun.xml.ws.security.opt.impl.enc.CryptoProcessor;
031: import com.sun.xml.ws.security.opt.impl.incoming.processor.CipherDataProcessor;
032: import com.sun.xml.ws.security.opt.impl.incoming.processor.KeyInfoProcessor;
033: import com.sun.xml.ws.security.opt.impl.incoming.processor.ReferenceListProcessor;
034: import com.sun.xml.ws.security.opt.impl.util.StreamUtil;
035: import com.sun.xml.wss.XWSSecurityException;
036: import com.sun.xml.wss.impl.MessageConstants;
037: import com.sun.xml.wss.impl.misc.Base64;
038: import com.sun.xml.wss.impl.policy.mls.EncryptionPolicy;
039: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
040: import java.io.IOException;
041: import java.io.OutputStream;
042: import java.security.Key;
043: import java.security.MessageDigest;
044: import java.security.NoSuchAlgorithmException;
045: import java.util.ArrayList;
046: import java.util.HashMap;
047: import java.util.List;
048: import javax.crypto.Cipher;
049: import javax.xml.crypto.KeySelector.Purpose;
050: import javax.xml.stream.XMLStreamException;
051: import javax.xml.stream.XMLStreamReader;
052: import javax.xml.stream.XMLStreamWriter;
053: import com.sun.xml.wss.logging.impl.opt.crypto.LogStringsMessages;
054: import java.util.logging.Level;
055: import java.util.logging.Logger;
056: import com.sun.xml.wss.logging.LogDomainConstants;
057:
058: /**
059: *
060: * @author K.Venugopal@sun.com
061: */
062: public class EncryptedKey implements SecurityHeaderElement,
063: NamespaceContextInfo, SecurityElementWriter, PolicyBuilder {
064: private static final Logger logger = Logger.getLogger(
065: LogDomainConstants.IMPL_OPT_CRYPTO_DOMAIN,
066: LogDomainConstants.IMPL_OPT_CRYPTO_DOMAIN_BUNDLE);
067:
068: private static final String ENCRYPTION_METHOD = "EncryptionMethod"
069: .intern();
070: private static final String REFERENCE_LIST = "ReferenceList"
071: .intern();
072: private static final String CIPHER_DATA = "CipherData".intern();
073: private static final String KEYINFO = "KeyInfo".intern();
074: private static final String DIGEST_METHOD = "DigestMethod".intern();
075: private static final String KEY_SIZE = "KeySize".intern();
076:
077: private static final int KEYINFO_ELEMENT = 1;
078: private static final int ENCRYPTIONMETHOD_ELEMENT = 2;
079:
080: private static final int REFERENCE_LIST_ELEMENT = 4;
081: private static final int CIPHER_DATA_ELEMENT = 5;
082: private static final int KEY_SIZE_ELEMENT = 6;
083: private static final int DIGEST_METHOD_ELEMENT = 7;
084:
085: private String id = "";
086: private String namespaceURI = "";
087: private String localName = "";
088: private String encryptionMethod = "";
089: private Key keyEncKey = null;
090: private ArrayList<String> referenceList = null;
091: private JAXBFilterProcessingContext pc = null;
092: private Key dataEncKey = null;
093: private ArrayList<String> pendingRefList = null;
094:
095: private HashMap<String, String> nsDecls;
096:
097: private CryptoProcessor cp = null;
098: private CipherDataProcessor cdp = null;
099:
100: private EncryptionPolicy encPolicy = null;
101: private WSSPolicy inferredKB = null;
102: private boolean ignoreEKSHA1 = false;
103: private boolean emPresent = false;
104:
105: /** Creates a new instance of EncryptedKey */
106: public EncryptedKey(XMLStreamReader reader,
107: JAXBFilterProcessingContext pc, HashMap nsDecls)
108: throws XMLStreamException, XWSSecurityException {
109: this .pc = pc;
110: this .nsDecls = nsDecls;
111: process(reader);
112: }
113:
114: public EncryptedKey(XMLStreamReader reader,
115: JAXBFilterProcessingContext pc, HashMap nsDecls,
116: boolean ignoreEKSHA1) throws XMLStreamException,
117: XWSSecurityException {
118: this .pc = pc;
119: this .ignoreEKSHA1 = ignoreEKSHA1;
120: this .nsDecls = nsDecls;
121: process(reader);
122: }
123:
124: public boolean refersToSecHdrWithId(final String id) {
125: throw new UnsupportedOperationException();
126: }
127:
128: public String getId() {
129: return id;
130: }
131:
132: public void setId(final String id) {
133: throw new UnsupportedOperationException();
134: }
135:
136: public String getNamespaceURI() {
137: return namespaceURI;
138: }
139:
140: public String getLocalPart() {
141: return localName;
142: }
143:
144: public XMLStreamReader readHeader() throws XMLStreamException {
145: throw new UnsupportedOperationException();
146: }
147:
148: public void writeTo(OutputStream os) {
149: throw new UnsupportedOperationException();
150: }
151:
152: public void writeTo(XMLStreamWriter streamWriter)
153: throws XMLStreamException {
154: throw new UnsupportedOperationException();
155: }
156:
157: private void process(XMLStreamReader reader)
158: throws XMLStreamException, XWSSecurityException {
159: id = reader.getAttributeValue(null, "Id");
160:
161: if (pc.isBSP()) {
162: String tmp = reader.getAttributeValue(null, "Recipient");
163: if (tmp != null) {
164: //log BSP R5602
165: logger.log(Level.SEVERE,
166: com.sun.xml.wss.logging.LogStringsMessages
167: .BSP_5602_ENCRYPTEDKEY_RECIPIENT(id));
168: throw new XWSSecurityException(
169: com.sun.xml.wss.logging.LogStringsMessages
170: .BSP_5602_ENCRYPTEDKEY_RECIPIENT(id));
171: }
172:
173: String mt = reader.getAttributeValue(null, "MimeType");
174: if (mt != null) {
175: //log BSP R5622
176: logger.log(Level.SEVERE,
177: com.sun.xml.wss.logging.LogStringsMessages
178: .BSP_5622_ENCRYPTEDKEY_MIMETYPE(id));
179: throw new XWSSecurityException(
180: com.sun.xml.wss.logging.LogStringsMessages
181: .BSP_5622_ENCRYPTEDKEY_MIMETYPE(id));
182: }
183:
184: String et = reader.getAttributeValue(null, "Encoding");
185: if (et != null) {
186: //log BSP R5623
187: logger.log(Level.SEVERE,
188: com.sun.xml.wss.logging.LogStringsMessages
189: .BSP_5623_ENCRYPTEDKEY_ENCODING(id));
190: throw new XWSSecurityException(
191: com.sun.xml.wss.logging.LogStringsMessages
192: .BSP_5623_ENCRYPTEDKEY_ENCODING(id));
193: }
194: }
195: namespaceURI = reader.getNamespaceURI();
196: localName = reader.getLocalName();
197:
198: if (StreamUtil.moveToNextElement(reader)) {
199: int refElement = getEventType(reader);
200: while (reader.getEventType() != reader.END_DOCUMENT) {
201: switch (refElement) {
202: case ENCRYPTIONMETHOD_ELEMENT: {
203: processEncryptionMethod(reader);
204: reader.next();
205: emPresent = true;
206: break;
207: }
208: case KEYINFO_ELEMENT: {
209: pc.getSecurityContext().setInferredKB(null);
210: KeyInfoProcessor kip = new KeyInfoProcessor(pc,
211: Purpose.DECRYPT);
212: keyEncKey = kip.getKey(reader);
213: inferredKB = (WSSPolicy) pc.getSecurityContext()
214: .getInferredKB();
215: pc.getSecurityContext().setInferredKB(null);
216: break;
217: }
218: case REFERENCE_LIST_ELEMENT: {
219: encPolicy = new EncryptionPolicy();
220: encPolicy
221: .setFeatureBinding(new EncryptionPolicy.FeatureBinding());
222: ReferenceListProcessor rlp = new ReferenceListProcessor(
223: encPolicy);
224: rlp.process(reader);
225: referenceList = rlp.getReferences();
226: pendingRefList = (ArrayList<String>) referenceList
227: .clone();
228: break;
229: }
230: case CIPHER_DATA_ELEMENT: {
231: cdp = new CipherDataProcessor();
232: cdp.process(reader);
233: if (!ignoreEKSHA1) {
234: try {
235: byte[] decodedCipher = cdp.readAsBytes();//Base64.decode(cipherValue);
236: byte[] ekSha1 = MessageDigest.getInstance(
237: "SHA-1").digest(decodedCipher);
238: String encEkSha1 = Base64.encode(ekSha1);
239: if (!pc.isSAMLEK())
240: pc.setExtraneousProperty(
241: MessageConstants.EK_SHA1_VALUE,
242: encEkSha1);
243:
244: } catch (NoSuchAlgorithmException nsae) {
245: throw new XWSSecurityException(nsae);
246: }
247: }
248: cp = new CryptoProcessor(Cipher.UNWRAP_MODE,
249: encryptionMethod, keyEncKey);
250:
251: break;
252: }
253: default: {
254: if (StreamUtil.isStartElement(reader)) {
255: throw new XWSSecurityException(
256: "Element name "
257: + reader.getName()
258: + " is not recognized under EncryptedKey");
259: }
260: }
261: }
262:
263: if (shouldBreak(reader)) {
264: break;
265: }
266: if (reader.getEventType() == XMLStreamReader.START_ELEMENT) {
267: if (getEventType(reader) == -1)
268: reader.next();
269:
270: } else {
271: reader.next();
272: }
273: refElement = getEventType(reader);
274: }
275: }
276:
277: if (pc.isBSP()) {
278: if (emPresent) {
279: logger
280: .log(
281: Level.SEVERE,
282: com.sun.xml.wss.logging.LogStringsMessages
283: .BSP_5603_ENCRYPTEDKEY_ENCRYPTIONMEHOD(id));
284: throw new XWSSecurityException(
285: com.sun.xml.wss.logging.LogStringsMessages
286: .BSP_5603_ENCRYPTEDKEY_ENCRYPTIONMEHOD(id));
287: }
288: }
289: }
290:
291: private boolean shouldBreak(XMLStreamReader reader)
292: throws XMLStreamException {
293: if (StreamUtil._break(reader, "EncryptedKey",
294: MessageConstants.XENC_NS)) {
295: return true;
296: }
297: if (reader.getEventType() == XMLStreamReader.END_DOCUMENT) {
298: return true;
299: }
300: return false;
301: }
302:
303: private void processEncryptionMethod(XMLStreamReader reader)
304: throws XMLStreamException, XWSSecurityException {
305: encryptionMethod = reader.getAttributeValue(null, "Algorithm");
306: if (encryptionMethod == null || encryptionMethod.length() == 0) {
307: logger.log(Level.SEVERE, LogStringsMessages
308: .WSS_1925_EMPTY_ENCMETHOD_ED());
309: throw new XWSSecurityException(LogStringsMessages
310: .WSS_1925_EMPTY_ENCMETHOD_ED());
311: }
312:
313: while (reader.getEventType() != reader.END_DOCUMENT) {
314: int eventType = getEventType(reader);
315: switch (eventType) {
316: case DIGEST_METHOD_ELEMENT: {
317: //String localName = reader.getLocalName();
318: break;
319: }
320: case KEY_SIZE_ELEMENT: {
321: //String localName = reader.getLocalName();
322: break;
323: }
324: default: {
325: break;
326: }
327: }
328: if (reader.getEventType() == XMLStreamReader.END_ELEMENT
329: && reader.getLocalName() == ENCRYPTION_METHOD) {
330: break;
331: }
332: reader.next();
333: }
334: }
335:
336: private int getEventType(XMLStreamReader reader) {
337: if (reader.getEventType() == XMLStreamReader.START_ELEMENT) {
338: if (reader.getLocalName() == ENCRYPTION_METHOD) {
339: return ENCRYPTIONMETHOD_ELEMENT;
340: }
341:
342: if (reader.getLocalName() == CIPHER_DATA) {
343: return CIPHER_DATA_ELEMENT;
344: }
345: if (reader.getLocalName() == REFERENCE_LIST) {
346: return REFERENCE_LIST_ELEMENT;
347: }
348:
349: if (reader.getLocalName() == KEYINFO) {
350: return KEYINFO_ELEMENT;
351: }
352:
353: if (reader.getLocalName() == DIGEST_METHOD) {
354: return DIGEST_METHOD_ELEMENT;
355: }
356: if (reader.getLocalName() == KEY_SIZE) {
357: return KEY_SIZE_ELEMENT;
358: }
359: }
360: return -1;
361: }
362:
363: public List<String> getReferenceList() {
364: return referenceList;
365: }
366:
367: public List<String> getPendingReferenceList() {
368: return pendingRefList;
369: }
370:
371: public Key getKey(String encAlgo) throws XWSSecurityException {
372: if (dataEncKey == null) {
373: try {
374: dataEncKey = cp.decryptKey(cdp.readAsBytes(), encAlgo);
375: } catch (IOException ex) {
376: logger.log(Level.SEVERE, LogStringsMessages
377: .WSS_1927_ERROR_DECRYPT_ED("EncryptedKey"));
378: throw new XWSSecurityException(LogStringsMessages
379: .WSS_1927_ERROR_DECRYPT_ED("EncryptedKey"), ex);
380: }
381: if (!ignoreEKSHA1)
382: pc.setExtraneousProperty(
383: MessageConstants.SECRET_KEY_VALUE, dataEncKey);
384: }
385: return dataEncKey;
386: }
387:
388: public HashMap<String, String> getInscopeNSContext() {
389: return nsDecls;
390: }
391:
392: public void writeTo(javax.xml.stream.XMLStreamWriter streamWriter,
393: HashMap props) throws javax.xml.stream.XMLStreamException {
394: throw new UnsupportedOperationException();
395: }
396:
397: public WSSPolicy getPolicy() {
398: return encPolicy;
399: }
400:
401: public WSSPolicy getInferredKB() {
402: return inferredKB;
403: }
404:
405: }
|