0001: /*
0002: * The contents of this file are subject to the terms
0003: * of the Common Development and Distribution License
0004: * (the License). You may not use this file except in
0005: * compliance with the License.
0006: *
0007: * You can obtain a copy of the license at
0008: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
0009: * See the License for the specific language governing
0010: * permissions and limitations under the License.
0011: *
0012: * When distributing Covered Code, include this CDDL
0013: * Header Notice in each file and include the License file
0014: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
0015: * If applicable, add the following below the CDDL Header,
0016: * with the fields enclosed by brackets [] replaced by
0017: * you own identifying information:
0018: * "Portions Copyrighted [year] [name of copyright owner]"
0019: *
0020: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
0021: */
0022:
0023: package com.sun.xml.ws.security.opt.impl.incoming;
0024:
0025: import com.sun.xml.ws.api.SOAPVersion;
0026: import com.sun.xml.ws.api.message.HeaderList;
0027: import com.sun.xml.ws.api.message.Header;
0028: import com.sun.xml.ws.api.message.Message;
0029: import com.sun.xml.ws.encoding.TagInfoset;
0030: import com.sun.xml.ws.message.AttachmentSetImpl;
0031: import com.sun.xml.ws.message.stream.StreamMessage;
0032: import com.sun.xml.ws.protocol.soap.VersionMismatchException;
0033: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
0034: import com.sun.xml.ws.security.opt.api.TokenValidator;
0035: import com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext;
0036: import com.sun.xml.ws.security.opt.impl.incoming.processor.SecurityHeaderProcessor;
0037: import com.sun.xml.ws.security.opt.impl.incoming.processor.SecurityTokenProcessor;
0038: import com.sun.xml.ws.security.opt.impl.util.StreamUtil;
0039: import com.sun.xml.ws.streaming.XMLStreamReaderUtil;
0040: import com.sun.xml.wss.XWSSecurityException;
0041: import com.sun.xml.wss.impl.MessageConstants;
0042: import com.sun.xml.wss.impl.PolicyResolver;
0043: import com.sun.xml.wss.impl.PolicyTypeUtil;
0044: import com.sun.xml.wss.impl.c14n.AttributeNS;
0045: import com.sun.xml.wss.impl.c14n.StAXAttr;
0046: import com.sun.xml.wss.impl.policy.mls.EncryptionPolicy;
0047: import com.sun.xml.wss.impl.policy.mls.EncryptionTarget;
0048: import com.sun.xml.wss.impl.policy.mls.MessagePolicy;
0049: import com.sun.xml.wss.impl.policy.mls.SignaturePolicy;
0050: import com.sun.xml.wss.impl.policy.mls.SignatureTarget;
0051: import com.sun.xml.wss.impl.policy.mls.Target;
0052: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
0053: import com.sun.xml.wss.impl.policy.verifier.MessagePolicyVerifier;
0054: import com.sun.xml.wss.impl.policy.verifier.TargetResolver;
0055: import com.sun.xml.wss.logging.LogDomainConstants;
0056: import java.io.ByteArrayInputStream;
0057: import java.io.ByteArrayOutputStream;
0058: import java.io.IOException;
0059: import java.io.InputStream;
0060: import java.io.OutputStream;
0061: import java.util.ArrayList;
0062: import java.util.HashMap;
0063: import java.util.Iterator;
0064: import java.util.List;
0065: import java.util.Vector;
0066: import java.util.logging.Logger;
0067: import java.util.logging.Level;
0068: import javax.xml.namespace.QName;
0069: import javax.xml.stream.XMLInputFactory;
0070: import javax.xml.stream.XMLOutputFactory;
0071: import javax.xml.stream.XMLStreamConstants;
0072: import javax.xml.stream.XMLStreamException;
0073: import javax.xml.stream.XMLStreamReader;
0074: import com.sun.xml.stream.buffer.XMLStreamBuffer;
0075: import com.sun.xml.stream.buffer.XMLStreamBufferException;
0076: import com.sun.xml.stream.buffer.XMLStreamBufferMark;
0077: import com.sun.xml.stream.buffer.stax.StreamReaderBufferCreator;
0078: import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
0079: import com.sun.xml.ws.api.streaming.XMLStreamReaderFactory;
0080: import com.sun.xml.wss.BasicSecurityProfile;
0081: import java.util.Map;
0082: import javax.xml.stream.XMLStreamWriter;
0083: import javax.xml.ws.WebServiceException;
0084: import com.sun.xml.wss.logging.impl.opt.LogStringsMessages;
0085: import static com.sun.xml.wss.BasicSecurityProfile.*;
0086: import com.sun.xml.ws.security.opt.impl.util.VerifiedMessageXMLStreamReader;
0087:
0088: /**
0089: *
0090: * @author K.Venugopal@sun.com
0091: */
0092:
0093: public final class SecurityRecipient {
0094:
0095: private static final Logger logger = Logger.getLogger(
0096: LogDomainConstants.IMPL_OPT_DOMAIN,
0097: LogDomainConstants.IMPL_OPT_DOMAIN_BUNDLE);
0098:
0099: //TODO Move static block to SecurityPipeBase .
0100: static {
0101: com.sun.org.apache.xml.internal.security.Init.init();
0102: }
0103:
0104: private static final int TIMESTAMP_ELEMENT = 1;
0105: private static final int USERNAME_TOKEN_ELEMENT = 2;
0106: private static final int BINARYSECURITY_TOKEN_ELEMENT = 3;
0107: private static final int ENCRYPTED_DATA_ELEMENT = 4;
0108: private static final int ENCRYPTED_KEY_ELEMENT = 5;
0109: private static final int SIGNATURE_ELEMENT = 6;
0110: private static final int REFERENCE_LIST_ELEMENT = 7;
0111: private static final int DERIVED_KEY_ELEMENT = 8;
0112: private static final int SIGNATURE_CONFIRMATION_ELEMENT = 9;
0113: private static final int SECURITY_CONTEXT_TOKEN = 10;
0114: private static final int SAML_ASSERTION_ELEMENT = 11;
0115: private static final int ENCRYPTED_HEADER_ELEMENT = 12;
0116: private static final int STR_ELEMENT = 13;
0117: private static final String SOAP_ENVELOPE = "Envelope";
0118: private static final String SOAP_HEADER = "Header";
0119: private static final String SOAP_BODY = "Body";
0120:
0121: private final String SOAP_NAMESPACE_URI;
0122: private final SOAPVersion soapVersion;
0123:
0124: private XMLStreamReader message = null;
0125: private StreamReaderBufferCreator creator = null;
0126: private HashMap<String, String> parentNS = new HashMap<String, String>();
0127: private HashMap<String, String> securityHeaderNS = new HashMap<String, String>();
0128: private HashMap<String, String> bodyENVNS = new HashMap<String, String>();
0129: private HashMap<String, String> envshNS = null;
0130: // for future use
0131: private XMLInputFactory staxIF = null;
0132: private JAXBFilterProcessingContext context = null;
0133: private HeaderList headers = null;
0134: private TagInfoset headerTag = null;
0135: private TagInfoset envelopeTag = null;
0136: private ArrayList processedHeaders = new ArrayList(2);
0137: private SecurityHeaderElement pendingElement = null;
0138: private ArrayList bufferedHeaders = new ArrayList();
0139: private SecurityContext securityContext = null;
0140: private TagInfoset bodyTag = null;
0141: private String bodyWsuId = "";
0142: private String payLoadWsuId = "";
0143: private String payLoadEncId = "";
0144: private HashMap<String, String> encIds = new HashMap<String, String>();
0145: private HashMap<String, QName> encQNames = new HashMap<String, QName>();
0146: private HashMap<String, String> edAlgos = new HashMap<String, String>();
0147: //used for bsp checks
0148: private BasicSecurityProfile bspContext = new BasicSecurityProfile();
0149:
0150: //private boolean isBSP = false;
0151: public SecurityRecipient(XMLStreamReader reader,
0152: SOAPVersion soapVersion) {
0153:
0154: this .message = reader;
0155: this .soapVersion = soapVersion;
0156: this .SOAP_NAMESPACE_URI = soapVersion.nsUri;
0157: securityContext = new SecurityContext();
0158: }
0159:
0160: public Message validateMessage(JAXBFilterProcessingContext ctx)
0161: throws XWSSecurityException {
0162: try {
0163: this .context = ctx;
0164: context.setSecurityContext(securityContext);
0165: // Move to soap:Envelope and verify
0166:
0167: //unconditionally set these since the policy is unknown
0168: context.setExtraneousProperty("EnableWSS11PolicyReceiver",
0169: "true");
0170: List scList = new ArrayList();
0171: context.setExtraneousProperty("receivedSignValues", scList);
0172:
0173: if (message.getEventType() != XMLStreamConstants.START_ELEMENT) {
0174: XMLStreamReaderUtil.nextElementContent(message);
0175: }
0176: XMLStreamReaderUtil.verifyReaderState(message,
0177: XMLStreamConstants.START_ELEMENT);
0178: if (SOAP_ENVELOPE.equals(message.getLocalName())
0179: && !SOAP_NAMESPACE_URI.equals(message
0180: .getNamespaceURI())) {
0181: throw new VersionMismatchException(soapVersion,
0182: SOAP_NAMESPACE_URI, message.getNamespaceURI());
0183: }
0184: XMLStreamReaderUtil.verifyTag(message, SOAP_NAMESPACE_URI,
0185: SOAP_ENVELOPE);
0186:
0187: envelopeTag = new TagInfoset(message);
0188: for (int i = 0; i < message.getNamespaceCount(); i++) {
0189: parentNS.put(message.getNamespacePrefix(i), message
0190: .getNamespaceURI(i));
0191: }
0192: // Move to next element
0193: XMLStreamReaderUtil.nextElementContent(message);
0194: XMLStreamReaderUtil.verifyReaderState(message,
0195: javax.xml.stream.XMLStreamConstants.START_ELEMENT);
0196:
0197: if (message.getLocalName().equals(SOAP_HEADER)
0198: && message.getNamespaceURI().equals(
0199: SOAP_NAMESPACE_URI)) {
0200: headerTag = new TagInfoset(message);
0201:
0202: // Collect namespaces on soap:Header
0203: for (int i = 0; i < message.getNamespaceCount(); i++) {
0204: parentNS.put(message.getNamespacePrefix(i), message
0205: .getNamespaceURI(i));
0206: }
0207: // skip <soap:Header>
0208: XMLStreamReaderUtil.nextElementContent(message);
0209:
0210: // If SOAP header blocks are present (i.e. not <soap:Header/>)
0211: if (message.getEventType() == XMLStreamConstants.START_ELEMENT) {
0212: this .headers = new HeaderList();
0213: // Cache SOAP header blocks
0214: cacheHeaders(message, parentNS);
0215:
0216: }
0217: // Move to soap:Body
0218: XMLStreamReaderUtil.nextElementContent(message);
0219: }
0220:
0221: return createMessage();
0222: } catch (WebServiceException te) {
0223: Message msg = new StreamMessage(envelopeTag, headerTag,
0224: new AttachmentSetImpl(), headers, bodyTag,
0225: getEmptyBodyNoException(), soapVersion);
0226: ctx.setPVMessage(msg);
0227: throw te;
0228: } catch (XMLStreamException e) {
0229: // TODO need to throw more meaningful exception
0230: Message msg = new StreamMessage(envelopeTag, headerTag,
0231: new AttachmentSetImpl(), headers, bodyTag,
0232: getEmptyBodyNoException(), soapVersion);
0233: ctx.setPVMessage(msg);
0234: throw new WebServiceException(e);
0235: } catch (XWSSecurityException xe) {
0236: Message msg = new StreamMessage(envelopeTag, headerTag,
0237: new AttachmentSetImpl(), headers, bodyTag,
0238: getEmptyBodyNoException(), soapVersion);
0239: ctx.setPVMessage(msg);
0240: throw xe;
0241: }
0242: }
0243:
0244: private void cacheHeaders(XMLStreamReader reader,
0245: Map<String, String> namespaces) throws XMLStreamException,
0246: XWSSecurityException {
0247:
0248: creator = new StreamReaderBufferCreator();
0249: MutableXMLStreamBuffer buffer = new MutableXMLStreamBuffer();
0250: creator.setXMLStreamBuffer(buffer);
0251: // Reader is positioned at the first header block
0252: while (reader.getEventType() == javax.xml.stream.XMLStreamConstants.START_ELEMENT) {
0253: Map<String, String> headerBlockNamespaces = namespaces;
0254:
0255: // Create Header
0256: if (reader.getLocalName().equals("Security")) {
0257: // Collect namespaces on SOAP header block
0258: if (reader.getNamespaceCount() > 0) {
0259: headerBlockNamespaces = new HashMap<String, String>(
0260: namespaces);
0261: for (int i = 0; i < reader.getNamespaceCount(); i++) {
0262: headerBlockNamespaces.put(reader
0263: .getNamespacePrefix(i), reader
0264: .getNamespaceURI(i));
0265: }
0266: }
0267: // Mark
0268: XMLStreamBuffer mark = new XMLStreamBufferMark(
0269: headerBlockNamespaces, creator);
0270: handleSecurityHeader();
0271: } else {
0272: try {
0273: // Collect namespaces on SOAP header block
0274: if (reader.getNamespaceCount() > 0) {
0275: headerBlockNamespaces = new HashMap<String, String>(
0276: namespaces);
0277: for (int i = 0; i < reader.getNamespaceCount(); i++) {
0278: headerBlockNamespaces.put(reader
0279: .getNamespacePrefix(i), reader
0280: .getNamespaceURI(i));
0281: }
0282: }
0283: // Mark
0284: XMLStreamBuffer mark = new XMLStreamBufferMark(
0285: headerBlockNamespaces, creator);
0286: GenericSecuredHeader gsh = new GenericSecuredHeader(
0287: reader, soapVersion, creator,
0288: (HashMap) namespaces, staxIF, context
0289: .getEncHeaderContent());
0290: headers.add(gsh);
0291:
0292: } catch (XMLStreamBufferException ex) {
0293: throw new XWSSecurityException(
0294: "Error occurred while reading SOAP Header"
0295: + ex);
0296: }
0297: }
0298: while (reader.isWhiteSpace()) {
0299: reader.next();
0300: }
0301: }
0302: }
0303:
0304: private void handleSecurityHeader() throws XWSSecurityException {
0305: // MutableXMLStreamBuffer buffer = new MutableXMLStreamBuffer();
0306: try {
0307: if (message.getEventType() == XMLStreamReader.START_ELEMENT) {
0308: if (message.getLocalName() == MessageConstants.WSSE_SECURITY_LNAME) {
0309: for (int i = 0; i < message.getNamespaceCount(); i++) {
0310: securityHeaderNS.put(message
0311: .getNamespacePrefix(i), message
0312: .getNamespaceURI(i));
0313: }
0314: StreamUtil.moveToNextStartOREndElement(message);
0315: }
0316: }
0317:
0318: HashMap<String, String> currentParentNS = new HashMap<String, String>();
0319: currentParentNS.putAll(parentNS);
0320: currentParentNS.putAll(securityHeaderNS);
0321: envshNS = currentParentNS;
0322: int eventType = getSecurityElementType();
0323: securityContext.setSOAPEnvelopeNSDecls(parentNS);
0324: securityContext.setSecurityHdrNSDecls(securityHeaderNS);
0325: securityContext.setNonSecurityHeaders(headers);
0326: securityContext
0327: .setProcessedSecurityHeaders(processedHeaders);
0328: securityContext.setBufferedSecurityHeaders(bufferedHeaders);
0329: context.setSecurityContext(securityContext);
0330: while (message.getEventType() != message.END_DOCUMENT) {
0331: switch (eventType) {
0332: case TIMESTAMP_ELEMENT: {
0333: if (context.isBSP()
0334: && bspContext.isTimeStampFound()) {
0335: log_bsp_3203();
0336: }
0337: bspContext.setTimeStampFound(true);
0338: TimestampHeader timestamp = new TimestampHeader(
0339: message, creator,
0340: (HashMap) currentParentNS, context);
0341: WSSPolicy policy = timestamp.getPolicy();
0342: ((TokenValidator) timestamp).validate(context);
0343: processedHeaders.add(timestamp);
0344: context.getInferredSecurityPolicy().append(
0345: timestamp.getPolicy());
0346: break;
0347: }
0348: case USERNAME_TOKEN_ELEMENT: {
0349: UsernameTokenHeader ut = new UsernameTokenHeader(
0350: message, creator,
0351: (HashMap) currentParentNS, staxIF);
0352: ut.validate(context);
0353: context.getSecurityContext()
0354: .getProcessedSecurityHeaders().add(ut);
0355: context.getInferredSecurityPolicy().append(
0356: ut.getPolicy());
0357: break;
0358: }
0359: case BINARYSECURITY_TOKEN_ELEMENT: {
0360: BinarySecurityToken bst = new BinarySecurityToken(
0361: message, creator,
0362: (HashMap) currentParentNS, staxIF);
0363: WSSPolicy policy = bst.getPolicy();
0364: ((TokenValidator) bst).validate(context);
0365: processedHeaders.add(bst);
0366: context.getInferredSecurityPolicy().append(
0367: bst.getPolicy());
0368: break;
0369: }
0370: case ENCRYPTED_KEY_ELEMENT: {
0371: EncryptedKey ek = new EncryptedKey(message,
0372: context, (HashMap) currentParentNS);
0373: ArrayList<String> list = (ArrayList) ek
0374: .getPendingReferenceList();
0375: if (list != null) {
0376: findAndReplaceED(list, ek);
0377: if (ek.getPendingReferenceList().size() > 0) {
0378: if (pendingElement == null) {
0379: pendingElement = ek;
0380: }//else{
0381: addSecurityHeader(ek);
0382: //}
0383: }
0384: } else {
0385: addSecurityHeader(ek);
0386: }
0387: if (ek.getPolicy() != null) {
0388: context.getInferredSecurityPolicy().append(
0389: ek.getPolicy());
0390: }
0391: break;
0392: }
0393: case ENCRYPTED_DATA_ELEMENT: {
0394: EncryptedData ed = new EncryptedData(message,
0395: context, currentParentNS);
0396: handleEncryptedData(ed, currentParentNS);
0397: break;
0398: }
0399:
0400: case ENCRYPTED_HEADER_ELEMENT: {
0401: throw new XWSSecurityException(
0402: "wsse11:EncryptedHeader not allowed inside SecurityHeader");
0403: //break;
0404: }
0405:
0406: case REFERENCE_LIST_ELEMENT: {
0407: ReferenceListHeader refList = new ReferenceListHeader(
0408: message, context);
0409: if (pendingElement == null) {
0410: pendingElement = refList;
0411: } else {
0412: addSecurityHeader(refList);
0413: }
0414:
0415: context.getInferredSecurityPolicy().append(
0416: refList.getPolicy());
0417: break;
0418: }
0419: case SIGNATURE_ELEMENT: {
0420: Signature sig = new Signature(context,
0421: currentParentNS, creator);
0422: sig.process(message);
0423: if (!sig.isValidated()) {
0424: if (pendingElement == null) {
0425: pendingElement = sig;
0426: } else {
0427: addSecurityHeader(sig);
0428: }
0429: }
0430: context.getInferredSecurityPolicy().append(
0431: sig.getPolicy());
0432: break;
0433: }
0434: case DERIVED_KEY_ELEMENT: {
0435: DerivedKeyToken dkt = new DerivedKeyToken(message,
0436: context, (HashMap) currentParentNS);
0437: processedHeaders.add(dkt);
0438: break;
0439: }
0440: case SIGNATURE_CONFIRMATION_ELEMENT: {
0441: SignatureConfirmation signConfirm = new SignatureConfirmation(
0442: message, creator,
0443: (HashMap) currentParentNS, staxIF);
0444: WSSPolicy policy = signConfirm.getPolicy();
0445: signConfirm.validate(context);
0446: processedHeaders.add(signConfirm);
0447: context.getInferredSecurityPolicy().append(
0448: signConfirm.getPolicy());
0449: break;
0450: }
0451: case SECURITY_CONTEXT_TOKEN: {
0452: SecurityContextToken sct = new SecurityContextToken(
0453: message, context, (HashMap) currentParentNS);
0454: processedHeaders.add(sct);
0455: break;
0456: }
0457: case SAML_ASSERTION_ELEMENT: {
0458: SAMLAssertion samlAssertion = new SAMLAssertion(
0459: message, context, null,
0460: (HashMap) currentParentNS);
0461: processedHeaders.add(samlAssertion);
0462: if (samlAssertion.isHOK()) {
0463: samlAssertion.validateSignature();
0464: }
0465: samlAssertion.validate(context);
0466: samlAssertion.getKey();
0467: context.getExtraneousProperties().put(
0468: MessageConstants.INCOMING_SAML_ASSERTION,
0469: samlAssertion);
0470:
0471: break;
0472: }
0473: case STR_ELEMENT: {
0474: SecurityTokenProcessor str = new SecurityTokenProcessor(
0475: context, null);
0476: str.resolveReference(message);
0477: break;
0478: }
0479: default: {
0480:
0481: }
0482: }
0483: if (StreamUtil._break(message,
0484: MessageConstants.WSSE_SECURITY_LNAME,
0485: MessageConstants.WSSE_NS)) {
0486: break;
0487: }
0488: eventType = getSecurityElementType();
0489: if (eventType == -1
0490: && !StreamUtil.isStartElement(message)) {
0491: if (StreamUtil._break(message,
0492: MessageConstants.WSSE_SECURITY_LNAME,
0493: MessageConstants.WSSE_NS)) {
0494: break;
0495: } else {
0496: message.next();
0497: }
0498: }
0499: }
0500: message.next();
0501: } catch (XMLStreamException ex) {
0502: //ex.printStackTrace();
0503: logger.log(Level.FINE,
0504: "Error occurred while reading SOAP Headers", ex);
0505: throw new XWSSecurityException(ex);
0506: } catch (XMLStreamBufferException ex) {
0507: // ex.printStackTrace();
0508: logger.log(Level.FINE,
0509: "Error occurred while reading SOAP Headers", ex);
0510: throw new XWSSecurityException(ex);
0511: }
0512: }
0513:
0514: private void handleEncryptedData(EncryptedData ed,
0515: HashMap<String, String> currentParentNS)
0516: throws XMLStreamException, XWSSecurityException {
0517: if (pendingElement != null
0518: && pendingElement instanceof EncryptedKey) {
0519: EncryptedKey ek = ((EncryptedKey) pendingElement);
0520: if (ek.getPendingReferenceList() != null
0521: && ek.getPendingReferenceList()
0522: .contains(ed.getId())) {
0523: //for policy verification
0524: if (ek.getPolicy() != null) {
0525: ek.getPolicy().setKeyBinding(ek.getInferredKB());
0526: }
0527: //
0528:
0529: XMLStreamReader decryptedData = ed.getDecryptedData(ek
0530: .getKey(ed.getEncryptionAlgorithm()));
0531: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
0532: context, currentParentNS, staxIF, creator);
0533: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
0534: StreamUtil.moveToNextElement(decryptedData);
0535: SecurityHeaderElement she = shp
0536: .createHeader(decryptedData);
0537: encIds.put(ed.getId(), she.getId());
0538: edAlgos.put(ed.getId(), ed.getEncryptionAlgorithm());
0539: //addSecurityHeader(she);
0540: ek.getPendingReferenceList().remove(ed.getId());
0541: if (ek.getPendingReferenceList().size() == 0) {
0542: pendingElement = null;
0543: bufferedHeaders.remove(ek);
0544: addSecurityHeader(ek);
0545: }
0546: checkDecryptedData(she);
0547: } else {
0548: if (!lookInBufferedHeaders(ed, currentParentNS))
0549: addSecurityHeader(ed);
0550: }
0551: } else if (pendingElement != null
0552: && pendingElement instanceof ReferenceListHeader) {
0553: ReferenceListHeader refList = (ReferenceListHeader) pendingElement;
0554: if (refList.getPendingReferenceList().contains(ed.getId())) {
0555: //for policy verification
0556: refList.getPolicy().setKeyBinding(ed.getInferredKB());
0557: //
0558:
0559: XMLStreamReader decryptedData = ed.getDecryptedData();
0560: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
0561: StreamUtil.moveToNextElement(decryptedData);
0562: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
0563: context, currentParentNS, staxIF, creator);
0564: SecurityHeaderElement she = shp
0565: .createHeader(decryptedData);
0566: encIds.put(ed.getId(), she.getId());
0567: edAlgos.put(ed.getId(), ed.getEncryptionAlgorithm());
0568: //addSecurityHeader(she);
0569: refList.getPendingReferenceList().remove(ed.getId());
0570: if (refList.getPendingReferenceList().size() == 0) {
0571: pendingElement = null;
0572: }
0573: checkDecryptedData(she);
0574: } else {
0575: if (!lookInBufferedHeaders(ed, currentParentNS))
0576: decryptStandaloneED(ed, currentParentNS);
0577: }
0578: } else {
0579: if (!lookInBufferedHeaders(ed, currentParentNS))
0580: decryptStandaloneED(ed, currentParentNS);
0581: }
0582: }
0583:
0584: private boolean lookInBufferedHeaders(EncryptedData ed,
0585: HashMap<String, String> currentParentNS)
0586: throws XWSSecurityException, XMLStreamException {
0587: if (bufferedHeaders.size() > 0) {
0588: for (int i = 0; i < bufferedHeaders.size(); i++) {
0589: SecurityHeaderElement bufShe = (SecurityHeaderElement) bufferedHeaders
0590: .get(i);
0591: if (bufShe.getLocalPart() == MessageConstants.ENCRYPTEDKEY_LNAME
0592: && bufShe.getNamespaceURI() == MessageConstants.XENC_NS) {
0593: EncryptedKey ek = ((EncryptedKey) bufShe);
0594: if (ek.getPendingReferenceList() != null
0595: && ek.getPendingReferenceList().contains(
0596: ed.getId())) {
0597: //for policy verification
0598: if (ek.getPolicy() != null) {
0599: ek.getPolicy().setKeyBinding(
0600: ek.getInferredKB());
0601: }
0602:
0603: XMLStreamReader decryptedData = ed
0604: .getDecryptedData(ek.getKey(ed
0605: .getEncryptionAlgorithm()));
0606: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
0607: context, currentParentNS, staxIF,
0608: creator);
0609: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
0610: StreamUtil.moveToNextElement(decryptedData);
0611: SecurityHeaderElement she = shp
0612: .createHeader(decryptedData);
0613: encIds.put(ed.getId(), she.getId());
0614: edAlgos.put(ed.getId(), ed
0615: .getEncryptionAlgorithm());
0616: //addSecurityHeader(she);
0617: ek.getPendingReferenceList().remove(ed.getId());
0618: checkDecryptedData(she);
0619: return true;
0620: }
0621:
0622: } else if (bufShe.getLocalPart() == MessageConstants.XENC_REFERENCE_LIST_LNAME
0623: && bufShe.getNamespaceURI() == MessageConstants.XENC_NS) {
0624: ReferenceListHeader refList = (ReferenceListHeader) bufShe;
0625: if (refList.getPendingReferenceList().contains(
0626: ed.getId())) {
0627: //for policy verification
0628: refList.getPolicy().setKeyBinding(
0629: ed.getInferredKB());
0630: //
0631:
0632: XMLStreamReader decryptedData = ed
0633: .getDecryptedData();
0634: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
0635: StreamUtil.moveToNextElement(decryptedData);
0636: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
0637: context, currentParentNS, staxIF,
0638: creator);
0639: SecurityHeaderElement she = shp
0640: .createHeader(decryptedData);
0641: encIds.put(ed.getId(), she.getId());
0642: edAlgos.put(ed.getId(), ed
0643: .getEncryptionAlgorithm());
0644: //addSecurityHeader(she);
0645: refList.getPendingReferenceList().remove(
0646: ed.getId());
0647: checkDecryptedData(she);
0648: return true;
0649: }
0650: }
0651: }
0652: }
0653: return false;
0654: }
0655:
0656: private void decryptStandaloneED(EncryptedData ed,
0657: HashMap<String, String> currentParentNS)
0658: throws XMLStreamException, XWSSecurityException {
0659: if (ed.getKey() == null) { //can't decrypt now
0660: bufferedHeaders.add(ed);
0661: return;
0662: }
0663: XMLStreamReader decryptedData = ed.getDecryptedData();
0664: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
0665: StreamUtil.moveToNextElement(decryptedData);
0666: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
0667: context, currentParentNS, staxIF, creator);
0668: SecurityHeaderElement she = shp.createHeader(decryptedData);
0669: encIds.put(ed.getId(), she.getId());
0670: edAlgos.put(ed.getId(), ed.getEncryptionAlgorithm());
0671: checkDecryptedData(she);
0672: if (!handleSAMLAssertion(she)) {
0673: addSecurityHeader(she);
0674: }
0675: }
0676:
0677: private void checkDecryptedData(SecurityHeaderElement she)
0678: throws XWSSecurityException {
0679: if (she.getLocalPart() == MessageConstants.SIGNATURE_LNAME) {
0680: Signature sig = (Signature) she;
0681: if (sig.getReferences().size() != 0 && isPending()) {
0682: if (pendingElement == null) {
0683: pendingElement = she;
0684: } else {
0685: bufferedHeaders.add(sig);
0686: }
0687: }
0688: }
0689: }
0690:
0691: private Message createMessage() throws XWSSecurityException {
0692: // Verify that <soap:Body> is present
0693: XMLStreamReaderUtil.verifyTag(message, SOAP_NAMESPACE_URI,
0694: SOAP_BODY);
0695: bodyTag = new TagInfoset(message);
0696: bodyENVNS.putAll(parentNS);
0697: for (int i = 0; i < message.getNamespaceCount(); i++) {
0698: bodyENVNS.put(message.getNamespacePrefix(i), message
0699: .getNamespaceURI(i));
0700: }
0701: bodyWsuId = StreamUtil.getWsuId(message);
0702: if (bodyWsuId == null) {
0703: bodyWsuId = "";
0704: }
0705: XMLStreamReaderUtil.nextElementContent(message);
0706: cachePayLoadId();
0707: if (pendingElement != null) {
0708: //String id = StreamUtil.getWsuId(message);
0709: try {
0710: if (pendingElement instanceof EncryptedKey
0711: && StreamUtil.isStartElement(message)
0712: && isEncryptedData()) {
0713: XMLStreamReader reader = message;
0714: EncryptedData ed = new EncryptedData(message,
0715: context, bodyENVNS);
0716: payLoadWsuId = ed.getId();
0717: handlePayLoadED(ed);
0718: payLoadEncId = ed.getId();
0719: XMLStreamReaderUtil.close(reader);
0720: XMLStreamReaderFactory.recycle(reader);
0721: } else if (pendingElement instanceof Signature) {
0722: Signature sig = (Signature) pendingElement;
0723: handleSignature(sig);
0724:
0725: processedHeaders.add(pendingElement);
0726: pendingElement = null;
0727: } else if (pendingElement instanceof ReferenceListHeader) {
0728: ReferenceListHeader refList = (ReferenceListHeader) pendingElement;
0729: if (refList.getPendingReferenceList().contains(
0730: payLoadWsuId)) {
0731: XMLStreamReader reader = message;
0732: EncryptedData ed = new EncryptedData(message,
0733: context, bodyENVNS);
0734: //for policy verification
0735: refList.getPolicy().setKeyBinding(
0736: ed.getInferredKB());
0737: payLoadWsuId = ed.getId();
0738: handlePayLoadED(ed);
0739: refList.getPendingReferenceList().remove(
0740: payLoadWsuId);
0741: payLoadEncId = ed.getId();
0742: cachePayLoadId();
0743: XMLStreamReaderUtil.close(reader);
0744: XMLStreamReaderFactory.recycle(reader);
0745: }
0746: if (refList.getPendingReferenceList().size() > 0) {
0747: findAndReplaceED((ArrayList<String>) refList
0748: .getPendingReferenceList(), refList);
0749: }
0750: if (refList.getPendingReferenceList().size() == 0) {
0751: pendingElement = null;
0752: } else {
0753: String uri = refList.getPendingReferenceList()
0754: .get(0);
0755: throw new XWSSecurityException(
0756: "Reference with ID "
0757: + uri
0758: + " was not found in the message");
0759: }
0760:
0761: }
0762: } catch (XMLStreamException e) {
0763: // TODO need to throw more meaningful exception
0764: throw new WebServiceException(e);
0765: } catch (XWSSecurityException xse) {
0766: throw new WebServiceException(xse);
0767: }
0768: }
0769:
0770: ArrayList clonedBufferedHeaders = (ArrayList) bufferedHeaders
0771: .clone();
0772: if (clonedBufferedHeaders.size() > 0) {
0773: for (int i = 0; i < clonedBufferedHeaders.size(); i++) {
0774: SecurityHeaderElement she = (SecurityHeaderElement) clonedBufferedHeaders
0775: .get(i);
0776: processSecurityHeader(she);
0777: }
0778: }
0779: if (processedHeaders.size() > 0) {
0780: for (int i = 0; i < processedHeaders.size(); i++) {
0781: SecurityHeaderElement she = (SecurityHeaderElement) processedHeaders
0782: .get(i);
0783: processProcessedHeaders(she);
0784: }
0785: }
0786:
0787: try {
0788: if (message == null) {
0789: message = getEmptyBody();
0790: }
0791: } catch (XMLStreamException xse) {
0792: throw new XWSSecurityException(xse);
0793: }
0794:
0795: Message streamMsg = null;
0796: if (!context.getDisablePayloadBuffering()
0797: && !context.isSecure()) {
0798: if (logger.isLoggable(Level.FINE)) {
0799: logger.log(Level.FINE,
0800: "Buffering Payload from incomming message");
0801: }
0802: VerifiedMessageXMLStreamReader verifiedReader = new VerifiedMessageXMLStreamReader(
0803: message, bodyENVNS);
0804: streamMsg = new VerifiedStreamMessage(envelopeTag,
0805: headerTag, new AttachmentSetImpl(), headers,
0806: bodyTag, verifiedReader, soapVersion,
0807: this .bodyENVNS);
0808: } else {
0809: if (logger.isLoggable(Level.FINE)) {
0810: logger.log(Level.FINE,
0811: "Not Buffering Payload from incomming message");
0812: }
0813: streamMsg = new StreamMessage(envelopeTag, headerTag,
0814: new AttachmentSetImpl(), headers, bodyTag, message,
0815: soapVersion);
0816: }
0817: context.setMessage(streamMsg);
0818: boolean scCancel = false;
0819: if (streamMsg.isFault())
0820: return streamMsg;
0821: if (context.getAddressingVersion() != null) {
0822: String action = streamMsg.getHeaders().getAction(
0823: context.getAddressingVersion(),
0824: context.getSOAPVersion());
0825:
0826: if (MessageConstants.MEX_GET.equals(action)) {
0827: return streamMsg;
0828: }
0829: if (MessageConstants.CANCEL_SECURITY_CONTEXT_TOKEN_ACTION
0830: .equals(action)
0831: || MessageConstants.CANCEL_SECURITY_CONTEXT_TOKEN_RESPONSE_ACTION
0832: .equals(action)) {
0833: scCancel = true;
0834: }
0835: }
0836: MessagePolicy msgPolicy = (MessagePolicy) context
0837: .getSecurityPolicy();
0838: boolean isTrust = context.isTrustMessage();
0839: if (msgPolicy == null || msgPolicy.size() <= 0) {
0840: PolicyResolver opResolver = (PolicyResolver) context
0841: .getExtraneousProperty(context.OPERATION_RESOLVER);
0842: if (opResolver != null && !isTrust)
0843: msgPolicy = opResolver.resolvePolicy(context);
0844: }
0845: if (context.isSecure()
0846: && context.getInferredSecurityPolicy().size() == 0) {
0847: if (msgPolicy == null || msgPolicy.size() == 0) {
0848: return streamMsg;
0849: } else {
0850: throw new XWSSecurityException(
0851: "Security Requirements not met - No Security header in message");
0852: }
0853: }
0854:
0855: // for policy verification, replace target uris with qnames for signature and encryption targets
0856: try {
0857: MessagePolicy inferredMessagePolicy = context
0858: .getInferredSecurityPolicy();
0859: for (int i = 0; i < inferredMessagePolicy.size(); i++) {
0860: WSSPolicy wssPolicy = (WSSPolicy) inferredMessagePolicy
0861: .get(i);
0862: if (PolicyTypeUtil.signaturePolicy(wssPolicy)) {
0863: SignaturePolicy.FeatureBinding fb = (SignaturePolicy.FeatureBinding) wssPolicy
0864: .getFeatureBinding();
0865: ArrayList targets = fb.getTargetBindings();
0866: // replace uri target types with qname target types
0867: modifyTargets(targets);
0868: } else if (PolicyTypeUtil.encryptionPolicy(wssPolicy)) {
0869: EncryptionPolicy.FeatureBinding fb = (EncryptionPolicy.FeatureBinding) wssPolicy
0870: .getFeatureBinding();
0871: ArrayList targets = fb.getTargetBindings();
0872: // replace uri target types with qname target types
0873: modifyTargets(targets);
0874: }
0875: }
0876:
0877: } catch (Exception ex) {
0878: throw new XWSSecurityException(ex);
0879: }
0880:
0881: if (scCancel) {
0882: boolean securedBody = false;
0883: boolean allHeaders = false;
0884: try {
0885: MessagePolicy mp = context.getInferredSecurityPolicy();
0886: for (int i = 0; i < mp.size(); i++) {
0887: WSSPolicy wp = (WSSPolicy) mp.get(i);
0888: if (PolicyTypeUtil.encryptionPolicy(wp)) {
0889: EncryptionPolicy ep = (EncryptionPolicy) wp;
0890: ArrayList list = ((EncryptionPolicy.FeatureBinding) ep
0891: .getFeatureBinding())
0892: .getTargetBindings();
0893: for (int ei = 0; ei < list.size(); ei++) {
0894: EncryptionTarget et = (EncryptionTarget) list
0895: .get(ei);
0896: if (et.getValue().equals(Target.BODY)) {
0897: securedBody = true;
0898: }
0899: }
0900: } else if (PolicyTypeUtil.signaturePolicy(wp)) {
0901: SignaturePolicy sp = (SignaturePolicy) wp;
0902: ArrayList list = ((SignaturePolicy.FeatureBinding) sp
0903: .getFeatureBinding())
0904: .getTargetBindings();
0905: for (int ei = 0; ei < list.size(); ei++) {
0906: SignatureTarget st = (SignatureTarget) list
0907: .get(ei);
0908: //if(st.getValue() == Target.BODY){
0909: if (st.getValue().equals(Target.BODY)) {
0910: securedBody = true;
0911: }
0912: }
0913: if (!allHeaders) {
0914: allHeaders = areHeadersSecured(sp);
0915: }
0916: }
0917: }
0918: } catch (Exception ex) {
0919: throw new XWSSecurityException(ex);
0920: }
0921:
0922: if (!securedBody || !allHeaders) {
0923: logger.log(Level.SEVERE, LogStringsMessages
0924: .WSS_1602_SCCANCEL_SECURITY_UNCONFIGURED());
0925: throw new XWSSecurityException(
0926: "Security Requirements not met");
0927: }
0928: return streamMsg;
0929: }
0930:
0931: // for policy verification
0932: TargetResolver targetResolver = new TargetResolverImpl(context);
0933: MessagePolicyVerifier mpv = new MessagePolicyVerifier(context,
0934: targetResolver);
0935:
0936: if (msgPolicy != null) {
0937: if (msgPolicy.isSSL() && !context.isSecure()) {
0938: logger.log(Level.SEVERE, LogStringsMessages
0939: .WSS_1601_SSL_NOT_ENABLED());
0940: throw new XWSSecurityException(LogStringsMessages
0941: .WSS_1601_SSL_NOT_ENABLED());
0942: }
0943: }
0944: if (!isTrust) {
0945: mpv.verifyPolicy(context.getInferredSecurityPolicy(),
0946: msgPolicy);
0947: }
0948:
0949: return streamMsg;
0950: }
0951:
0952: private XMLStreamReader getEmptyBody() throws XMLStreamException {
0953: // create an empty body and create xmlstream reader out of it
0954: String emptyBody = "<S:Body xmlns:S=\"" + soapVersion.nsUri
0955: + "\"" + "></S:Body>";
0956: InputStream in = new ByteArrayInputStream(emptyBody.getBytes());
0957: XMLInputFactory xif = XMLInputFactory.newInstance();
0958: XMLStreamReader empBody = xif.createXMLStreamReader(in);
0959: empBody.next(); //next of start document
0960: empBody.next(); // next of Body, will point to end of body
0961: return empBody;
0962: }
0963:
0964: private XMLStreamReader getEmptyBodyNoException() {
0965: try {
0966: return getEmptyBody();
0967: } catch (XMLStreamException ex) {
0968: ex.printStackTrace();
0969: }
0970: return null;
0971: }
0972:
0973: // replace uri target types with qname target types
0974: private void modifyTargets(ArrayList targets) {
0975: for (int i = 0; i < targets.size(); i++) {
0976: Target target = (Target) targets.get(i);
0977: if (target.getType() == Target.TARGET_TYPE_VALUE_URI) {
0978: findAndReplaceTargets(target);
0979: }
0980: }
0981: }
0982:
0983: private boolean handleSAMLAssertion(SecurityHeaderElement she)
0984: throws XWSSecurityException {
0985: if (she.getLocalPart() == MessageConstants.SAML_ASSERTION_LNAME) {
0986: SAMLAssertion samlAssertion = (SAMLAssertion) she;
0987: processedHeaders.add(samlAssertion);
0988: if (samlAssertion.isHOK()) {
0989: samlAssertion.validateSignature();
0990: }
0991: samlAssertion.getKey();
0992: context.getExtraneousProperties().put(
0993: MessageConstants.INCOMING_SAML_ASSERTION,
0994: samlAssertion);
0995: return true;
0996: }
0997: return false;
0998: }
0999:
1000: private void findAndReplaceTargets(Target target) {
1001: String uri = target.getValue();
1002: int index = uri.indexOf("#");
1003: QName qname = null;
1004: if (index >= 0) {
1005: uri = uri.substring(index + 1);
1006: }
1007: if (target instanceof EncryptionTarget) {
1008: String temp = encIds.get(uri);
1009: String edAlgo = edAlgos.get(uri);
1010: ((EncryptionTarget) target)
1011: .setDataEncryptionAlgorithm(edAlgo);
1012: if (temp != null) {
1013: uri = temp;
1014: } else {
1015: qname = encQNames.get(uri);
1016: }
1017: }
1018: // look if uri is body
1019: if (uri.equals(bodyWsuId)) {
1020: target.setType(Target.TARGET_TYPE_VALUE_QNAME);
1021: target.setValue("SOAP-BODY");
1022: target.setContentOnly(false);
1023: return;
1024: }
1025: if (uri.equals(payLoadWsuId) || uri.equals(payLoadEncId)) {
1026: target.setType(Target.TARGET_TYPE_VALUE_QNAME);
1027: target.setValue("SOAP-BODY");
1028: target.setContentOnly(true);
1029: return;
1030: }
1031:
1032: // look in non-security headers
1033: if (headers != null && headers.size() > 0) {
1034: Iterator<Header> listItr = headers.listIterator();
1035: while (listItr.hasNext()) {
1036: GenericSecuredHeader header = (GenericSecuredHeader) listItr
1037: .next();
1038: if (header.hasID(uri)) {
1039: qname = new QName(header.getNamespaceURI(), header
1040: .getLocalPart());
1041: target.setQName(qname);
1042: target.setContentOnly(false);
1043: return;
1044: } else if (qname != null) {
1045: target.setQName(qname);
1046: target.setContentOnly(false);
1047: return;
1048: }
1049: }
1050: }
1051: // look in processed headers
1052: for (int j = 0; j < processedHeaders.size(); j++) {
1053: SecurityHeaderElement header = (SecurityHeaderElement) processedHeaders
1054: .get(j);
1055: if (uri.equals(header.getId())) {
1056: qname = new QName(header.getNamespaceURI(), header
1057: .getLocalPart());
1058: target.setQName(qname);
1059: target.setContentOnly(false);
1060: return;
1061: }
1062: }
1063: // look in buffered headers
1064: for (int j = 0; j < bufferedHeaders.size(); j++) {
1065: SecurityHeaderElement header = (SecurityHeaderElement) bufferedHeaders
1066: .get(j);
1067: if (uri.equals(header.getId())) {
1068: qname = new QName(header.getNamespaceURI(), header
1069: .getLocalPart());
1070: target.setQName(qname);
1071: target.setContentOnly(false);
1072: return;
1073: }
1074: }
1075: }
1076:
1077: private void processProcessedHeaders(SecurityHeaderElement she)
1078: throws XWSSecurityException {
1079: if (she instanceof EncryptedData) {
1080: throw new XWSSecurityException(
1081: "Error in Processing, EncryptedData inside procesesdHeaders, should never happen");
1082: } else if (she instanceof EncryptedKey) {
1083: EncryptedKey ek = (EncryptedKey) she;
1084: ArrayList<String> list = (ArrayList) ek
1085: .getPendingReferenceList();
1086: if (list != null && list.size() > 0) {
1087: throw new XWSSecurityException(
1088: "Error in processing, ReferenceList inside EK should have been processed");
1089: }
1090: } else if (she instanceof ReferenceListHeader) {
1091: ReferenceListHeader refList = (ReferenceListHeader) she;
1092: if (refList.getPendingReferenceList() != null
1093: && refList.getPendingReferenceList().size() > 0) {
1094: throw new XWSSecurityException(
1095: "Error in processing, references in ReferenceList not processed");
1096: }
1097: } else if (she instanceof Signature) {
1098: Signature sig = (Signature) she;
1099: if (sig.getReferences() != null
1100: && sig.getReferences().size() > 0) {
1101: throw new XWSSecurityException(
1102: "Error in processing, references in Signature not processed");
1103: }
1104: }
1105: }
1106:
1107: private boolean isPending() throws XWSSecurityException {
1108: for (int i = 0; i < bufferedHeaders.size(); i++) {
1109: SecurityHeaderElement she = (SecurityHeaderElement) bufferedHeaders
1110: .get(i);
1111: if (isPrimary(she)) {
1112: return false;
1113: }
1114: }
1115: return true;
1116: }
1117:
1118: private boolean isPrimary(SecurityHeaderElement she) {
1119: if (she.getLocalPart() == MessageConstants.SIGNATURE_LNAME) {
1120: return true;
1121: } else if (she.getLocalPart() == MessageConstants.ENCRYPTEDKEY_LNAME) {
1122: return true;
1123: } else if (she.getLocalPart() == MessageConstants.XENC_REFERENCE_LIST_LNAME) {
1124: return true;
1125: }
1126: return false;
1127: }
1128:
1129: private void processSecurityHeader(SecurityHeaderElement she)
1130: throws XWSSecurityException {
1131: if (she instanceof Signature) {
1132: handleSignature((Signature) she);
1133: processedHeaders.add(she);
1134: } else if (she instanceof EncryptedData) {
1135: EncryptedData ed = (EncryptedData) she;
1136: XMLStreamReader decryptedData;
1137: try {
1138: decryptedData = ed.getDecryptedData();
1139: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
1140: context, envshNS, staxIF, creator);
1141: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
1142: StreamUtil.moveToNextElement(decryptedData);
1143: SecurityHeaderElement newHeader = shp
1144: .createHeader(decryptedData);
1145: encIds.put(ed.getId(), newHeader.getId());
1146: edAlgos.put(ed.getId(), ed.getEncryptionAlgorithm());
1147: processSecurityHeader(newHeader);
1148: processedHeaders.add(newHeader);
1149: } catch (XMLStreamException ex) {
1150: ex.printStackTrace();
1151: throw new XWSSecurityException(
1152: "Error occurred while decrypting EncryptedData with ID "
1153: + ed.getId(), ex);
1154: }
1155: } else if (she instanceof EncryptedKey) {
1156: EncryptedKey ek = (EncryptedKey) she;
1157: if (pendingElement == null) {
1158: pendingElement = ek;
1159: }
1160: addSecurityHeader(ek);
1161: ArrayList<String> list = (ArrayList) ek
1162: .getPendingReferenceList();
1163: if (list != null) {
1164: findAndReplaceED(list, ek);
1165:
1166: if (ek.getPendingReferenceList().size() > 0
1167: && payLoadWsuId.length() > 0) {
1168: if (ek.getPendingReferenceList().contains(
1169: payLoadWsuId)) {
1170:
1171: EncryptedData ed;
1172: try {
1173: ed = new EncryptedData(message, context,
1174: bodyENVNS);
1175: payLoadWsuId = ed.getId();
1176: handlePayLoadED(ed);
1177: } catch (XMLStreamException ex) {
1178: ex.printStackTrace();
1179: throw new XWSSecurityException(
1180: "Error occurred while parsing EncryptedData"
1181: + ex);
1182: }
1183: ek.getPendingReferenceList().remove(
1184: payLoadWsuId);
1185: }
1186: }
1187: if (ek.getPendingReferenceList().size() != 0) {
1188: throw new XWSSecurityException(
1189: "Data Reference under EncryptedKey with ID "
1190: + ek.getId() + " is not found");
1191: } else {
1192: pendingElement = null;
1193: bufferedHeaders.remove(ek);
1194: addSecurityHeader(ek);
1195: }
1196: }
1197: } else if (she instanceof ReferenceListHeader) {
1198: ReferenceListHeader refList = (ReferenceListHeader) she;
1199: if (refList.getPendingReferenceList()
1200: .contains(payLoadWsuId)) {
1201: try {
1202: EncryptedData ed = new EncryptedData(message,
1203: context, bodyENVNS);
1204:
1205: //for policy verification
1206: refList.getPolicy().setKeyBinding(
1207: ed.getInferredKB());
1208: //
1209: payLoadWsuId = ed.getId();
1210: handlePayLoadED(ed);
1211: refList.getPendingReferenceList().remove(
1212: payLoadWsuId);
1213: cachePayLoadId();
1214: payLoadEncId = ed.getId();
1215: } catch (XMLStreamException ex) {
1216: throw new XWSSecurityException(
1217: "Error occurred while processing EncryptedData",
1218: ex);
1219: }
1220: }
1221: if (refList.getPendingReferenceList().size() > 0) {
1222: findAndReplaceED((ArrayList<String>) refList
1223: .getPendingReferenceList(), refList);
1224: }
1225: if (refList.getPendingReferenceList().size() > 0) {
1226: String uri = refList.getPendingReferenceList().get(0);
1227: throw new XWSSecurityException("Reference with ID "
1228: + uri + " was not found in the message");
1229: }
1230: } else {
1231: throw new XWSSecurityException(
1232: "Need to support this header, please file a bug."
1233: + she);
1234: }
1235: }
1236:
1237: private void handleSignature(Signature sig)
1238: throws XWSSecurityException {
1239: com.sun.xml.ws.security.opt.crypto.dsig.Reference bodyRef = null;
1240: com.sun.xml.ws.security.opt.crypto.dsig.Reference payLoadRef = null;
1241: if (bodyWsuId.length() > 0) {
1242: bodyRef = sig.removeReferenceWithID("#" + bodyWsuId);
1243: }
1244: if (payLoadWsuId.length() > 0) {
1245: payLoadRef = sig.removeReferenceWithID("#" + payLoadWsuId);
1246: }
1247: if (bodyRef != null && payLoadRef != null) {
1248: throw new XWSSecurityException(
1249: "Does not support signing of Body and PayLoad together");
1250: }
1251:
1252: boolean validated = false;
1253: try {
1254: validated = sig.validate();
1255: } catch (XWSSecurityException xe) {
1256: throw new WebServiceException(xe);
1257: }
1258: if (!validated) {
1259: ArrayList<com.sun.xml.ws.security.opt.crypto.dsig.Reference> refs = sig
1260: .getReferences();
1261: if (refs != null && refs.size() > 0) {
1262: throw new WebServiceException(
1263: "Could not find Reference "
1264: + refs.get(0).getURI()
1265: + " under Signature with ID"
1266: + sig.getId());
1267: } else {
1268: throw new XWSSecurityException(
1269: "Verification of Signature with ID "
1270: + sig.getId()
1271: + " failed, possible cause : proper canonicalized"
1272: + "signedinfo was not produced.");
1273: }
1274: } else {
1275: if (bodyRef != null) {
1276: message = sig.wrapWithDigester(bodyRef, message,
1277: bodyTag, parentNS, false);
1278: } else if (payLoadRef != null) {
1279: message = sig.wrapWithDigester(payLoadRef, message,
1280: bodyTag, bodyENVNS, true);
1281: }
1282: }
1283: }
1284:
1285: private void handlePayLoadED(EncryptedData ed)
1286: throws XWSSecurityException, XMLStreamException {
1287: if (pendingElement != null
1288: && pendingElement instanceof EncryptedKey) {
1289: EncryptedKey ek = ((EncryptedKey) pendingElement);
1290: if (ek.getPendingReferenceList().contains(
1291: ((SecurityHeaderElement) ed).getId())) {
1292: //for policy verification
1293: if (ek.getPolicy() != null) {
1294: ek.getPolicy().setKeyBinding(ek.getInferredKB());
1295: }
1296:
1297: message = ed.getDecryptedData(ek.getKey(ed
1298: .getEncryptionAlgorithm()));
1299: payLoadEncId = payLoadWsuId;
1300: if (message != null && message.hasNext()) {
1301: message.next();
1302: }
1303: if (message == null) {
1304: message = getEmptyBody();
1305: }
1306: cachePayLoadId();
1307: ek.getPendingReferenceList().remove(
1308: ((SecurityHeaderElement) ed).getId());
1309: findAndReplaceED((ArrayList<String>) ek
1310: .getPendingReferenceList(), ek);
1311: if (ek.getPendingReferenceList().size() == 0) {
1312: pendingElement = null;
1313: } else {
1314: String uri = ek.getPendingReferenceList().get(0);
1315: throw new XWSSecurityException(
1316: "Could not find Reference " + uri
1317: + " under EncryptedKey with ID"
1318: + ek.getId());
1319: }
1320: }
1321: } else {
1322: message = ed.getDecryptedData();
1323: if (message != null && message.hasNext()) {
1324: message.next();
1325: }
1326: if (message == null) {
1327: message = getEmptyBody();
1328: }
1329: }
1330: edAlgos.put(ed.getId(), ed.getEncryptionAlgorithm());
1331: }
1332:
1333: private void moveToNextElement() throws XMLStreamException {
1334: message.next();
1335: while (message.getEventType() != XMLStreamReader.START_ELEMENT) {
1336: message.next();
1337: }
1338: }
1339:
1340: private boolean isTimeStamp() {
1341: if (message.getLocalName() == MessageConstants.TIMESTAMP_LNAME
1342: && message.getNamespaceURI() == MessageConstants.WSU_NS) {
1343: return true;
1344: }
1345: return false;
1346: }
1347:
1348: private boolean isBST() {
1349: if (message.getLocalName() == MessageConstants.WSSE_BINARY_SECURITY_TOKEN_LNAME
1350: && message.getNamespaceURI() == MessageConstants.WSSE_NS) {
1351: return true;
1352: }
1353: return false;
1354: }
1355:
1356: private boolean isUsernameToken() {
1357: if (message.getLocalName() == MessageConstants.USERNAME_TOKEN_LNAME
1358: && message.getNamespaceURI() == MessageConstants.WSSE_NS) {
1359: return true;
1360: }
1361: return false;
1362: }
1363:
1364: private boolean isSignature() {
1365: if (message.getLocalName() == MessageConstants.SIGNATURE_LNAME
1366: && message.getNamespaceURI() == MessageConstants.DSIG_NS) {
1367: return true;
1368: }
1369: return false;
1370: }
1371:
1372: private boolean isEncryptedKey() {
1373: if (message.getLocalName() == MessageConstants.ENCRYPTEDKEY_LNAME
1374: && message.getNamespaceURI() == MessageConstants.XENC_NS) {
1375: return true;
1376: }
1377: return false;
1378: }
1379:
1380: private boolean isReferenceList() {
1381: if (message.getLocalName() == MessageConstants.XENC_REFERENCE_LIST_LNAME
1382: && message.getNamespaceURI() == MessageConstants.XENC_NS) {
1383: return true;
1384: }
1385: return false;
1386: }
1387:
1388: private boolean isEncryptedData() {
1389: if (message.getLocalName() == MessageConstants.ENCRYPTED_DATA_LNAME
1390: && message.getNamespaceURI() == MessageConstants.XENC_NS) {
1391: return true;
1392: }
1393: return false;
1394: }
1395:
1396: private boolean isDerivedKey() {
1397: if (message.getLocalName() == MessageConstants.DERIVEDKEY_TOKEN_LNAME
1398: && message.getNamespaceURI() == MessageConstants.WSSC_NS) {
1399: return true;
1400: }
1401: return false;
1402: }
1403:
1404: private boolean isSignatureConfirmation() {
1405: if (message.getLocalName() == MessageConstants.SIGNATURE_CONFIRMATION_LNAME
1406: && message.getNamespaceURI() == MessageConstants.WSSE11_NS) {
1407: return true;
1408: }
1409: return false;
1410: }
1411:
1412: private boolean isSCT() {
1413: if (message.getLocalName() == MessageConstants.SECURITY_CONTEXT_TOKEN_LNAME
1414: && message.getNamespaceURI() == MessageConstants.WSSC_NS) {
1415: return true;
1416: }
1417: return false;
1418: }
1419:
1420: private boolean isEncryptedHeader() {
1421: if (message.getLocalName() == MessageConstants.ENCRYPTED_HEADER_LNAME
1422: && message.getNamespaceURI() == MessageConstants.WSSE11_NS) {
1423: return true;
1424: }
1425: return false;
1426: }
1427:
1428: private boolean isSTR() {
1429: if (message.getLocalName() == MessageConstants.WSSE_SECURITY_TOKEN_REFERENCE_LNAME
1430: && message.getNamespaceURI() == MessageConstants.WSSE_NS) {
1431: return true;
1432: }
1433: return false;
1434: }
1435:
1436: private boolean isSAML() {
1437: if (message.getLocalName() == MessageConstants.SAML_ASSERTION_LNAME) {
1438: String uri = message.getNamespaceURI();
1439: if (uri == MessageConstants.SAML_v2_0_NS
1440: || uri == MessageConstants.SAML_v1_0_NS
1441: || uri == MessageConstants.SAML_v1_1_NS) {
1442: return true;
1443: }
1444: }
1445: return false;
1446: }
1447:
1448: private int getSecurityElementType() {
1449: if (message.getEventType() == XMLStreamReader.START_ELEMENT) {
1450: if (isTimeStamp()) {
1451: return TIMESTAMP_ELEMENT;
1452: }
1453:
1454: if (isUsernameToken()) {
1455: return USERNAME_TOKEN_ELEMENT;
1456: }
1457:
1458: if (isBST()) {
1459: return BINARYSECURITY_TOKEN_ELEMENT;
1460: }
1461:
1462: if (isSignature()) {
1463: return SIGNATURE_ELEMENT;
1464: }
1465:
1466: if (isEncryptedKey()) {
1467: return ENCRYPTED_KEY_ELEMENT;
1468: }
1469:
1470: if (isEncryptedData()) {
1471: return ENCRYPTED_DATA_ELEMENT;
1472: }
1473:
1474: if (isEncryptedHeader()) {
1475: return ENCRYPTED_HEADER_ELEMENT;
1476: }
1477:
1478: if (isReferenceList()) {
1479: return REFERENCE_LIST_ELEMENT;
1480: }
1481:
1482: if (isSignatureConfirmation()) {
1483: return SIGNATURE_CONFIRMATION_ELEMENT;
1484: }
1485:
1486: if (isDerivedKey()) {
1487: return this .DERIVED_KEY_ELEMENT;
1488: }
1489:
1490: if (isSCT()) {
1491: return this .SECURITY_CONTEXT_TOKEN;
1492: }
1493:
1494: if (isSAML()) {
1495: return SAML_ASSERTION_ELEMENT;
1496: }
1497:
1498: if (isSTR()) {
1499: return STR_ELEMENT;
1500: }
1501: }
1502: return -1;
1503: }
1504:
1505: private void findAndReplaceED(ArrayList<String> edList,
1506: SecurityHeaderElement ekOrRlh) throws XWSSecurityException {
1507: EncryptedKey ek = null;
1508: ReferenceListHeader rlh = null;
1509: if (ekOrRlh instanceof EncryptedKey)
1510: ek = (EncryptedKey) ekOrRlh;
1511: else if (ekOrRlh instanceof ReferenceListHeader)
1512: rlh = (ReferenceListHeader) ekOrRlh;
1513: else {
1514: // should never happen
1515: return;
1516: }
1517: ArrayList<String> refList = (ArrayList) edList.clone();
1518:
1519: for (int i = 0; i < refList.size(); i++) {
1520: String id = refList.get(i);
1521: boolean found = false;
1522:
1523: Iterator<Header> listItr = headers.listIterator();
1524: while (listItr.hasNext()) {
1525: GenericSecuredHeader header = (GenericSecuredHeader) listItr
1526: .next();
1527: if (header.hasID(id)) {
1528: GenericSecuredHeader processedHeader = processEncryptedSOAPHeader(
1529: header, ekOrRlh);
1530: edList.remove(id);
1531:
1532: int index = headers.indexOf(header);
1533: headers.set(index, processedHeader);
1534: found = true;
1535: break;
1536: }
1537: }
1538: if (found) {
1539: continue;
1540: }
1541: for (int j = 0; j < processedHeaders.size(); j++) {
1542: SecurityHeaderElement header = (SecurityHeaderElement) processedHeaders
1543: .get(j);
1544: if (id.equals(header.getId())) {
1545: if (header instanceof EncryptedData) {
1546: found = true;
1547: throw new XWSSecurityException(
1548: "EncryptedKey or ReferenceList must appear before EncryptedData element with ID"
1549: + header.getId());
1550: }
1551: }
1552: }
1553: if (found) {
1554: continue;
1555: }
1556: for (int j = 0; j < bufferedHeaders.size(); j++) {
1557: SecurityHeaderElement header = (SecurityHeaderElement) bufferedHeaders
1558: .get(j);
1559: if (id.equals(header.getId())) {
1560: if (header instanceof EncryptedData) {
1561: EncryptedData ed = (EncryptedData) header;
1562: XMLStreamReader decryptedData = null;
1563: try {
1564: if (ek != null) {
1565: if (ek.getPolicy() != null) {
1566: //for policy verification
1567: ek.getPolicy().setKeyBinding(
1568: ek.getInferredKB());
1569: }
1570: decryptedData = ed
1571: .getDecryptedData(ek
1572: .getKey(ed
1573: .getEncryptionAlgorithm()));
1574: } else if (rlh != null) {
1575: rlh.getPolicy().setKeyBinding(
1576: ed.getInferredKB());
1577: decryptedData = ed.getDecryptedData();
1578: } else {
1579: throw new XWSSecurityException(
1580: "Internal Error: Both EncryptedKey and ReferenceList are set to null");
1581: }
1582:
1583: SecurityHeaderProcessor shp = new SecurityHeaderProcessor(
1584: context, envshNS, staxIF, creator);
1585: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
1586: StreamUtil
1587: .moveToNextElement(decryptedData);
1588: SecurityHeaderElement she = shp
1589: .createHeader(decryptedData);
1590: edList.remove(ed.getId());
1591: encIds.put(ed.getId(), she.getId());
1592: edAlgos.put(ed.getId(), ed
1593: .getEncryptionAlgorithm());
1594: bufferedHeaders.set(i, she);
1595: } catch (XMLStreamException ex) {
1596: ex.printStackTrace();
1597: throw new XWSSecurityException(
1598: "Error occurred while decrypting EncryptedData with ID "
1599: + ed.getId(), ex);
1600: }
1601: }
1602: }
1603: }
1604: }
1605: }
1606:
1607: private GenericSecuredHeader processEncryptedSOAPHeader(
1608: GenericSecuredHeader header, SecurityHeaderElement ekOrRlh)
1609: throws XWSSecurityException {
1610: EncryptedKey ek = null;
1611: ReferenceListHeader rlh = null;
1612: if (ekOrRlh instanceof EncryptedKey)
1613: ek = (EncryptedKey) ekOrRlh;
1614: else if (ekOrRlh instanceof ReferenceListHeader)
1615: rlh = (ReferenceListHeader) ekOrRlh;
1616:
1617: try {
1618: XMLStreamReader reader = header.readHeader();
1619: if (reader.getEventType() == XMLStreamReader.START_DOCUMENT)
1620: reader.next();
1621: if (reader.getEventType() != XMLStreamReader.START_ELEMENT)
1622: StreamUtil.moveToNextElement(reader);
1623: XMLStreamReader decryptedData = null;
1624: InputStream decryptedIS = null;
1625: EncryptedData ed = null;
1626: EncryptedHeader eh = null;
1627: boolean encContent = false;
1628: EncryptedContentHeaderParser encContentparser = null;
1629: if (MessageConstants.ENCRYPTED_DATA_LNAME.equals(reader
1630: .getLocalName())
1631: && MessageConstants.XENC_NS.equals(reader
1632: .getNamespaceURI())) {
1633: ed = new EncryptedData(reader, context, parentNS);
1634: } else if (MessageConstants.ENCRYPTED_HEADER_LNAME
1635: .equals(reader.getLocalName())
1636: && MessageConstants.WSSE11_NS.equals(reader
1637: .getNamespaceURI())) {
1638: eh = new EncryptedHeader(reader, context, parentNS);
1639: ed = eh.getEncryptedData();
1640: } else if (context.getEncHeaderContent()) {
1641: // the content of header is encrypted
1642: encContent = true;
1643:
1644: encContentparser = new EncryptedContentHeaderParser(
1645: reader, parentNS, context);
1646: ed = encContentparser.getEncryptedData();
1647: } else {
1648: throw new XWSSecurityException(
1649: "Wrong Encrypted SOAP Header");
1650: }
1651:
1652: //for policy verification
1653: if (!encContent) {
1654: if (ek != null) {
1655: if (ek.getPolicy() != null) {
1656: ek.getPolicy()
1657: .setKeyBinding(ek.getInferredKB());
1658: }
1659: decryptedData = ed.getDecryptedData(ek.getKey(ed
1660: .getEncryptionAlgorithm()));
1661: } else if (rlh != null) {
1662: rlh.getPolicy().setKeyBinding(ed.getInferredKB());
1663: decryptedData = ed.getDecryptedData();
1664: } else {
1665: throw new XWSSecurityException(
1666: "Internal Error: Both EncryptedKey and ReferenceList set to null");
1667: }
1668: //
1669:
1670: if (decryptedData.getEventType() == XMLStreamReader.START_DOCUMENT)
1671: decryptedData.next();
1672: if (decryptedData.getEventType() != XMLStreamReader.START_ELEMENT)
1673: StreamUtil.moveToNextElement(decryptedData);
1674: } else {
1675: if (ek != null) {
1676: if (ek.getPolicy() != null) {
1677: ek.getPolicy()
1678: .setKeyBinding(ek.getInferredKB());
1679: }
1680: decryptedIS = ed.getCipherInputStream(ek.getKey(ed
1681: .getEncryptionAlgorithm()));
1682: } else if (rlh != null) {
1683: rlh.getPolicy().setKeyBinding(ed.getInferredKB());
1684: decryptedIS = ed.getCipherInputStream();
1685: }
1686: }
1687:
1688: GenericSecuredHeader gsh = null;
1689: if (!encContent) {
1690: Map<String, String> headerBlockNamespaces = parentNS;
1691: // Collect namespaces on SOAP header block
1692: if (decryptedData.getNamespaceCount() > 0) {
1693: headerBlockNamespaces = new HashMap<String, String>(
1694: parentNS);
1695: for (int k = 0; k < decryptedData
1696: .getNamespaceCount(); k++) {
1697: headerBlockNamespaces.put(decryptedData
1698: .getNamespacePrefix(k), decryptedData
1699: .getNamespaceURI(k));
1700: }
1701: }
1702: // Mark
1703: //XMLStreamBuffer mark = new XMLStreamBufferMark(headerBlockNamespaces, creator);
1704: gsh = new GenericSecuredHeader(decryptedData,
1705: soapVersion, creator,
1706: (HashMap) headerBlockNamespaces, staxIF,
1707: context.getEncHeaderContent());
1708: } else {
1709:
1710: XMLStreamReader decryptedHeader = encContentparser
1711: .getDecryptedElement(decryptedIS);
1712:
1713: if (decryptedHeader.getEventType() == XMLStreamReader.START_DOCUMENT)
1714: decryptedHeader.next();
1715: if (decryptedHeader.getEventType() != XMLStreamReader.START_ELEMENT)
1716: StreamUtil.moveToNextElement(decryptedHeader);
1717: Map<String, String> headerBlockNamespaces = parentNS;
1718: // Collect namespaces on SOAP header block
1719: if (decryptedHeader.getNamespaceCount() > 0) {
1720: headerBlockNamespaces = new HashMap<String, String>(
1721: parentNS);
1722: for (int k = 0; k < decryptedHeader
1723: .getNamespaceCount(); k++) {
1724: String prefix = decryptedHeader
1725: .getNamespacePrefix(k);
1726: if (prefix == null)
1727: prefix = "";
1728: headerBlockNamespaces.put(prefix,
1729: decryptedHeader.getNamespaceURI(k));
1730: }
1731: }
1732: gsh = new GenericSecuredHeader(decryptedHeader,
1733: soapVersion, creator,
1734: (HashMap) headerBlockNamespaces, staxIF,
1735: context.getEncHeaderContent());
1736: }
1737: QName gshQName = new QName(gsh.getNamespaceURI(), gsh
1738: .getLocalPart());
1739: if (eh != null) {
1740: encQNames.put(eh.getId(), gshQName);
1741: edAlgos.put(eh.getId(), ed.getEncryptionAlgorithm());
1742: } else {
1743: encQNames.put(ed.getId(), gshQName);
1744: edAlgos.put(ed.getId(), ed.getEncryptionAlgorithm());
1745: }
1746:
1747: return gsh;
1748: } catch (XMLStreamException ex) {
1749: ex.printStackTrace();
1750: throw new XWSSecurityException(
1751: "Error occurred while decrypting EncryptedData ",
1752: ex);
1753: } catch (XMLStreamBufferException ex) {
1754: throw new XWSSecurityException(
1755: "Error occurred while decrypting EncryptedData", ex);
1756: }
1757: }
1758:
1759: private void addSecurityHeader(SecurityHeaderElement sh) {
1760: if (pendingElement == null || (sh instanceof TokenValidator)) {
1761: processedHeaders.add(sh);
1762: } else {
1763: bufferedHeaders.add(sh);
1764: }
1765: }
1766:
1767: private void cachePayLoadId() {
1768: if (message != null
1769: && message.getEventType() == XMLStreamReader.START_ELEMENT) {
1770: payLoadWsuId = StreamUtil.getWsuId(message);
1771: if (payLoadWsuId == null) {
1772: payLoadWsuId = StreamUtil.getId(message);
1773: }
1774: if (payLoadWsuId == null) {
1775: payLoadWsuId = "";
1776: }
1777: }
1778: }
1779:
1780: private boolean areHeadersSecured(SignaturePolicy sp) {
1781: ArrayList list = ((SignaturePolicy.FeatureBinding) sp
1782: .getFeatureBinding()).getTargetBindings();
1783: List headerList = headers;
1784: for (int hl = 0; hl < headerList.size(); hl++) {
1785: Header hdr = (Header) headerList.get(hl);
1786: String localName = hdr.getLocalPart();
1787: String uri = hdr.getNamespaceURI();
1788: boolean found = false;
1789: if (MessageConstants.ADDRESSING_W3C_NAMESPACE.equals(uri)
1790: || MessageConstants.ADDRESSING_MEMBER_SUBMISSION_NAMESPACE
1791: .equals(uri)) {
1792: for (int i = 0; i < list.size(); i++) {
1793: SignatureTarget st = (SignatureTarget) list.get(i);
1794: QName value = st.getQName();
1795: if (value.getLocalPart().equals(localName)
1796: && value.getNamespaceURI().equals(uri)) {
1797: found = true;
1798: break;
1799: }
1800: }
1801: if (!found) {
1802: return found;
1803: }
1804: }
1805: }
1806: return true;
1807: }
1808:
1809: }
|