0001: /*
0002: * EncryptionProcessor.java
0003: *
0004: * Created on March 17, 2005, 5:22 PM
0005: */
0006:
0007: /*
0008: * The contents of this file are subject to the terms
0009: * of the Common Development and Distribution License
0010: * (the License). You may not use this file except in
0011: * compliance with the License.
0012: *
0013: * You can obtain a copy of the license at
0014: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
0015: * See the License for the specific language governing
0016: * permissions and limitations under the License.
0017: *
0018: * When distributing Covered Code, include this CDDL
0019: * Header Notice in each file and include the License file
0020: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
0021: * If applicable, add the following below the CDDL Header,
0022: * with the fields enclosed by brackets [] replaced by
0023: * you own identifying information:
0024: * "Portions Copyrighted [year] [name of copyright owner]"
0025: *
0026: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
0027: */
0028:
0029: package com.sun.xml.wss.impl.apachecrypto;
0030:
0031: import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey;
0032: import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
0033: import com.sun.org.apache.xml.internal.security.keys.KeyInfo;
0034: import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
0035: import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
0036: import com.sun.xml.wss.core.EncryptedHeaderBlock;
0037: import com.sun.xml.wss.impl.misc.Base64;
0038:
0039: import com.sun.xml.wss.impl.FilterProcessingContext;
0040:
0041: import com.sun.xml.wss.logging.LogDomainConstants;
0042: import com.sun.xml.wss.impl.MessageConstants;
0043: import com.sun.xml.wss.impl.SecurableSoapMessage;
0044: import com.sun.xml.wss.impl.XMLUtil;
0045: import com.sun.xml.wss.XWSSecurityException;
0046: import com.sun.xml.wss.impl.PolicyTypeUtil;
0047: import com.sun.xml.wss.impl.misc.SecurityUtil;
0048:
0049: import com.sun.xml.wss.saml.SAMLException;
0050:
0051: import com.sun.xml.wss.core.DerivedKeyTokenHeaderBlock;
0052: import com.sun.xml.wss.core.EncryptedDataHeaderBlock;
0053: import com.sun.xml.wss.core.KeyInfoHeaderBlock;
0054: import com.sun.xml.wss.core.ReferenceListHeaderBlock;
0055: import com.sun.xml.wss.core.SecurityHeader;
0056: import com.sun.xml.wss.core.SecurityTokenReference;
0057: import com.sun.xml.wss.core.X509SecurityToken;
0058: import com.sun.xml.wss.core.reference.DirectReference;
0059: import com.sun.xml.wss.core.reference.EncryptedKeySHA1Identifier;
0060:
0061: import com.sun.xml.wss.impl.resolver.AttachmentSignatureInput;
0062:
0063: import com.sun.xml.wss.impl.keyinfo.KeyIdentifierStrategy;
0064:
0065: import com.sun.xml.wss.impl.misc.KeyResolver;
0066:
0067: import com.sun.xml.wss.swa.MimeConstants;
0068:
0069: import com.sun.xml.wss.saml.Assertion;
0070:
0071: import java.io.ByteArrayInputStream;
0072: import java.io.ByteArrayOutputStream;
0073: import java.io.InputStream;
0074: import java.io.OutputStream;
0075: import java.security.NoSuchAlgorithmException;
0076: import javax.crypto.Cipher;
0077: import javax.crypto.SecretKey;
0078:
0079: import java.security.Key;
0080: import java.security.PublicKey;
0081: import com.sun.xml.wss.impl.keyinfo.KeyInfoStrategy;
0082: import com.sun.xml.wss.impl.keyinfo.KeyNameStrategy;
0083: import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
0084: import com.sun.xml.wss.impl.policy.mls.EncryptionPolicy;
0085: import com.sun.xml.wss.impl.policy.mls.EncryptionTarget;
0086: import com.sun.xml.wss.impl.policy.mls.SymmetricKeyBinding;
0087: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
0088: import com.sun.xml.wss.impl.policy.mls.DerivedTokenKeyBinding;
0089: import java.security.cert.X509Certificate;
0090: import java.util.ArrayList;
0091: import java.util.HashMap;
0092: import java.util.Iterator;
0093: import java.util.logging.Level;
0094: import java.util.logging.Logger;
0095: import java.security.MessageDigest;
0096:
0097: import javax.xml.soap.SOAPElement;
0098: import javax.xml.soap.SOAPHeader;
0099: import javax.xml.soap.SOAPPart;
0100: import javax.xml.soap.AttachmentPart;
0101: import javax.xml.soap.MimeHeader;
0102: import javax.xml.namespace.QName;
0103:
0104: import org.w3c.dom.Element;
0105: import org.w3c.dom.Node;
0106: import org.w3c.dom.NodeList;
0107:
0108: import com.sun.xml.wss.impl.policy.mls.SecureConversationTokenKeyBinding;
0109: import com.sun.xml.wss.impl.policy.mls.IssuedTokenKeyBinding;
0110: import com.sun.xml.wss.core.SecurityContextTokenImpl;
0111: import com.sun.xml.ws.security.SecurityContextToken;
0112: import com.sun.xml.ws.security.IssuedTokenContext;
0113: import com.sun.xml.wss.impl.AlgorithmSuite;
0114: import com.sun.xml.ws.security.impl.DerivedKeyTokenImpl;
0115: import com.sun.xml.ws.security.DerivedKeyToken;
0116:
0117: import javax.crypto.spec.SecretKeySpec;
0118:
0119: import com.sun.xml.ws.security.trust.GenericToken;
0120:
0121: /**
0122: *
0123: * @author XWSS Security Team
0124: * @author K.Venugopal@sun.com
0125: */
0126:
0127: public class EncryptionProcessor {
0128:
0129: private static byte[] crlf = null;
0130: protected static final Logger log = Logger.getLogger(
0131: LogDomainConstants.IMPL_CRYPTO_DOMAIN,
0132: LogDomainConstants.IMPL_CRYPTO_DOMAIN_BUNDLE);
0133: static {
0134: try {
0135: crlf = "\r\n".getBytes("US-ASCII");
0136: } catch (java.io.UnsupportedEncodingException ue) {
0137: //log;
0138: if (log != null) {
0139: log.log(Level.SEVERE, "WSS1204.crlf.init.failed", ue);
0140: }
0141: }
0142: }
0143:
0144: /** Creates a new instance of EncryptionProcessor */
0145: public EncryptionProcessor() {
0146: }
0147:
0148: public static void encrypt(FilterProcessingContext context)
0149: throws XWSSecurityException {
0150:
0151: //TODO: support for QName and XPath
0152: SecurableSoapMessage secureMsg = context
0153: .getSecurableSoapMessage();
0154: SecurityHeader _secHeader = secureMsg
0155: .findOrCreateSecurityHeader();
0156:
0157: boolean _exportCertificate = false;
0158: SecretKey _symmetricKey = null;
0159: SecretKey keyEncSK = null;
0160:
0161: X509Certificate _x509Cert = null;
0162: KeyInfoStrategy keyInfoStrategy = null;
0163:
0164: String referenceType = null;
0165: String x509TokenId = null;
0166: String keyEncAlgo = XMLCipher.RSA_v1dot5;
0167: String dataEncAlgo = MessageConstants.TRIPLE_DES_BLOCK_ENCRYPTION;
0168: String symmetricKeyName = null;
0169:
0170: AuthenticationTokenPolicy.X509CertificateBinding certificateBinding = null;
0171:
0172: WSSPolicy wssPolicy = (WSSPolicy) context.getSecurityPolicy();
0173: EncryptionPolicy.FeatureBinding featureBinding = (EncryptionPolicy.FeatureBinding) wssPolicy
0174: .getFeatureBinding();
0175: WSSPolicy keyBinding = (WSSPolicy) wssPolicy.getKeyBinding();
0176:
0177: AlgorithmSuite algSuite = context.getAlgorithmSuite();
0178:
0179: SecurityTokenReference samlTokenRef = null;
0180: SecurityTokenReference secConvRef = null;
0181: SecurityTokenReference ekTokenRef = null;
0182: SecurityTokenReference dktSctTokenRef = null;
0183: SecurityTokenReference issuedTokenRef = null;
0184: //adding EncryptedKey Direct Reference to handle EncryptBeforeSigning
0185: SecurityTokenReference ekDirectRef = null;
0186:
0187: DerivedKeyTokenHeaderBlock dktHeadrBlock = null;
0188:
0189: SecurityContextTokenImpl sct = null;
0190: boolean sctTokenInserted = false;
0191: SOAPElement sctElement = null;
0192: boolean sctWithDKT = false;
0193: boolean includeSCT = true;
0194:
0195: boolean issuedWithDKT = false;
0196: SecurityTokenReference dktIssuedTokenRef = null;
0197: SOAPElement issuedTokenElement = null;
0198: Element issuedTokenElementFromMsg = null;
0199: boolean issuedTokenInserted = false;
0200: boolean includeIST = true;
0201:
0202: boolean dktSender = false;
0203:
0204: //Key obtained from SymmetricKeyBinding in case of DKT
0205: Key originalKey = null;
0206: String ekId = context.getSecurableSoapMessage().generateId();
0207: String insertedEkId = null;
0208: //Check to see if same x509 token used for Signature and Encryption
0209: boolean skbX509TokenInserted = false;
0210:
0211: boolean useStandaloneRefList = false;
0212:
0213: HashMap ekCache = context.getEncryptedKeyCache();
0214:
0215: SOAPElement x509TokenElement = null;
0216:
0217: SecurableSoapMessage secureMessage = context
0218: .getSecurableSoapMessage();
0219:
0220: if (log.isLoggable(Level.FINEST)) {
0221: log.log(Level.FINEST, "KeyBinding in Encryption is "
0222: + keyBinding);
0223: }
0224:
0225: boolean wss11Receiver = "true".equals(context
0226: .getExtraneousProperty("EnableWSS11PolicyReceiver"));
0227: boolean wss11Sender = "true".equals(context
0228: .getExtraneousProperty("EnableWSS11PolicySender"));
0229: boolean sendEKSHA1 = wss11Receiver && wss11Sender
0230: && (getEKSHA1Ref(context) != null);
0231: boolean wss10 = !wss11Sender;
0232:
0233: String tmp = featureBinding.getDataEncryptionAlgorithm();
0234: if (tmp == null || "".equals(tmp)) {
0235: if (context.getAlgorithmSuite() != null) {
0236: tmp = context.getAlgorithmSuite()
0237: .getEncryptionAlgorithm();
0238: } else {
0239: // warn that no dataEncAlgo was set
0240: }
0241: }
0242: //TODO :: Change to getDataEncryptionAlgorith,
0243: if (tmp != null && !"".equals(tmp)) {
0244: dataEncAlgo = tmp;
0245: }
0246:
0247: if (context.getAlgorithmSuite() != null) {
0248: keyEncAlgo = context.getAlgorithmSuite()
0249: .getAsymmetricKeyAlgorithm();
0250: }
0251:
0252: // derivedTokenKeyBinding with x509 as originalkeyBinding is to be treated same as
0253: // DerivedKey with Symmetric binding and X509 as key binding of Symmetric binding
0254: if (PolicyTypeUtil.derivedTokenKeyBinding(keyBinding)) {
0255: DerivedTokenKeyBinding dtk = (DerivedTokenKeyBinding) keyBinding
0256: .clone();
0257: WSSPolicy originalKeyBinding = dtk.getOriginalKeyBinding();
0258:
0259: if (PolicyTypeUtil
0260: .x509CertificateBinding(originalKeyBinding)) {
0261: AuthenticationTokenPolicy.X509CertificateBinding ckBindingClone = (AuthenticationTokenPolicy.X509CertificateBinding) originalKeyBinding
0262: .clone();
0263: //create a symmetric key binding and set it as original key binding of dkt
0264: SymmetricKeyBinding skb = new SymmetricKeyBinding();
0265: skb.setKeyBinding(ckBindingClone);
0266: // set the x509 binding as key binding of symmetric binding
0267: dtk.setOriginalKeyBinding(skb);
0268: keyBinding = dtk;
0269: }
0270: }
0271:
0272: if (PolicyTypeUtil.usernameTokenPolicy(keyBinding)) {
0273: log
0274: .log(Level.SEVERE,
0275: "WSS1210.unsupported.UsernameToken.AsKeyBinding.EncryptionPolicy");
0276: throw new XWSSecurityException(
0277: "UsernameToken as KeyBinding for EncryptionPolicy is Not Yet Supported");
0278: } else if (PolicyTypeUtil.x509CertificateBinding(keyBinding)) {
0279: //we need to use standalone reflist to support EncryptBeforeSigning
0280: useStandaloneRefList = true;
0281: if (context.getX509CertificateBinding() != null) {
0282: certificateBinding = context
0283: .getX509CertificateBinding();
0284: context.setX509CertificateBinding(null);
0285: } else {
0286: certificateBinding = (AuthenticationTokenPolicy.X509CertificateBinding) keyBinding;
0287: }
0288:
0289: x509TokenId = certificateBinding.getUUID();
0290: if (x509TokenId == null || x509TokenId.equals("")) {
0291: x509TokenId = secureMsg.generateId();
0292: }
0293: if (log.isLoggable(Level.FINEST)) {
0294: log.log(Level.FINEST, "Certificate was " + _x509Cert);
0295: log.log(Level.FINEST, "BinaryToken ID " + x509TokenId);
0296: }
0297:
0298: HashMap tokenCache = context.getTokenCache();
0299: HashMap insertedX509Cache = context.getInsertedX509Cache();
0300:
0301: SecurityUtil.checkIncludeTokenPolicy(context,
0302: certificateBinding, x509TokenId);
0303:
0304: _x509Cert = certificateBinding.getX509Certificate();
0305: referenceType = certificateBinding.getReferenceType();
0306: if (referenceType.equals("Identifier")
0307: && certificateBinding.getValueType().equals(
0308: MessageConstants.X509v1_NS)) {
0309: log
0310: .log(Level.SEVERE,
0311: "WSS1211.unsupported.KeyIdentifierStrategy.X509v1");
0312: throw new XWSSecurityException(
0313: "Key Identifier strategy with X509v1 certificate is not allowed");
0314: }
0315: keyInfoStrategy = KeyInfoStrategy
0316: .getInstance(referenceType);
0317: _exportCertificate = true;
0318: keyInfoStrategy.setCertificate(_x509Cert);
0319:
0320: if (MessageConstants.DIRECT_REFERENCE_TYPE
0321: .equals(referenceType)) {
0322:
0323: X509SecurityToken token = (X509SecurityToken) tokenCache
0324: .get(x509TokenId);
0325: if (token == null) {
0326: String valueType = certificateBinding
0327: .getValueType();
0328: if (valueType == null || valueType.equals("")) {
0329: //default valueType for X509 as v3
0330: valueType = MessageConstants.X509v3_NS;
0331: }
0332: token = new X509SecurityToken(secureMsg
0333: .getSOAPPart(), _x509Cert, x509TokenId,
0334: valueType);
0335: }
0336: if (insertedX509Cache.get(x509TokenId) == null) {
0337: secureMsg.findOrCreateSecurityHeader()
0338: .insertHeaderBlock(token);
0339: insertedX509Cache.put(x509TokenId, token);
0340: x509TokenElement = secureMsg
0341: .findOrCreateSecurityHeader()
0342: .getNextSiblingOfTimestamp();
0343: } else {
0344: x509TokenElement = secureMsg
0345: .getElementByWsuId(x509TokenId);
0346: }
0347:
0348: //x509TokenElement = secureMsg.findOrCreateSecurityHeader().getFirstChildElement();
0349:
0350: }
0351:
0352: //TODO:Revisit this -Venu
0353: tmp = null;
0354: tmp = certificateBinding.getKeyAlgorithm();
0355: if (tmp != null && !tmp.equals("")) {
0356: keyEncAlgo = tmp;
0357: }
0358: _symmetricKey = SecurityUtil
0359: .generateSymmetricKey(dataEncAlgo);
0360: } else if (PolicyTypeUtil.symmetricKeyBinding(keyBinding)) {
0361: SymmetricKeyBinding skb = null;
0362: if (context.getSymmetricKeyBinding() != null) {
0363: skb = context.getSymmetricKeyBinding();
0364: context.setSymmetricKeyBinding(null);
0365: } else {
0366: skb = (SymmetricKeyBinding) keyBinding;
0367: }
0368:
0369: KeyInfoHeaderBlock keyInfoBlock = null;
0370:
0371: if (!skb.getKeyIdentifier().equals(MessageConstants._EMPTY)) {
0372: keyEncAlgo = skb.getKeyAlgorithm();
0373: if (keyEncAlgo != null && !"".equals(keyEncAlgo)) {
0374: _symmetricKey = SecurityUtil
0375: .generateSymmetricKey(dataEncAlgo);
0376: }
0377: keyInfoStrategy = KeyInfoStrategy
0378: .getInstance(MessageConstants.KEY_NAME_TYPE);
0379: keyEncSK = skb.getSecretKey();
0380: symmetricKeyName = skb.getKeyIdentifier();
0381: String secKeyAlgo = keyEncSK.getAlgorithm();
0382:
0383: if (_symmetricKey == null) {
0384: ((KeyNameStrategy) keyInfoStrategy)
0385: .setKeyName(symmetricKeyName);
0386: _symmetricKey = keyEncSK;
0387: keyEncSK = null;
0388: }
0389: } else if (sendEKSHA1) {
0390: //get the signing key and EKSHA1 reference from the Subject, it was stored from the incoming message
0391: String ekSha1Ref = getEKSHA1Ref(context);
0392: _symmetricKey = skb.getSecretKey();
0393:
0394: keyInfoBlock = new KeyInfoHeaderBlock(secureMessage
0395: .getSOAPPart());
0396: ekTokenRef = new SecurityTokenReference(secureMessage
0397: .getSOAPPart());
0398: EncryptedKeySHA1Identifier refElem = new EncryptedKeySHA1Identifier(
0399: secureMessage.getSOAPPart());
0400: refElem.setReferenceValue(ekSha1Ref);
0401: ekTokenRef.setReference(refElem);
0402: //set the wsse11:TokenType attribute as required by WSS 1.1
0403: //ekTokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
0404:
0405: referenceType = MessageConstants.EK_SHA1_TYPE;
0406: keyInfoStrategy = KeyInfoStrategy
0407: .getInstance(referenceType);
0408: //keyInfoStrategy.insertKey(ekTokenRef, secureMsg);
0409:
0410: //TODO: the below cond is always true.
0411: } else if (wss11Sender || wss10) {
0412: _symmetricKey = skb.getSecretKey();
0413: useStandaloneRefList = true;
0414:
0415: if (!skb.getCertAlias().equals(MessageConstants._EMPTY)) {
0416: certificateBinding = new AuthenticationTokenPolicy.X509CertificateBinding();
0417: //x509Binding.newPrivateKeyBinding();
0418: certificateBinding.setCertificateIdentifier(skb
0419: .getCertAlias());
0420: _x509Cert = context
0421: .getSecurityEnvironment()
0422: .getCertificate(
0423: context.getExtraneousProperties(),
0424: certificateBinding
0425: .getCertificateIdentifier(),
0426: false);
0427: certificateBinding.setX509Certificate(_x509Cert);
0428: certificateBinding.setReferenceType("Direct");
0429: } else if (context.getX509CertificateBinding() != null) {
0430: certificateBinding = context
0431: .getX509CertificateBinding();
0432: context.setX509CertificateBinding(null);
0433: }
0434:
0435: _x509Cert = certificateBinding.getX509Certificate();
0436: x509TokenId = certificateBinding.getUUID();
0437: if (x509TokenId == null || x509TokenId.equals("")) {
0438: x509TokenId = secureMsg.generateId();
0439: }
0440:
0441: if (log.isLoggable(Level.FINEST)) {
0442: log.log(Level.FINEST, "Certificate was "
0443: + _x509Cert);
0444: log.log(Level.FINEST, "BinaryToken ID "
0445: + x509TokenId);
0446: }
0447:
0448: HashMap tokenCache = context.getTokenCache();
0449: HashMap insertedX509Cache = context
0450: .getInsertedX509Cache();
0451:
0452: SecurityUtil.checkIncludeTokenPolicy(context,
0453: certificateBinding, x509TokenId);
0454:
0455: X509SecurityToken token = (X509SecurityToken) tokenCache
0456: .get(x509TokenId);
0457: if (token == null) {
0458: String valueType = certificateBinding
0459: .getValueType();
0460: if (valueType == null || valueType.equals("")) {
0461: //default valueType for X509 as v3
0462: valueType = MessageConstants.X509v3_NS;
0463: }
0464: token = new X509SecurityToken(secureMsg
0465: .getSOAPPart(), _x509Cert, x509TokenId,
0466: valueType);
0467: tokenCache.put(x509TokenId, token);
0468: context.setCurrentSecret(_symmetricKey);
0469: } else {
0470: skbX509TokenInserted = true;
0471: _symmetricKey = context.getCurrentSecret();
0472:
0473: }
0474: ekTokenRef = new SecurityTokenReference(secureMessage
0475: .getSOAPPart());
0476: DirectReference reference = new DirectReference();
0477: insertedEkId = (String) ekCache.get(x509TokenId);
0478: if (insertedEkId == null)
0479: insertedEkId = ekId;
0480: reference.setURI("#" + insertedEkId);
0481: reference
0482: .setValueType(MessageConstants.EncryptedKey_NS);
0483: ekTokenRef.setReference(reference);
0484:
0485: if (!skbX509TokenInserted) {
0486:
0487: referenceType = certificateBinding
0488: .getReferenceType();
0489: if (referenceType.equals("Identifier")
0490: && certificateBinding.getValueType()
0491: .equals(MessageConstants.X509v1_NS)) {
0492: log
0493: .log(Level.SEVERE,
0494: "WSS1211.unsupported.KeyIdentifierStrategy.X509v1");
0495: throw new XWSSecurityException(
0496: "Key Identifier strategy with X509v1 is not allowed");
0497: }
0498: keyInfoStrategy = KeyInfoStrategy
0499: .getInstance(referenceType);
0500: _exportCertificate = true;
0501: keyInfoStrategy.setCertificate(_x509Cert);
0502: //Store SymmetricKey generated in ProcessingContext
0503: context.setExtraneousProperty("SecretKey",
0504: _symmetricKey);
0505: }
0506: if (MessageConstants.DIRECT_REFERENCE_TYPE
0507: .equals(referenceType)) {
0508: if (insertedX509Cache.get(x509TokenId) == null) {
0509: secureMsg.findOrCreateSecurityHeader()
0510: .insertHeaderBlock(token);
0511: insertedX509Cache.put(x509TokenId, token);
0512: x509TokenElement = secureMsg
0513: .findOrCreateSecurityHeader()
0514: .getNextSiblingOfTimestamp();
0515: } else {
0516: //x509TokenElement = secureMsg.findOrCreateSecurityHeader().getFirstChildElement();
0517: x509TokenElement = secureMsg
0518: .getElementByWsuId(x509TokenId);
0519: }
0520: }
0521:
0522: }
0523:
0524: } else if (PolicyTypeUtil.samlTokenPolicy(keyBinding)) {
0525: //TODO handler saml, it should be a remote SAML Assertion
0526: // since a message from the sender cannot have the receivers assertion as part of message
0527: AuthenticationTokenPolicy.SAMLAssertionBinding samlBinding = (AuthenticationTokenPolicy.SAMLAssertionBinding) keyBinding;
0528:
0529: Assertion assertion1 = null;
0530: Assertion assertion2 = null;
0531:
0532: try {
0533: if (System
0534: .getProperty("com.sun.xml.wss.saml.binding.jaxb") == null) {
0535: if (samlBinding.getAssertion().getAttributeNode(
0536: "ID") != null) {
0537: assertion1 = (Assertion) com.sun.xml.wss.saml.assertion.saml20.jaxb20.Assertion
0538: .fromElement(samlBinding.getAssertion());
0539: } else {
0540: assertion1 = (Assertion) com.sun.xml.wss.saml.assertion.saml11.jaxb20.Assertion
0541: .fromElement(samlBinding.getAssertion());
0542: }
0543: } else {
0544: assertion2 = (Assertion) com.sun.xml.wss.saml.assertion.saml11.jaxb10.Assertion
0545: .fromElement(samlBinding.getAssertion());
0546: }
0547: } catch (SAMLException ex) {
0548: log.log(Level.SEVERE,
0549: "WSS1212.error.SAMLAssertionException");
0550: throw new XWSSecurityException(ex);
0551: }
0552:
0553: String assertionID = null;
0554: if (assertion1 != null) {
0555: HashMap tokenCache = context.getTokenCache();
0556: //assuming unique IDs
0557: assertionID = ((com.sun.xml.wss.saml.Assertion) assertion1)
0558: .getAssertionID();
0559: tokenCache.put(assertionID, assertion1);
0560: } else if (assertion2 != null) {
0561: HashMap tokenCache = context.getTokenCache();
0562: //assuming unique IDs
0563: assertionID = ((com.sun.xml.wss.saml.Assertion) assertion2)
0564: .getAssertionID();
0565: tokenCache.put(assertionID, assertion2);
0566: } else {
0567: log.log(Level.SEVERE, "WSS1213.null.SAMLAssertion");
0568: throw new XWSSecurityException("SAML Assertion is NULL");
0569: }
0570:
0571: Key key = null;
0572:
0573: key = KeyResolver.resolveSamlAssertion(context
0574: .getSecurableSoapMessage(), samlBinding
0575: .getAssertion(), true, context, assertionID);
0576:
0577: _x509Cert = context.getSecurityEnvironment()
0578: .getCertificate(context.getExtraneousProperties(),
0579: (PublicKey) key, false);
0580: if (_x509Cert == null) {
0581: log
0582: .log(Level.SEVERE,
0583: "WSS1214.unableto.locate.certificate.SAMLAssertion");
0584: throw new XWSSecurityException(
0585: "Could not locate Certificate corresponding to Key in SubjectConfirmation of SAML Assertion");
0586: }
0587:
0588: if (!"".equals(samlBinding.getKeyAlgorithm())) {
0589: keyEncAlgo = samlBinding.getKeyAlgorithm();
0590: }
0591:
0592: _symmetricKey = SecurityUtil
0593: .generateSymmetricKey(dataEncAlgo);
0594:
0595: referenceType = samlBinding.getReferenceType();
0596: if (referenceType
0597: .equals(MessageConstants.EMBEDDED_REFERENCE_TYPE)) {
0598: log
0599: .log(Level.SEVERE,
0600: "WSS1215.unsupported.EmbeddedReference.SAMLAssertion");
0601: throw new XWSSecurityException(
0602: "Embedded Reference Type for SAML Assertions not supported yet");
0603: }
0604:
0605: String assertionId = null;
0606: if (assertion1 != null) {
0607: assertionId = ((com.sun.xml.wss.saml.Assertion) assertion1)
0608: .getAssertionID();
0609: } else if (assertion2 != null) {
0610: assertionId = ((com.sun.xml.wss.saml.Assertion) assertion2)
0611: .getAssertionID();
0612: }
0613: Element binding = samlBinding.getAuthorityBinding();
0614: samlTokenRef = new SecurityTokenReference(secureMsg
0615: .getSOAPPart());
0616: String strId = samlBinding.getSTRID();
0617: if (strId == null) {
0618: strId = secureMsg.generateId();
0619: }
0620: samlTokenRef.setWsuId(strId);
0621:
0622: if (binding != null) {
0623: samlTokenRef.setSamlAuthorityBinding(binding, secureMsg
0624: .getSOAPPart());
0625: }
0626: keyInfoStrategy = new KeyIdentifierStrategy(assertionId);
0627: keyInfoStrategy.insertKey(samlTokenRef, secureMsg);
0628:
0629: } else if (PolicyTypeUtil.issuedTokenKeyBinding(keyBinding)) {
0630:
0631: IssuedTokenContext trustContext = context.getTrustContext();
0632:
0633: //get the symmetric key for encryption
0634: try {
0635: _symmetricKey = new SecretKeySpec(trustContext
0636: .getProofKey(), SecurityUtil
0637: .getSecretKeyAlgorithm(dataEncAlgo));
0638: } catch (Exception e) {
0639: log.log(Level.SEVERE,
0640: "WSS1216.unableto.get.symmetrickey.Encryption");
0641: throw new XWSSecurityException(e);
0642: }
0643:
0644: //Get the IssuedToken and insert it into the message
0645: GenericToken issuedToken = (GenericToken) trustContext
0646: .getSecurityToken();
0647:
0648: // check if the token is already present
0649: IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding) keyBinding;
0650: //String ikbPolicyId = ikb.getPolicyToken().getTokenId();
0651: String ikbPolicyId = ikb.getUUID();
0652:
0653: //Look for TrustToken in TokenCache
0654: HashMap tokCache = context.getTokenCache();
0655: Object tok = tokCache.get(ikbPolicyId);
0656:
0657: SecurityTokenReference str = null;
0658: Element strElem = null;
0659:
0660: includeIST = (ikb.INCLUDE_ALWAYS_TO_RECIPIENT.equals(ikb
0661: .getIncludeToken()) || ikb.INCLUDE_ALWAYS
0662: .equals(ikb.getIncludeToken()));
0663:
0664: if (includeIST && (issuedToken == null)) {
0665: log.log(Level.SEVERE, "WSS1217.null.IssueToken");
0666: throw new XWSSecurityException(
0667: "Issued Token to be inserted into the Message was Null");
0668: }
0669:
0670: //trust token to be inserted into message
0671: if (issuedToken != null) {
0672: // treat the token as an Opaque entity and just insert the token into message
0673: Element elem = (Element) issuedToken.getTokenValue();
0674: //TODO: remove these expensive conversions DOM Imports
0675: if (tok == null) {
0676: issuedTokenElement = XMLUtil.convertToSoapElement(
0677: secureMessage.getSOAPPart(), elem);
0678: //Temp FIX for Issue#26: We need an Id to cache and MS not sending Id in some cases
0679: String tokId = issuedTokenElement
0680: .getAttribute("Id");
0681: if ("".equals(tokId)
0682: && MessageConstants.ENCRYPTED_DATA_LNAME
0683: .equals(issuedTokenElement
0684: .getLocalName())) {
0685: issuedTokenElement.setAttribute("Id",
0686: secureMessage.generateId());
0687: }
0688: tokCache.put(ikbPolicyId, issuedTokenElement);
0689: } else {
0690: issuedTokenInserted = true;
0691: // it will be SOAPElement retrieve its wsuId attr
0692: String wsuId = SecurityUtil
0693: .getWsuIdOrId((Element) tok);
0694: issuedTokenElementFromMsg = secureMessage
0695: .getElementById(wsuId);
0696: if (issuedTokenElementFromMsg == null) {
0697: log
0698: .log(Level.SEVERE,
0699: "WSS1218.unableto.locate.IssueToken.Message");
0700: throw new XWSSecurityException(
0701: "Could not locate Issued Token in Message");
0702: }
0703: }
0704: }
0705:
0706: if (includeIST) {
0707: if (trustContext.getAttachedSecurityTokenReference() != null) {
0708: strElem = SecurityUtil
0709: .convertSTRToElement(
0710: trustContext
0711: .getAttachedSecurityTokenReference()
0712: .getTokenValue(),
0713: secureMessage.getSOAPPart());
0714: } else {
0715: log
0716: .log(Level.SEVERE,
0717: "WSS1219.unableto.refer.Attached.IssueToken");
0718: throw new XWSSecurityException(
0719: "Cannot determine how to reference the Attached Issued Token in the Message");
0720: }
0721: } else {
0722: //Trust Issued Token should not be in message at all, so use an external reference
0723: if (trustContext.getUnAttachedSecurityTokenReference() != null) {
0724: strElem = SecurityUtil
0725: .convertSTRToElement(
0726: trustContext
0727: .getUnAttachedSecurityTokenReference()
0728: .getTokenValue(),
0729: secureMessage.getSOAPPart());
0730: } else {
0731: log
0732: .log(Level.SEVERE,
0733: "WSS1220.unableto.refer.Un-Attached.IssueToken");
0734: throw new XWSSecurityException(
0735: "Cannot determine how to reference the Un-Attached Issued Token in the Message");
0736: }
0737: }
0738:
0739: //TODO: remove these expensive conversions
0740: Element imported = (Element) secureMessage.getSOAPPart()
0741: .importNode(strElem, true);
0742: issuedTokenRef = new SecurityTokenReference(XMLUtil
0743: .convertToSoapElement(secureMessage.getSOAPPart(),
0744: imported), false);
0745: SecurityUtil.updateSamlVsKeyCache(issuedTokenRef, context,
0746: _symmetricKey);
0747:
0748: } else if (PolicyTypeUtil
0749: .secureConversationTokenKeyBinding(keyBinding)) {
0750:
0751: SecureConversationTokenKeyBinding sctBinding = (SecureConversationTokenKeyBinding) keyBinding;
0752:
0753: //String sctPolicyId = sctBinding.getPolicyToken().getTokenId();
0754: String sctPolicyId = sctBinding.getUUID();
0755: //Look for SCT in TokenCache
0756: HashMap tokCache = context.getTokenCache();
0757: sct = (SecurityContextTokenImpl) tokCache.get(sctPolicyId);
0758:
0759: IssuedTokenContext ictx = context
0760: .getSecureConversationContext();
0761:
0762: if (sct == null) {
0763: SecurityContextToken sct1 = (SecurityContextToken) ictx
0764: .getSecurityToken();
0765: if (sct1 == null) {
0766: log.log(Level.SEVERE,
0767: "WSS1221.null.SecureConversationToken");
0768: throw new XWSSecurityException(
0769: "SecureConversation Token not Found");
0770: }
0771:
0772: sct = new SecurityContextTokenImpl(secureMessage
0773: .getSOAPPart(),
0774: sct1.getIdentifier().toString(), sct1
0775: .getInstance(), sct1.getWsuId(), sct1
0776: .getExtElements());
0777: // put back in token cache
0778: tokCache.put(sctPolicyId, sct);
0779: } else {
0780: sctTokenInserted = true;
0781: // record the element
0782: sctElement = secureMessage.getElementByWsuId(sct
0783: .getWsuId());
0784: }
0785:
0786: String sctWsuId = sct.getWsuId();
0787: if (sctWsuId == null) {
0788: sct.setId(secureMessage.generateId());
0789: }
0790: sctWsuId = sct.getWsuId();
0791:
0792: secConvRef = new SecurityTokenReference(secureMessage
0793: .getSOAPPart());
0794: DirectReference reference = new DirectReference();
0795: if (sctBinding.INCLUDE_ALWAYS_TO_RECIPIENT
0796: .equals(sctBinding.getIncludeToken())
0797: || sctBinding.INCLUDE_ALWAYS.equals(sctBinding
0798: .getIncludeToken())) {
0799:
0800: reference.setURI("#" + sctWsuId);
0801: } else {
0802: includeSCT = false;
0803: reference.setSCTURI(sct.getIdentifier().toString(), sct
0804: .getInstance());
0805: }
0806:
0807: secConvRef.setReference(reference);
0808: referenceType = MessageConstants.DIRECT_REFERENCE_TYPE;
0809: keyInfoStrategy = KeyInfoStrategy
0810: .getInstance(referenceType);
0811:
0812: String jceAlgo = SecurityUtil
0813: .getSecretKeyAlgorithm(dataEncAlgo);
0814: _symmetricKey = new SecretKeySpec(ictx.getProofKey(),
0815: jceAlgo);
0816:
0817: } else if (PolicyTypeUtil.derivedTokenKeyBinding(keyBinding)) {
0818: DerivedTokenKeyBinding dtk = (DerivedTokenKeyBinding) keyBinding
0819: .clone();
0820: WSSPolicy originalKeyBinding = dtk.getOriginalKeyBinding();
0821:
0822: String algorithm = null;
0823: if (algSuite != null) {
0824: algorithm = algSuite.getEncryptionAlgorithm();
0825: }
0826: //The offset and length to be used for DKT
0827: long offset = 0; // Default 0
0828: long length = SecurityUtil
0829: .getLengthFromAlgorithm(algorithm);
0830:
0831: if (PolicyTypeUtil
0832: .x509CertificateBinding(originalKeyBinding)) {
0833: //throw new XWSSecurityException("Asymmetric Binding with DerivedKeys under X509Token Policy Not Yet Supported");
0834: } else if (PolicyTypeUtil
0835: .symmetricKeyBinding(originalKeyBinding)) {
0836: SymmetricKeyBinding skb = null;
0837: if (context.getSymmetricKeyBinding() != null) {
0838: skb = context.getSymmetricKeyBinding();
0839: context.setSymmetricKeyBinding(null);
0840: } else {
0841: skb = (SymmetricKeyBinding) originalKeyBinding;
0842: }
0843:
0844: if (sendEKSHA1) {
0845: String ekSha1Ref = getEKSHA1Ref(context);
0846: //Construct a derivedKeyToken to be used
0847: originalKey = skb.getSecretKey();
0848: byte[] secret = originalKey.getEncoded();
0849: DerivedKeyToken dkt = new DerivedKeyTokenImpl(
0850: offset, length, secret);
0851: String dktId = secureMessage.generateId();
0852: String nonce = Base64.encode(dkt.getNonce());
0853: //get the symmetric key for encryption key from derivedkeyToken
0854: try {
0855: String jceAlgo = SecurityUtil
0856: .getSecretKeyAlgorithm(algorithm);
0857: _symmetricKey = dkt
0858: .generateSymmetricKey(jceAlgo);
0859: } catch (Exception e) {
0860: log
0861: .log(Level.SEVERE,
0862: "WSS1216.unableto.get.symmetrickey.Encryption");
0863: throw new XWSSecurityException(e);
0864: }
0865: //STR for DerivedKeyToken
0866: SecurityTokenReference tokenRef = new SecurityTokenReference(
0867: secureMessage.getSOAPPart());
0868: EncryptedKeySHA1Identifier refElem = new EncryptedKeySHA1Identifier(
0869: secureMessage.getSOAPPart());
0870: refElem.setReferenceValue(ekSha1Ref);
0871: tokenRef.setReference(refElem);
0872:
0873: //set the wsse11:TokenType attribute as required by WSS 1.1
0874: //TODO: uncomment this once MS is ready to accpet this
0875: //tokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
0876:
0877: dktHeadrBlock = new DerivedKeyTokenHeaderBlock(
0878: _secHeader.getOwnerDocument(), tokenRef,
0879: nonce, dkt.getOffset(), dkt.getLength(),
0880: dktId);
0881:
0882: //Construct the STR for Encryption
0883: DirectReference reference = new DirectReference();
0884: reference.setURI("#" + dktId);
0885: ekTokenRef = new SecurityTokenReference(
0886: secureMessage.getSOAPPart());
0887: ekTokenRef.setReference(reference);
0888: } else if (wss11Sender || wss10) {
0889: dktSender = true;
0890: originalKey = skb.getSecretKey();
0891: if (context.getX509CertificateBinding() != null) {
0892: certificateBinding = context
0893: .getX509CertificateBinding();
0894: context.setX509CertificateBinding(null);
0895: _x509Cert = certificateBinding
0896: .getX509Certificate();
0897: }
0898: _x509Cert = certificateBinding.getX509Certificate();
0899: referenceType = certificateBinding
0900: .getReferenceType();
0901: keyInfoStrategy = KeyInfoStrategy
0902: .getInstance(referenceType);
0903: _exportCertificate = true;
0904: keyInfoStrategy.setCertificate(_x509Cert);
0905: x509TokenId = certificateBinding.getUUID();
0906: if (x509TokenId == null || x509TokenId.equals("")) {
0907: x509TokenId = secureMsg.generateId();
0908: }
0909:
0910: if (log.isLoggable(Level.FINEST)) {
0911: log.log(Level.FINEST, "Certificate was "
0912: + _x509Cert);
0913: log.log(Level.FINEST, "BinaryToken ID "
0914: + x509TokenId);
0915: }
0916:
0917: HashMap tokenCache = context.getTokenCache();
0918: HashMap insertedX509Cache = context
0919: .getInsertedX509Cache();
0920:
0921: SecurityUtil.checkIncludeTokenPolicy(context,
0922: certificateBinding, x509TokenId);
0923:
0924: // ReferenceType adjustment in checkIncludeTokenPolicy is also currently
0925: // causing an insertion of the X509 into the Message
0926: X509SecurityToken insertedx509 = (X509SecurityToken) context
0927: .getInsertedX509Cache().get(x509TokenId);
0928:
0929: // this one is used to determine if the whole BST + EK + DKT(opt)
0930: // has been inserted by another filter such as Encryption running before
0931: X509SecurityToken token = (X509SecurityToken) tokenCache
0932: .get(x509TokenId);
0933: if (token == null) {
0934: if (insertedx509 != null) {
0935: token = insertedx509;
0936: tokenCache.put(x509TokenId, insertedx509);
0937: } else {
0938: String valueType = certificateBinding
0939: .getValueType();
0940: if (valueType == null
0941: || valueType.equals("")) {
0942: //default valueType for X509 as v3
0943: valueType = MessageConstants.X509v3_NS;
0944: }
0945: token = new X509SecurityToken(secureMsg
0946: .getSOAPPart(), _x509Cert,
0947: x509TokenId, valueType);
0948: tokenCache.put(x509TokenId, token);
0949: }
0950: context.setCurrentSecret(originalKey);
0951: //Store SymmetricKey generated in ProcessingContext
0952: context.setExtraneousProperty("SecretKey",
0953: originalKey);
0954: } else {
0955: skbX509TokenInserted = true;
0956: originalKey = context.getCurrentSecret();
0957: }
0958: //
0959: if (insertedx509 == null) {
0960: if (MessageConstants.DIRECT_REFERENCE_TYPE
0961: .equals(referenceType)) {
0962: secureMsg.findOrCreateSecurityHeader()
0963: .insertHeaderBlock(token);
0964: insertedX509Cache.put(x509TokenId, token);
0965: x509TokenElement = secureMsg
0966: .findOrCreateSecurityHeader()
0967: .getNextSiblingOfTimestamp();
0968: }
0969: } else {
0970: //x509TokenElement = secureMsg.getElementByWsuId(x509TokenId);
0971: x509TokenElement = insertedx509;
0972: }
0973: //}
0974:
0975: //Construct a derivedKeyToken to be used
0976: byte[] secret = originalKey.getEncoded();
0977: DerivedKeyToken dkt = new DerivedKeyTokenImpl(
0978: offset, length, secret);
0979: String dktId = secureMessage.generateId();
0980: String nonce = Base64.encode(dkt.getNonce());
0981: //get the symmetric key for encryption key from derivedkeyToken
0982: try {
0983: String jceAlgo = SecurityUtil
0984: .getSecretKeyAlgorithm(algorithm);
0985: _symmetricKey = dkt
0986: .generateSymmetricKey(jceAlgo);
0987: } catch (Exception e) {
0988: log
0989: .log(Level.SEVERE,
0990: "WSS1216.unableto.get.symmetrickey.Encryption");
0991: throw new XWSSecurityException(e);
0992: }
0993:
0994: //STR for DerivedKeyToken
0995: SecurityTokenReference tokenRef = new SecurityTokenReference(
0996: secureMessage.getSOAPPart());
0997: DirectReference reference = new DirectReference();
0998: //TODO: PLUGFEST Commeting for now as Microsoft setting the EncryptedKey type on reference valueType
0999: //tokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
1000: //set id of encrypted key in STR of DKT
1001: insertedEkId = (String) ekCache.get(x509TokenId);
1002: if (insertedEkId == null)
1003: insertedEkId = ekId;
1004: reference.setURI("#" + insertedEkId);
1005: reference
1006: .setValueType(MessageConstants.EncryptedKey_NS);
1007: tokenRef.setReference(reference);
1008: dktHeadrBlock = new DerivedKeyTokenHeaderBlock(
1009: _secHeader.getOwnerDocument(), tokenRef,
1010: nonce, dkt.getOffset(), dkt.getLength(),
1011: dktId);
1012:
1013: //Construct the STR for Encryption
1014: DirectReference refEnc = new DirectReference();
1015: refEnc.setURI("#" + dktId);
1016: ekTokenRef = new SecurityTokenReference(
1017: secureMessage.getSOAPPart());
1018: ekTokenRef.setReference(refEnc);
1019: }
1020: } else if (PolicyTypeUtil
1021: .secureConversationTokenKeyBinding(originalKeyBinding)) {
1022:
1023: sctWithDKT = true;
1024:
1025: SecureConversationTokenKeyBinding sctBinding = (SecureConversationTokenKeyBinding) originalKeyBinding;
1026: //String sctPolicyId = sctBinding.getPolicyToken().getTokenId();
1027: String sctPolicyId = sctBinding.getUUID();
1028: //Look for SCT in TokenCache
1029: HashMap tokCache = context.getTokenCache();
1030: sct = (SecurityContextTokenImpl) tokCache
1031: .get(sctPolicyId);
1032:
1033: IssuedTokenContext ictx = context
1034: .getSecureConversationContext();
1035:
1036: if (sct == null) {
1037: SecurityContextToken sct1 = (SecurityContextToken) ictx
1038: .getSecurityToken();
1039: if (sct1 == null) {
1040: log.log(Level.SEVERE,
1041: "WSS1221.null.SecureConversationToken");
1042: throw new XWSSecurityException(
1043: "SecureConversation Token not Found");
1044: }
1045:
1046: sct = new SecurityContextTokenImpl(secureMessage
1047: .getSOAPPart(), sct1.getIdentifier()
1048: .toString(), sct1.getInstance(), sct1
1049: .getWsuId(), sct1.getExtElements());
1050: // put back in token cache
1051: tokCache.put(sctPolicyId, sct);
1052: } else {
1053: sctTokenInserted = true;
1054: // record the element
1055: sctElement = secureMessage.getElementByWsuId(sct
1056: .getWsuId());
1057: }
1058:
1059: String sctWsuId = sct.getWsuId();
1060: if (sctWsuId == null) {
1061: sct.setId(secureMessage.generateId());
1062: }
1063: sctWsuId = sct.getWsuId();
1064:
1065: byte[] secret = context.getSecureConversationContext()
1066: .getProofKey();
1067: DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset,
1068: length, secret);
1069: String dktId = secureMessage.generateId();
1070: String nonce = Base64.encode(dkt.getNonce());
1071: //get the symmetric key for encryption key from derivedkeyToken
1072: try {
1073: _symmetricKey = dkt
1074: .generateSymmetricKey(SecurityUtil
1075: .getSecretKeyAlgorithm(dataEncAlgo));
1076: } catch (Exception e) {
1077: log
1078: .log(Level.SEVERE,
1079: "WSS1216.unableto.get.symmetrickey.Encryption");
1080: throw new XWSSecurityException(e);
1081: }
1082: //STR for DerivedKeyToken
1083: SecurityTokenReference secRef = new SecurityTokenReference(
1084: secureMessage.getSOAPPart());
1085: DirectReference reference = new DirectReference();
1086: if (sctBinding.INCLUDE_ALWAYS_TO_RECIPIENT
1087: .equals(sctBinding.getIncludeToken())
1088: || sctBinding.INCLUDE_ALWAYS.equals(sctBinding
1089: .getIncludeToken())) {
1090:
1091: reference.setURI("#" + sctWsuId);
1092: } else {
1093: includeSCT = false;
1094: reference.setSCTURI(sct.getIdentifier().toString(),
1095: sct.getInstance());
1096: }
1097: secRef.setReference(reference);
1098: dktHeadrBlock = new DerivedKeyTokenHeaderBlock(
1099: _secHeader.getOwnerDocument(), secRef, nonce,
1100: dkt.getOffset(), dkt.getLength(), dktId);
1101:
1102: //Construct the STR for Encryption
1103: DirectReference refEnc = new DirectReference();
1104: refEnc.setURI("#" + dktId);
1105: dktSctTokenRef = new SecurityTokenReference(
1106: secureMessage.getSOAPPart());
1107: dktSctTokenRef.setReference(refEnc);
1108:
1109: } else if (PolicyTypeUtil
1110: .issuedTokenKeyBinding(originalKeyBinding)) {
1111:
1112: issuedWithDKT = true;
1113:
1114: IssuedTokenContext trustContext = context
1115: .getTrustContext();
1116: DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset,
1117: length, trustContext.getProofKey());
1118: String dktId = secureMessage.generateId();
1119: String nonce = Base64.encode(dkt.getNonce());
1120:
1121: //get the symmetric key for encryption
1122: Key origKey = null;
1123: try {
1124: origKey = new SecretKeySpec(trustContext
1125: .getProofKey(), SecurityUtil
1126: .getSecretKeyAlgorithm(dataEncAlgo));
1127: } catch (Exception e) {
1128: log
1129: .log(Level.SEVERE,
1130: "WSS1216.unableto.get.symmetrickey.Encryption");
1131: throw new XWSSecurityException(e);
1132: }
1133:
1134: //get the symmetric key for encryption key from derivedkeyToken
1135: try {
1136: _symmetricKey = dkt
1137: .generateSymmetricKey(SecurityUtil
1138: .getSecretKeyAlgorithm(dataEncAlgo));
1139: } catch (Exception e) {
1140: log
1141: .log(Level.SEVERE,
1142: "WSS1216.unableto.get.symmetrickey.Encryption");
1143: throw new XWSSecurityException(e);
1144: }
1145:
1146: //Get the IssuedToken and insert it into the message
1147: GenericToken issuedToken = (GenericToken) trustContext
1148: .getSecurityToken();
1149:
1150: // check if the token is already present
1151: IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding) originalKeyBinding;
1152: //String ikbPolicyId = ikb.getPolicyToken().getTokenId();
1153: String ikbPolicyId = ikb.getUUID();
1154: //Look for TrustToken in TokenCache
1155: HashMap tokCache = context.getTokenCache();
1156: Object tok = tokCache.get(ikbPolicyId);
1157:
1158: SecurityTokenReference str = null;
1159: Element strElem = null;
1160:
1161: includeIST = (ikb.INCLUDE_ALWAYS_TO_RECIPIENT
1162: .equals(ikb.getIncludeToken()) || ikb.INCLUDE_ALWAYS
1163: .equals(ikb.getIncludeToken()));
1164:
1165: if (includeIST && (issuedToken == null)) {
1166: log.log(Level.SEVERE, "WSS1217.null.IssueToken");
1167: throw new XWSSecurityException(
1168: "Issued Token to be inserted into the Message was Null");
1169: }
1170:
1171: if (issuedToken != null) {
1172: // treat the token as an Opaque entity and just insert the token into message
1173: Element elem = (Element) issuedToken
1174: .getTokenValue();
1175: //TODO: remove these expensive conversions DOM Imports
1176: if (tok == null) {
1177: issuedTokenElement = XMLUtil
1178: .convertToSoapElement(secureMessage
1179: .getSOAPPart(), elem);
1180: //Temp FIX for Issue#26: We need an Id to cache and MS not sending Id in some cases
1181: String tokId = issuedTokenElement
1182: .getAttribute("Id");
1183: if ("".equals(tokId)
1184: && MessageConstants.ENCRYPTED_DATA_LNAME
1185: .equals(issuedTokenElement
1186: .getLocalName())) {
1187: issuedTokenElement.setAttribute("Id",
1188: secureMessage.generateId());
1189: }
1190: tokCache.put(ikbPolicyId, issuedTokenElement);
1191: } else {
1192: issuedTokenInserted = true;
1193: // it will be SOAPElement retrieve its wsuId attr
1194: String wsuId = SecurityUtil
1195: .getWsuIdOrId((Element) tok);
1196: issuedTokenElementFromMsg = secureMessage
1197: .getElementById(wsuId);
1198: if (issuedTokenElementFromMsg == null) {
1199: log
1200: .log(Level.SEVERE,
1201: "WSS1218.unableto.locate.IssueToken.Message");
1202: throw new XWSSecurityException(
1203: "Could not locate Issued Token in Message");
1204: }
1205: }
1206: }
1207:
1208: if (includeIST) {
1209: if (trustContext
1210: .getAttachedSecurityTokenReference() != null) {
1211: strElem = (Element) trustContext
1212: .getAttachedSecurityTokenReference()
1213: .getTokenValue();
1214: } else {
1215: log
1216: .log(Level.SEVERE,
1217: "WSS1219.unableto.refer.Attached.IssueToken");
1218: throw new XWSSecurityException(
1219: "Cannot determine how to reference the Attached Issued Token in the Message");
1220: }
1221: } else {
1222: //Trust Issued Token should not be in message at all, so use an external reference
1223: if (trustContext
1224: .getUnAttachedSecurityTokenReference() != null) {
1225: strElem = (Element) trustContext
1226: .getUnAttachedSecurityTokenReference()
1227: .getTokenValue();
1228: } else {
1229: log
1230: .log(Level.SEVERE,
1231: "WSS1220.unableto.refer.Un-Attached.IssueToken");
1232: throw new XWSSecurityException(
1233: "Cannot determine how to reference the Un-Attached Issued Token in the Message");
1234: }
1235: }
1236:
1237: //TODO: remove these expensive conversions
1238: Element imported = (Element) secureMessage
1239: .getSOAPPart().importNode(strElem, true);
1240: str = new SecurityTokenReference(XMLUtil
1241: .convertToSoapElement(secureMessage
1242: .getSOAPPart(), (Element) imported
1243: .cloneNode(true)), false);
1244:
1245: if (origKey != null) {
1246: SecurityUtil.updateSamlVsKeyCache(str, context,
1247: origKey);
1248: }
1249:
1250: dktHeadrBlock = new DerivedKeyTokenHeaderBlock(
1251: _secHeader.getOwnerDocument(), str, nonce, dkt
1252: .getOffset(), dkt.getLength(), dktId);
1253: //Construct the STR for Encryption
1254: DirectReference refEnc = new DirectReference();
1255: refEnc.setURI("#" + dktId);
1256: dktIssuedTokenRef = new SecurityTokenReference(
1257: secureMessage.getSOAPPart());
1258: dktIssuedTokenRef.setReference(refEnc);
1259:
1260: }
1261: } else {
1262: log.log(Level.SEVERE,
1263: "WSS1222.unsupported.KeyBinding.EncryptionPolicy");
1264: throw new XWSSecurityException(
1265: "Unsupported Key Binding for EncryptionPolicy");
1266: }
1267:
1268: XMLCipher _keyEncryptor = null;
1269: XMLCipher _dataEncryptor = null;
1270: Cipher _attachmentEncryptor = null;
1271: Cipher _dataCipher = null;
1272: try {
1273: // lazy n static instantiation can happen
1274: //TODO :: Algorithms -- Venu
1275: if (log.isLoggable(Level.FINEST)) {
1276: log.log(Level.FINEST, "KeyEncryption algorithm is "
1277: + keyEncAlgo);
1278: }
1279:
1280: if (_x509Cert != null) {
1281: //prepare for keytransport
1282: _keyEncryptor = XMLCipher.getInstance(keyEncAlgo);
1283: _keyEncryptor.init(XMLCipher.WRAP_MODE, _x509Cert
1284: .getPublicKey());
1285: } else if (keyEncSK != null) {
1286: //prepare for keywrap
1287: _keyEncryptor = XMLCipher.getInstance(keyEncAlgo);
1288: _keyEncryptor.init(XMLCipher.WRAP_MODE, keyEncSK);
1289: }
1290:
1291: if (log.isLoggable(Level.FINEST)) {
1292: log.log(Level.FINEST, "Data encryption algorithm is "
1293: + dataEncAlgo);
1294: }
1295:
1296: String dataAlgorithm = JCEMapper
1297: .translateURItoJCEID(dataEncAlgo);
1298: _dataCipher = Cipher.getInstance(dataAlgorithm);
1299: _dataEncryptor = XMLCipher.getInstance(dataEncAlgo,
1300: _dataCipher);
1301: _dataCipher.init(XMLCipher.ENCRYPT_MODE, _symmetricKey);
1302: _dataEncryptor.init(XMLCipher.ENCRYPT_MODE, _symmetricKey);
1303:
1304: } catch (Exception xee) {
1305: log.log(Level.SEVERE,
1306: "WSS1205.unableto.initialize.xml.cipher", xee);
1307: throw new XWSSecurityException(
1308: "Unable to initialize XML Cipher", xee);
1309: }
1310:
1311: ArrayList targets = featureBinding.getTargetBindings();
1312:
1313: ArrayList _aparts = new ArrayList();
1314: ArrayList _dnodes = new ArrayList();
1315:
1316: Iterator i = targets.iterator();
1317: //TODO : remove all the three while loops and
1318: //convert to a 2 loop - Venu
1319: while (i.hasNext()) {
1320: EncryptionTarget target = (EncryptionTarget) i.next();
1321: boolean contentOnly = target.getContentOnly();
1322: Boolean cOnly = Boolean.valueOf(contentOnly);
1323: if (target.getValue() == MessageConstants.PROCESS_ALL_ATTACHMENTS) {
1324: Iterator itr = secureMsg.getAttachments();
1325: while (itr.hasNext()) {
1326: AttachmentPart ap = (AttachmentPart) itr.next();
1327: Object[] s = new Object[2];
1328: s[0] = ap;
1329: s[1] = cOnly;
1330: _aparts.add(s);
1331: }
1332: continue;
1333: }
1334: Object mgpart = secureMsg.getMessageParts(target);
1335: //Change this to context.
1336: //TODO :: Venu
1337: ArrayList transforms = target
1338: .getCipherReferenceTransforms();
1339: if (mgpart == null) {
1340: continue;
1341: } else if (mgpart instanceof AttachmentPart) {
1342: Object[] s = new Object[2];
1343: s[0] = mgpart;
1344: s[1] = cOnly;
1345: _aparts.add(s);
1346: } else {
1347: if (mgpart instanceof Node) {
1348: Object[] s = new Object[2];
1349: s[0] = mgpart;
1350: s[1] = cOnly;
1351: _dnodes.add(s);
1352: } else if (mgpart instanceof NodeList) {
1353: for (int j = 0; j < ((NodeList) mgpart).getLength(); j++) {
1354: Object[] s = new Object[2];
1355: Node n = ((NodeList) mgpart).item(j);
1356: s[0] = n;
1357: s[1] = cOnly;
1358: _dnodes.add(s);
1359: }
1360: }
1361: }
1362: }
1363:
1364: if (_dnodes.isEmpty() && _aparts.isEmpty()) {
1365: if (log.isLoggable(Level.WARNING)) {
1366: log
1367: .log(Level.WARNING,
1368: "None of the specified Encryption Parts found in the Message");
1369: }
1370: }
1371:
1372: EncryptedKey _encryptedKey = null;
1373: ReferenceListHeaderBlock _ekReferenceList = null;
1374: ReferenceListHeaderBlock _standaloneReferenceList = null;
1375:
1376: if (_keyEncryptor != null && !skbX509TokenInserted) {
1377: try {
1378: if (!dktSender) {
1379: _encryptedKey = _keyEncryptor.encryptKey(secureMsg
1380: .getSOAPPart(), _symmetricKey);
1381: } else {
1382: _encryptedKey = _keyEncryptor.encryptKey(secureMsg
1383: .getSOAPPart(), originalKey);
1384: }
1385: _encryptedKey.setId(ekId);
1386: ekCache.put(x509TokenId, ekId);
1387: KeyInfoHeaderBlock keyInfoBlock = new KeyInfoHeaderBlock(
1388: secureMsg.getSOAPPart());
1389:
1390: if (samlTokenRef != null) {
1391: keyInfoBlock
1392: .addSecurityTokenReference(samlTokenRef);
1393: } else if (_x509Cert != null) {
1394: keyInfoStrategy.insertKey(keyInfoBlock, secureMsg,
1395: x509TokenId);
1396: } else if (keyEncSK != null) {
1397: //keyInfoStrategy.insertKey(keyInfoBlock, secureMsg,null);
1398: keyInfoBlock.addKeyName(symmetricKeyName);
1399: }
1400: KeyInfo keyInfo = keyInfoBlock.getKeyInfo(); /*new KeyInfo(keyInfoBlock.getAsSoapElement(), null); */
1401: _encryptedKey.setKeyInfo(keyInfo);
1402:
1403: } catch (Exception xe) {
1404: log
1405: .log(
1406: Level.SEVERE,
1407: "WSS1223.unableto.set.KeyInfo.EncryptedKey",
1408: xe);
1409: //xe.printStackTrace();
1410: throw new XWSSecurityException(xe);
1411: }
1412: }
1413:
1414: if (_encryptedKey != null && !dktSender
1415: && !useStandaloneRefList) {
1416: _ekReferenceList = new ReferenceListHeaderBlock(secureMsg
1417: .getSOAPPart());
1418: }
1419: // process APs - push only EDs (create EDs), modify AP headers/content
1420:
1421: //When encrypting content and attachments with the same key process attachments first.
1422: //SWA Spec.
1423: SOAPElement x509Sibling = null;
1424:
1425: if (x509TokenElement != null) {
1426: x509Sibling = (SOAPElement) x509TokenElement
1427: .getNextSibling();
1428: }
1429: Iterator _apartsI = _aparts.iterator();
1430: if (_apartsI.hasNext()) {
1431: //We have attachments so get the cipher instances.
1432: try {
1433: //_attachmentEncryptor = Cipher.getInstance("DESede/CBC/ISO10126Padding");
1434: //TODO:GETMAP -venu
1435: String dataAlgorithm = JCEMapper
1436: .translateURItoJCEID(dataEncAlgo);
1437: _attachmentEncryptor = Cipher
1438: .getInstance(dataAlgorithm);
1439: _attachmentEncryptor.init(Cipher.ENCRYPT_MODE,
1440: _symmetricKey);
1441: } catch (Exception xee) {
1442: log.log(Level.SEVERE,
1443: "WSS1205.unableto.initialize.xml.cipher", xee);
1444: throw new XWSSecurityException(
1445: "Unable to initialize XML Cipher", xee);
1446: }
1447: }
1448: while (_apartsI.hasNext()) {
1449: Object[] s = (Object[]) _apartsI.next();
1450: AttachmentPart p = (AttachmentPart) s[0];
1451: boolean b = ((Boolean) s[1]).booleanValue();
1452:
1453: // create n push an ED
1454:
1455: EncryptedDataHeaderBlock edhb = new EncryptedDataHeaderBlock();
1456:
1457: String id = secureMsg.generateId();
1458:
1459: edhb.setId(id);
1460: edhb
1461: .setType((b ? MessageConstants.ATTACHMENT_CONTENT_ONLY_URI
1462: : MessageConstants.ATTACHMENT_COMPLETE_URI));
1463: edhb.setMimeType(p.getContentType());
1464:
1465: String uri = p.getContentId();
1466: if (uri != null) {
1467: if (uri.charAt(0) == '<'
1468: && uri.charAt(uri.length() - 1) == '>') {
1469: uri = "cid:" + uri.substring(1, uri.length() - 1);
1470: } else {
1471: uri = "cid:" + uri;
1472: }
1473: } else {
1474: uri = p.getContentLocation();
1475: }
1476:
1477: edhb.getCipherReference(true, uri);
1478: edhb.setEncryptionMethod(dataEncAlgo);
1479: edhb
1480: .addTransform(MessageConstants.ATTACHMENT_CONTENT_ONLY_TRANSFORM_URI);
1481:
1482: encryptAttachment(p, b, _attachmentEncryptor);
1483:
1484: if (_ekReferenceList != null) {
1485: _ekReferenceList.addReference("#" + id);
1486: }
1487: if (x509Sibling == null && x509TokenElement == null) {
1488: _secHeader.insertHeaderBlock(edhb);
1489: } else {
1490: if (x509Sibling != null) {
1491: _secHeader.insertBefore(edhb, x509Sibling);
1492: } else {
1493: _secHeader.appendChild(edhb);
1494: }
1495: }
1496: }
1497: int optType = -1;
1498: Iterator _dnodeI = _dnodes.iterator();
1499: while (_dnodeI.hasNext()) {
1500: Object[] s = (Object[]) _dnodeI.next();
1501: Node n = (Node) s[0];
1502: boolean b = ((Boolean) s[1]).booleanValue();
1503: //TODO :Add Transforms here.
1504: Element ed = null;
1505: boolean _fi = false;
1506: if (context.getConfigType() == MessageConstants.SIGN_ENCRYPT_BODY) {
1507: if (_fi) {
1508: ed = encryptBodyContent(secureMsg, context
1509: .getCanonicalizedData(), _dataEncryptor);
1510: } else {
1511: signEncrypt(context, _dataCipher, _ekReferenceList,
1512: _standaloneReferenceList, keyInfoStrategy,
1513: dataEncAlgo);
1514: continue;
1515: }
1516: } else {
1517: if (n.getNodeType() == Node.TEXT_NODE) {
1518: ed = encryptElement(secureMsg, (SOAPElement) n
1519: .getParentNode(), true, _dataEncryptor);
1520: } else {
1521: ed = encryptElement(secureMsg, (SOAPElement) n, b,
1522: _dataEncryptor);
1523: }
1524: }
1525: EncryptedHeaderBlock ehb = null;
1526: boolean isEhb = false;
1527: EncryptedDataHeaderBlock xencEncryptedData = new EncryptedDataHeaderBlock(
1528: XMLUtil.convertToSoapElement(secureMsg
1529: .getSOAPPart(), ed));
1530:
1531: String xencEncryptedDataId = secureMsg.generateId();
1532: String xencEncryptedDataRef = "#" + xencEncryptedDataId;
1533: if (ed.getParentNode() instanceof SOAPHeader && wss11Sender) {
1534: isEhb = true;
1535: ehb = new EncryptedHeaderBlock(secureMsg.getSOAPPart());
1536: ehb.setId(xencEncryptedDataId);
1537: ehb.copyAttributes(secureMsg, _secHeader);
1538: } else {
1539: xencEncryptedData.setId(xencEncryptedDataId);
1540: }
1541:
1542: if (_ekReferenceList != null) {
1543: _ekReferenceList.addReference(xencEncryptedDataRef);
1544: } else {
1545: if (_standaloneReferenceList == null) {
1546: _standaloneReferenceList = new ReferenceListHeaderBlock(
1547: secureMsg.getSOAPPart());
1548: }
1549: _standaloneReferenceList
1550: .addReference(xencEncryptedDataRef);
1551:
1552: KeyInfoHeaderBlock keyInfoBlock = new KeyInfoHeaderBlock(
1553: secureMsg.getSOAPPart());
1554: SecurityTokenReference cloned = null;
1555: if (dktSctTokenRef != null) {
1556: cloned = new SecurityTokenReference(
1557: (SOAPElement) dktSctTokenRef
1558: .cloneNode(true));
1559: keyInfoBlock.addSecurityTokenReference(cloned);
1560: } else if (secConvRef != null) {
1561: cloned = new SecurityTokenReference(
1562: (SOAPElement) secConvRef.cloneNode(true));
1563: keyInfoBlock.addSecurityTokenReference(cloned);
1564: } else if (ekTokenRef != null) {
1565: cloned = new SecurityTokenReference(
1566: (SOAPElement) ekTokenRef.cloneNode(true));
1567: keyInfoBlock.addSecurityTokenReference(cloned);
1568: } else if (dktIssuedTokenRef != null) {
1569: cloned = new SecurityTokenReference(
1570: (SOAPElement) dktIssuedTokenRef
1571: .cloneNode(true));
1572: keyInfoBlock.addSecurityTokenReference(cloned);
1573: } else if (issuedTokenRef != null) {
1574: cloned = new SecurityTokenReference(
1575: (SOAPElement) issuedTokenRef
1576: .cloneNode(true));
1577: keyInfoBlock.addSecurityTokenReference(cloned);
1578: } else {
1579:
1580: if (PolicyTypeUtil
1581: .x509CertificateBinding(keyBinding)) {
1582: //to handle EncryptBeforeSigning we split EK and RefList even in this case
1583: DirectReference dRef = new DirectReference();
1584: dRef.setURI("#" + ekId);
1585: ekDirectRef = new SecurityTokenReference(
1586: secureMessage.getSOAPPart());
1587: ekDirectRef.setReference(dRef);
1588: keyInfoBlock
1589: .addSecurityTokenReference(ekDirectRef);
1590:
1591: } else {
1592: // this is the default KeyName case
1593: keyInfoStrategy.insertKey(keyInfoBlock,
1594: secureMsg, null);
1595: }
1596:
1597: }
1598: xencEncryptedData.setKeyInfo(keyInfoBlock);
1599: }
1600:
1601: if (isEhb) {
1602: try {
1603: ed.getParentNode().replaceChild(
1604: ehb.getAsSoapElement(), ed);
1605: ehb.addChildElement(xencEncryptedData
1606: .getAsSoapElement());
1607: } catch (Exception se) {
1608: se.printStackTrace();
1609: }
1610: } else {
1611: ed.getParentNode().replaceChild(
1612: xencEncryptedData.getAsSoapElement(), ed);
1613: }
1614: }
1615:
1616: try {
1617: x509Sibling = null;
1618:
1619: if (x509TokenElement != null) {
1620: x509Sibling = (SOAPElement) x509TokenElement
1621: .getNextSibling();
1622: }
1623:
1624: if (_encryptedKey != null) {
1625: SOAPElement se = (SOAPElement) _keyEncryptor
1626: .martial(_encryptedKey);
1627: se = _secHeader.makeUsable(se);
1628: if (_ekReferenceList != null)
1629: se.appendChild(_ekReferenceList.getAsSoapElement());
1630:
1631: //store EKSHA1 of KeyValue contents in context
1632: Element cipherData = (Element) se.getChildElements(
1633: new QName(MessageConstants.XENC_NS,
1634: "CipherData",
1635: MessageConstants.XENC_PREFIX)).next();
1636: String cipherValue = cipherData.getElementsByTagNameNS(
1637: MessageConstants.XENC_NS, "CipherValue")
1638: .item(0).getTextContent();
1639: byte[] decodedCipher = Base64.decode(cipherValue);
1640: byte[] ekSha1 = MessageDigest.getInstance("SHA-1")
1641: .digest(decodedCipher);
1642: String encEkSha1 = Base64.encode(ekSha1);
1643: context.setExtraneousProperty("EncryptedKeySHA1",
1644: encEkSha1);
1645:
1646: if (x509Sibling == null) {
1647: if (x509TokenElement == null) {
1648: _secHeader.insertHeaderBlockElement(se);
1649: } else {
1650: _secHeader.appendChild(se);
1651: }
1652: } else {
1653: _secHeader.insertBefore(se, x509Sibling);
1654: }
1655: //For SymmetricBinding with X509 case and for Asym with E before S
1656: if (_standaloneReferenceList != null) {
1657: _secHeader.insertBefore(_standaloneReferenceList,
1658: se.getNextSibling());
1659: context
1660: .setCurrentReferenceList(se
1661: .getNextSibling());
1662: }
1663: } else {
1664: if (_standaloneReferenceList != null) {
1665: // if SCT or IssuedToken is not already in message then do what we did before WSIT
1666: if ((sctElement == null)
1667: && (issuedTokenElementFromMsg == null)) {
1668: if (insertedEkId != null) {
1669: //insert the standalone reflist under EK
1670: Element ekElem = secureMessage
1671: .getElementById(insertedEkId);
1672: _secHeader.insertBefore(
1673: _standaloneReferenceList, ekElem
1674: .getNextSibling());
1675:
1676: } else {
1677: _secHeader
1678: .insertHeaderBlock(_standaloneReferenceList);
1679: context
1680: .setCurrentReferenceList(_standaloneReferenceList
1681: .getAsSoapElement());
1682: }
1683: } else {
1684: // insert standalone reflist under the SCT/Issued Token
1685: if (sctElement != null) {
1686: _secHeader.insertBefore(
1687: _standaloneReferenceList,
1688: sctElement.getNextSibling());
1689: } else if (issuedTokenElementFromMsg != null) {
1690: _secHeader.insertBefore(
1691: _standaloneReferenceList,
1692: issuedTokenElementFromMsg
1693: .getNextSibling());
1694: } else {
1695: _secHeader
1696: .insertHeaderBlock(_standaloneReferenceList);
1697: context
1698: .setCurrentReferenceList(_standaloneReferenceList
1699: .getAsSoapElement());
1700: }
1701: }
1702: }
1703: }
1704:
1705: if (sctWithDKT || issuedWithDKT) {
1706: // SCT or IssuedToken not in message so insert it above the DKT in SecHeader
1707: if (sctElement == null && (sct != null)) {
1708: _secHeader.insertHeaderBlock(dktHeadrBlock);
1709: if (includeSCT) {
1710: _secHeader.insertHeaderBlock(sct);
1711: }
1712: } else if (issuedTokenElementFromMsg == null
1713: && (issuedTokenElement != null)) {
1714: _secHeader.insertHeaderBlock(dktHeadrBlock);
1715: if (includeIST) {
1716: _secHeader
1717: .insertHeaderBlockElement(issuedTokenElement);
1718: }
1719: // also store the token in Packet.invocationProperties to be used by
1720: // client side response processing
1721: context.setIssuedSAMLToken(issuedTokenElement);
1722: } else {
1723: // if the token is already in Message then insert DKT below it.
1724: if (sctElement != null) {
1725: _secHeader.insertBefore(dktHeadrBlock,
1726: sctElement.getNextSibling());
1727: } else if (issuedTokenElementFromMsg != null) {
1728: _secHeader.insertBefore(dktHeadrBlock,
1729: issuedTokenElementFromMsg
1730: .getNextSibling());
1731: } else {
1732: _secHeader.insertHeaderBlock(dktHeadrBlock);
1733: }
1734: }
1735: } else {
1736: //Insert DKT here
1737: // insert the derivedKey into SecurityHeader
1738: if (dktHeadrBlock != null) {
1739: if (insertedEkId != null) { //If DKT referes to EK
1740: Element ekElem = secureMessage
1741: .getElementById(insertedEkId);
1742: _secHeader.insertBefore(dktHeadrBlock, ekElem
1743: .getNextSibling());
1744: } else {
1745: _secHeader.insertHeaderBlock(dktHeadrBlock);
1746: }
1747: }
1748: // insert the SecurityContextToken if any in the Non DKT path
1749: if (!sctTokenInserted && (sct != null) && includeSCT) {
1750: _secHeader.insertHeaderBlock(sct);
1751: }
1752:
1753: // insert trust token if any in the Non DKT path
1754: if (!issuedTokenInserted
1755: && (issuedTokenElement != null) && includeIST) {
1756: _secHeader
1757: .insertHeaderBlockElement(issuedTokenElement);
1758: // also store the token in Packet.invocationProperties to be used by
1759: // client side response processing
1760: context.setIssuedSAMLToken(issuedTokenElement);
1761: }
1762: }
1763:
1764: } catch (Base64DecodingException e) {
1765: log
1766: .log(
1767: Level.SEVERE,
1768: "WSS1224.error.insertion.HeaderBlock.SecurityHeader",
1769: e);
1770: throw new XWSSecurityException(e);
1771: } catch (NoSuchAlgorithmException e) {
1772: log
1773: .log(
1774: Level.SEVERE,
1775: "WSS1224.error.insertion.HeaderBlock.SecurityHeader",
1776: e);
1777: throw new XWSSecurityException(e);
1778: }
1779:
1780: }
1781:
1782: //Handle encryption of elememnt and element content
1783:
1784: private static Element encryptElement(
1785: SecurableSoapMessage secureMsg, SOAPElement encryptElm,
1786: boolean contentOnly, XMLCipher xmlCipher)
1787: throws XWSSecurityException {
1788:
1789: String localName = encryptElm.getLocalName();
1790:
1791: // BSP: 5607
1792: if (!contentOnly
1793: && (MessageConstants.SOAP_1_1_NS
1794: .equalsIgnoreCase(encryptElm.getNamespaceURI()) || MessageConstants.SOAP_1_2_NS
1795: .equalsIgnoreCase(encryptElm.getNamespaceURI()))
1796: && ("Header".equalsIgnoreCase(localName)
1797: || "Envelope".equalsIgnoreCase(localName) || "Body"
1798: .equalsIgnoreCase(localName))) {
1799: log.log(Level.SEVERE, "WSS1206.illegal.target", encryptElm
1800: .getElementName().getQualifiedName());
1801: throw new XWSSecurityException("Encryption of SOAP "
1802: + localName + " is not allowed"); // BSP 5607
1803: }
1804:
1805: SOAPPart soapPart = secureMsg.getSOAPPart();
1806:
1807: // Get the relative location of the element we are working on
1808: Node refNode = null;
1809: Node contextNode;
1810: if (contentOnly) {
1811: contextNode = encryptElm;
1812: } else {
1813: contextNode = encryptElm.getParentNode();
1814: refNode = encryptElm.getNextSibling();
1815: }
1816:
1817: try {
1818: xmlCipher.doFinal(soapPart, encryptElm, contentOnly);
1819: } catch (Exception e) {
1820: log.log(Level.SEVERE, "WSS1207.unableto.encrypt.message");
1821: throw new XWSSecurityException("Unable to encrypt element",
1822: e);
1823: }
1824:
1825: Element xencEncryptedData;
1826: if (contentOnly) {
1827: xencEncryptedData = (Element) contextNode.getFirstChild();
1828: } else {
1829: if (refNode == null) {
1830: xencEncryptedData = (Element) contextNode
1831: .getLastChild();
1832: } else {
1833: xencEncryptedData = (Element) refNode
1834: .getPreviousSibling();
1835: }
1836: }
1837:
1838: return xencEncryptedData;
1839: }
1840:
1841: private static Element encryptBodyContent(
1842: SecurableSoapMessage contextNode, byte[] canonData,
1843: XMLCipher xmlCipher) throws XWSSecurityException {
1844: throw new UnsupportedOperationException(
1845: "Old optimizations disabled in WSIT");
1846: // try{
1847: // EncryptedData ed = xmlCipher.encryptData((Document)contextNode.getSOAPPart(),canonData,true);
1848: // Element encryptedBodyContent = xmlCipher.martial(ed);
1849: // SOAPBody body =
1850: // ((com.sun.xml.messaging.saaj.soap.ExpressMessage)contextNode.getSOAPMessage()).getEMBody();
1851: // body.appendChild(encryptedBodyContent);
1852: // return encryptedBodyContent;
1853: // }catch(Exception e){
1854: // log.log(Level.SEVERE, "WSS1207.unableto.encrypt.message");
1855: // throw new XWSSecurityException("Unable to encrypt element", e);
1856: // }
1857: }
1858:
1859: private static void signEncrypt(FilterProcessingContext fpc,
1860: Cipher cipher, ReferenceListHeaderBlock _ekReferenceList,
1861: ReferenceListHeaderBlock _standaloneReferenceList,
1862: KeyInfoStrategy keyInfoStrategy, String encAlgo)
1863: throws XWSSecurityException {
1864: throw new UnsupportedOperationException("Not supported in WSIT");
1865: // try{
1866: // byte[] canonData = fpc.getCanonicalizedData();
1867: // byte[] cipherOutput = cipher.doFinal(canonData);
1868: // byte[] iv = cipher.getIV();
1869: // EncryptedDataImpl ed = new EncryptedDataImpl();
1870: //
1871: // ed.setEncryptedData(cipherOutput);
1872: // ed.setIv(iv);
1873: //
1874: // ed.setEncAlgo(encAlgo);
1875: // String xencEncryptedDataId = fpc.getSecurableSoapMessage().generateId();
1876: // String xencEncryptedDataRef = "#" + xencEncryptedDataId;
1877: // ed.setId(xencEncryptedDataId);
1878: // if (_ekReferenceList != null){
1879: // _ekReferenceList.addReference(xencEncryptedDataRef);
1880: // }else {
1881: // if (_standaloneReferenceList == null){
1882: // _standaloneReferenceList = new ReferenceListHeaderBlock(fpc.getSecurableSoapMessage().getSOAPPart());
1883: // }
1884: // _standaloneReferenceList.addReference(xencEncryptedDataRef);
1885: //
1886: // KeyInfoHeaderBlock keyInfoBlock = new KeyInfoHeaderBlock(fpc.getSecurableSoapMessage().getSOAPPart());
1887: // keyInfoStrategy.insertKey(keyInfoBlock, fpc.getSecurableSoapMessage(), null);
1888: // ed.setKeyInfo(keyInfoBlock);
1889: // }
1890: //
1891: // SOAPMessage msg = fpc.getSOAPMessage();
1892: // com.sun.xml.jaxws.JAXWSMessage jxm = ((com.sun.xml.messaging.saaj.soap.ExpressMessage)msg).getJAXWSMessage();
1893: // ed.setXMLSerializer(jxm.getXmlSerializer());
1894: // jxm.setEncryptedBody(ed);
1895: // }catch(Exception e){
1896: // log.log(Level.SEVERE, "WSS1207.unableto.encrypt.message");
1897: // throw new XWSSecurityException("Unable to encrypt element", e);
1898: // }
1899: }
1900:
1901: //Start of Attachment code.
1902: private static void encryptAttachment(AttachmentPart part,
1903: boolean contentOnly, Cipher cipher)
1904: throws XWSSecurityException {
1905: try {
1906: byte[] cipherInput = null;
1907:
1908: if (contentOnly) {
1909: ByteArrayOutputStream baos = new ByteArrayOutputStream();
1910: part.getDataHandler().writeTo(baos);
1911: cipherInput = ((ByteArrayOutputStream) baos)
1912: .toByteArray();
1913: } else {
1914: Object[] obj = AttachmentSignatureInput
1915: ._getSignatureInput(part);
1916:
1917: byte[] headers = serializeHeaders((java.util.Vector) obj[0]);
1918: byte[] content = (byte[]) obj[1];
1919:
1920: cipherInput = new byte[headers.length + content.length];
1921:
1922: System.arraycopy(headers, 0, cipherInput, 0,
1923: headers.length);
1924: System.arraycopy(content, 0, cipherInput,
1925: headers.length, content.length);
1926: }
1927:
1928: byte[] cipherOutput = cipher.doFinal(cipherInput);
1929:
1930: byte[] iv = cipher.getIV();
1931: byte[] encryptedBytes = new byte[iv.length
1932: + cipherOutput.length];
1933:
1934: System.arraycopy(iv, 0, encryptedBytes, 0, iv.length);
1935: System.arraycopy(cipherOutput, 0, encryptedBytes,
1936: iv.length, cipherOutput.length);
1937:
1938: int cLength = encryptedBytes.length;
1939: String cType = MimeConstants.APPLICATION_OCTET_STREAM_TYPE;
1940: String uri = part.getContentId();
1941: //Step 9 and 10.SWA spec.
1942: if (!contentOnly) {
1943: part.removeAllMimeHeaders();
1944: }
1945:
1946: if (uri != null) {
1947: part.setMimeHeader(MimeConstants.CONTENT_ID, uri);
1948: } else {
1949: uri = part.getContentLocation();
1950: if (uri != null) {
1951: part.setMimeHeader(MimeConstants.CONTENT_LOCATION,
1952: uri);
1953: }
1954: }
1955: part.setContentType(cType);
1956: part.setMimeHeader(MimeConstants.CONTENT_LENGTH, Integer
1957: .toString(cLength));
1958: part.setMimeHeader("Content-Transfer-Encoding", "base64");
1959:
1960: EncryptedAttachmentDataHandler dh = new EncryptedAttachmentDataHandler(
1961: new EncryptedAttachmentDataSource(encryptedBytes));
1962: part.setDataHandler(dh);
1963:
1964: } catch (Exception e) {
1965: log.log(Level.SEVERE,
1966: "WSS1225.error.encrypting.Attachment", e);
1967: throw new XWSSecurityException(e);
1968: }
1969: }
1970:
1971: private static String getEKSHA1Ref(FilterProcessingContext context) {
1972: String ekSha1Ref = null;
1973: ekSha1Ref = (String) context
1974: .getExtraneousProperty(MessageConstants.EK_SHA1_VALUE);
1975: return ekSha1Ref;
1976: }
1977:
1978: private static byte[] serializeHeaders(java.util.Vector mimeHeaders)
1979: throws XWSSecurityException {
1980: ByteArrayOutputStream baos = new ByteArrayOutputStream();
1981:
1982: try {
1983: for (int i = 0; i < mimeHeaders.size(); i++) {
1984: MimeHeader mh = (MimeHeader) mimeHeaders.elementAt(i);
1985:
1986: String name = mh.getName();
1987: String vlue = mh.getValue();
1988:
1989: String line = name + ":" + vlue + "\r\n";
1990:
1991: byte[] b = line.getBytes("US-ASCII");
1992: baos.write(b, 0, b.length);
1993: }
1994:
1995: baos.write(crlf, 0, crlf.length);
1996: } catch (Exception e) {
1997: log.log(Level.SEVERE, "WSS1226.error.serialize.headers", e);
1998: throw new XWSSecurityException(e);
1999: }
2000:
2001: return baos.toByteArray();
2002: }
2003:
2004: private static class EncryptedAttachmentDataSource implements
2005: javax.activation.DataSource {
2006: byte[] datasource;
2007:
2008: EncryptedAttachmentDataSource(byte[] ds) {
2009: datasource = ds;
2010: }
2011:
2012: public String getContentType() {
2013: return MimeConstants.APPLICATION_OCTET_STREAM_TYPE;
2014: }
2015:
2016: public InputStream getInputStream() throws java.io.IOException {
2017: return new ByteArrayInputStream(datasource);
2018: }
2019:
2020: public String getName() {
2021: return "Encrypted Attachment DataSource";
2022: }
2023:
2024: public OutputStream getOutputStream()
2025: throws java.io.IOException {
2026: ByteArrayOutputStream baos = new ByteArrayOutputStream();
2027: baos.write(datasource, 0, datasource.length);
2028: return baos;
2029: }
2030: }
2031:
2032: private static class EncryptedAttachmentDataHandler extends
2033: javax.activation.DataHandler {
2034:
2035: EncryptedAttachmentDataHandler(javax.activation.DataSource ds) {
2036: super (ds);
2037: }
2038:
2039: public void writeTo(OutputStream os) throws java.io.IOException {
2040: ((ByteArrayOutputStream) getDataSource().getOutputStream())
2041: .writeTo(os);
2042: }
2043: }
2044:
2045: //End of Attachment code.
2046: }
|