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: /*
0024: * DecryptionProcessor.java
0025: *
0026: * Created on March 18, 2005, 3:31 PM
0027: */
0028:
0029: package com.sun.xml.wss.impl.apachecrypto;
0030:
0031: import com.sun.xml.wss.impl.misc.Base64;
0032: import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey;
0033: import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
0034: import com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException;
0035: import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
0036: import com.sun.xml.wss.impl.FilterProcessingContext;
0037: import com.sun.xml.wss.impl.PolicyTypeUtil;
0038: import com.sun.xml.wss.impl.policy.SecurityPolicy;
0039: import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
0040: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
0041: import com.sun.xml.wss.impl.policy.verifier.EncryptionPolicyVerifier;
0042: import com.sun.xml.wss.logging.LogDomainConstants;
0043: import com.sun.xml.wss.impl.MessageConstants;
0044: import com.sun.xml.wss.impl.PolicyViolationException;
0045: import com.sun.xml.wss.impl.SecurableSoapMessage;
0046: import com.sun.xml.wss.impl.policy.mls.Target;
0047: import com.sun.xml.wss.impl.WssSoapFaultException;
0048: import com.sun.xml.wss.impl.XMLUtil;
0049: import com.sun.xml.wss.XWSSecurityException;
0050: import com.sun.xml.wss.core.EncryptedDataHeaderBlock;
0051: import com.sun.xml.wss.core.EncryptedKeyHeaderBlock;
0052: import com.sun.xml.wss.core.KeyInfoHeaderBlock;
0053: import com.sun.xml.wss.core.ReferenceListHeaderBlock;
0054: import com.sun.xml.wss.core.SecurityHeader;
0055: import com.sun.xml.wss.impl.policy.mls.MessagePolicy;
0056: import com.sun.xml.wss.impl.dsig.AttachmentData;
0057: import com.sun.xml.wss.impl.misc.KeyResolver;
0058: import com.sun.xml.wss.impl.policy.mls.EncryptionPolicy;
0059:
0060: import com.sun.xml.wss.impl.policy.mls.EncryptionTarget;
0061: import com.sun.xml.wss.swa.MimeConstants;
0062: import java.io.ByteArrayInputStream;
0063: import java.io.ByteArrayOutputStream;
0064: import java.io.InputStream;
0065: import java.security.Key;
0066: import java.util.logging.Level;
0067: import java.util.logging.Logger;
0068: import javax.xml.soap.SOAPElement;
0069: import javax.xml.soap.SOAPFactory;
0070: import java.security.MessageDigest;
0071: import java.util.ArrayList;
0072: import java.util.Enumeration;
0073: import java.util.HashSet;
0074: import java.util.Iterator;
0075: import java.util.List;
0076: import java.util.Set;
0077: import javax.crypto.Cipher;
0078: import javax.crypto.SecretKey;
0079: import javax.crypto.spec.IvParameterSpec;
0080: import javax.mail.Header;
0081: import javax.mail.internet.MimeBodyPart;
0082: import javax.xml.namespace.QName;
0083: import javax.xml.soap.AttachmentPart;
0084: import javax.xml.soap.MimeHeader;
0085: import javax.xml.transform.TransformerException;
0086: import org.w3c.dom.DOMException;
0087: import org.w3c.dom.Document;
0088: import org.w3c.dom.Element;
0089: import org.w3c.dom.Node;
0090: import org.w3c.dom.NodeList;
0091:
0092: /**
0093: * @author Kumar Jayanti
0094: * @author Anil Tappetla
0095: * @author Vishal Mahajan
0096: * @author K.Venugopal@sun.com
0097: */
0098:
0099: public class DecryptionProcessor {
0100: protected static final Logger log = Logger.getLogger(
0101: LogDomainConstants.IMPL_CRYPTO_DOMAIN,
0102: LogDomainConstants.IMPL_CRYPTO_DOMAIN_BUNDLE);
0103:
0104: /** Creates a new instance of DecryptionProcessor */
0105: public DecryptionProcessor() {
0106: }
0107:
0108: public static void decrypt(FilterProcessingContext context)
0109: throws XWSSecurityException {
0110: SecurableSoapMessage secureMessage = context
0111: .getSecurableSoapMessage();
0112: SecurityHeader wsseSecurity = secureMessage
0113: .findSecurityHeader();
0114: SOAPElement headerElement = wsseSecurity
0115: .getCurrentHeaderElement();
0116:
0117: String localName = headerElement.getLocalName();
0118: if (log.isLoggable(Level.FINEST)) {
0119: log.log(Level.FINEST,
0120: "EncryptionProcessor:decrypt : LocalName is "
0121: + localName);
0122: }
0123: if (localName == null) {
0124: context.setPVE(new PolicyViolationException(
0125: "Expected one of EncryptedKey,EncryptedData,ReferenceList as per receiver"
0126: + "requirements, found none"));
0127: context.isPrimaryPolicyViolation(true);
0128: return;
0129: }
0130: EncryptionPolicy inferredPolicy = null;
0131: if (context.getMode() == FilterProcessingContext.ADHOC
0132: || context.getMode() == FilterProcessingContext.POSTHOC) {
0133: inferredPolicy = new EncryptionPolicy();
0134: context.setInferredPolicy(inferredPolicy);
0135: } /*else if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0136: inferredPolicy = new EncryptionPolicy();
0137: context.getInferredSecurityPolicy().append(inferredPolicy);
0138: }*/
0139:
0140: SecretKey key = null;
0141: if (MessageConstants.ENCRYPTED_DATA_LNAME.equals(localName)) {
0142: processEncryptedData(headerElement, key, context);
0143: } else if (MessageConstants.XENC_ENCRYPTED_KEY_LNAME
0144: .equals(localName)) {
0145: if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0146: inferredPolicy = new EncryptionPolicy();
0147: context.getInferredSecurityPolicy().append(
0148: inferredPolicy);
0149: }
0150: processEncryptedKey(context, headerElement);
0151: } else if (MessageConstants.XENC_REFERENCE_LIST_LNAME
0152: .equals(localName)) {
0153: if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0154: inferredPolicy = new EncryptionPolicy();
0155: context.getInferredSecurityPolicy().append(
0156: inferredPolicy);
0157: }
0158: decryptReferenceList(headerElement, key, null, context);
0159: } else {
0160: context.setPVE(new PolicyViolationException(
0161: "Expected one of EncryptedKey,EncryptedData,ReferenceList as per receiver"
0162: + "requirements, found " + localName));
0163: context.isPrimaryPolicyViolation(true);
0164: return;
0165: }
0166:
0167: if (context.getMode() == FilterProcessingContext.ADHOC) {
0168: new EncryptionPolicyVerifier(context).verifyPolicy(context
0169: .getSecurityPolicy(), context.getInferredPolicy());
0170: }
0171:
0172: }
0173:
0174: public static void processEncryptedKey(
0175: FilterProcessingContext context,
0176: SOAPElement xencEncryptedKey) throws XWSSecurityException {
0177: boolean isBSP = false;
0178: //EncryptionPolicy.FeatureBinding featureBinding = null;
0179: try {
0180: xencEncryptedKey.normalize();
0181:
0182: //For storing EKSHA1 in Subject
0183: Element cipherData = (Element) xencEncryptedKey
0184: .getChildElements(
0185: new QName(MessageConstants.XENC_NS,
0186: "CipherData",
0187: MessageConstants.XENC_PREFIX))
0188: .next();
0189: String cipherValue = cipherData.getElementsByTagNameNS(
0190: MessageConstants.XENC_NS, "CipherValue").item(0)
0191: .getTextContent();
0192: byte[] decodedCipher = Base64.decode(cipherValue);
0193: byte[] ekSha1 = MessageDigest.getInstance("SHA-1").digest(
0194: decodedCipher);
0195: String encEkSha1 = Base64.encode(ekSha1);
0196: context.setExtraneousProperty(
0197: MessageConstants.EK_SHA1_VALUE, encEkSha1);
0198:
0199: EncryptedKeyHeaderBlock encKeyHB = new EncryptedKeyHeaderBlock(
0200: xencEncryptedKey);
0201: String encryptionAlgorithm = encKeyHB
0202: .getEncryptionMethodURI();
0203: SecurityPolicy securityPolicy = context.getSecurityPolicy();
0204:
0205: if (securityPolicy != null
0206: && PolicyTypeUtil.encryptionPolicy(securityPolicy)) {
0207: isBSP = ((EncryptionPolicy) securityPolicy).isBSP();
0208: //featureBinding = (EncryptionPolicy.FeatureBinding )((EncryptionPolicy)securityPolicy).getFeatureBinding();
0209: }
0210:
0211: //TODO: not sure what is happening here, was this introduced by manveen
0212: EncryptionPolicy infPolicy = null;
0213:
0214: if (context.getMode() != FilterProcessingContext.DEFAULT) {
0215: infPolicy = (EncryptionPolicy) context
0216: .getInferredPolicy();
0217:
0218: }
0219: // if(infPolicy != null){
0220: // featureBinding = (EncryptionPolicy.FeatureBinding )infPolicy.getFeatureBinding();
0221: // }
0222:
0223: if (isBSP) {
0224: if (!(MessageConstants.RSA_15_KEY_TRANSPORT
0225: .equals(encryptionAlgorithm)
0226: || MessageConstants.RSA_OAEP_KEY_TRANSPORT
0227: .equals(encryptionAlgorithm)
0228: || MessageConstants.TRIPLE_DES_KEY_WRAP
0229: .equals(encryptionAlgorithm)
0230: || MessageConstants.AES_KEY_WRAP_128
0231: .equals(encryptionAlgorithm) || MessageConstants.AES_KEY_WRAP_256
0232: .equals(encryptionAlgorithm))) {
0233: log.log(Level.SEVERE,
0234: "WSS1227.keyEncryptionAlg.Violation");
0235: throw new XWSSecurityException(
0236: "Violation of BSP5621. KeyEncryption algorithm"
0237: + "MUST be one of #rsa-1_5,#rsa-oaep-mgf1p,#kw-tripledes,#kw-aes256,#kw-aes128");
0238: }
0239: }
0240:
0241: XMLCipher xmlCipher = XMLCipher
0242: .getInstance(encryptionAlgorithm);
0243: EncryptedKey encryptedKey = xmlCipher
0244: .loadEncryptedKey(xencEncryptedKey);
0245:
0246: KeyInfoHeaderBlock keyInfo = new KeyInfoHeaderBlock(
0247: encryptedKey.getKeyInfo());
0248: SOAPElement refListSoapElement = null;
0249: String commonDataEncAlgo = null;
0250:
0251: refListSoapElement = (SOAPElement) xencEncryptedKey
0252: .getChildElements(
0253: SOAPFactory
0254: .newInstance()
0255: .createName(
0256: MessageConstants.XENC_REFERENCE_LIST_LNAME,
0257: MessageConstants.XENC_PREFIX,
0258: MessageConstants.XENC_NS))
0259: .next();
0260: commonDataEncAlgo = getDataEncryptionAlgorithm(refListSoapElement);
0261: //TODO :: Move this away into Policy.
0262: if (isBSP) {
0263: if (!(MessageConstants.TRIPLE_DES_BLOCK_ENCRYPTION
0264: .equalsIgnoreCase(commonDataEncAlgo)
0265: || MessageConstants.AES_BLOCK_ENCRYPTION_128
0266: .equalsIgnoreCase(commonDataEncAlgo) || MessageConstants.AES_BLOCK_ENCRYPTION_256
0267: .equalsIgnoreCase(commonDataEncAlgo))) {
0268: log.log(Level.SEVERE,
0269: "WSS1228.DataEncryptionAlg.Violation");
0270: throw new XWSSecurityException(
0271: "Violation of BSP5620 for DataEncryption Algo permitted values");
0272: }
0273: }
0274:
0275: Key key = KeyResolver.getKey(keyInfo, false, context);
0276: xmlCipher.init(XMLCipher.UNWRAP_MODE, key);
0277: if (infPolicy != null) {
0278: WSSPolicy keyBinding = (WSSPolicy) infPolicy
0279: .getKeyBinding();
0280:
0281: if (PolicyTypeUtil.x509CertificateBinding(keyBinding)) {
0282: ((AuthenticationTokenPolicy.X509CertificateBinding) keyBinding)
0283: .setKeyAlgorithm(encryptionAlgorithm);
0284: } else if (PolicyTypeUtil.samlTokenPolicy(keyBinding)) {
0285: ((AuthenticationTokenPolicy.SAMLAssertionBinding) keyBinding)
0286: .setKeyAlgorithm(encryptionAlgorithm);
0287: }
0288: }
0289: XMLCipher dataCipher = null;
0290: SecretKey symmetricKey;
0291:
0292: try {
0293: symmetricKey = (SecretKey) xmlCipher.decryptKey(
0294: encryptedKey, commonDataEncAlgo);
0295: dataCipher = initXMLCipher(symmetricKey,
0296: commonDataEncAlgo);
0297: } catch (XMLEncryptionException xmlee) {
0298: log.log(Level.SEVERE, "WSS1200.error.decrypting.key");
0299: throw SecurableSoapMessage.newSOAPFaultException(
0300: MessageConstants.WSSE_FAILED_CHECK,
0301: "Decryption of key encryption key failed",
0302: xmlee);
0303: }
0304: //Store the SecretKey in context, for EKSHA1 support
0305: context.setExtraneousProperty(
0306: MessageConstants.SECRET_KEY_VALUE, symmetricKey);
0307: if (refListSoapElement != null)
0308: decryptReferenceList(refListSoapElement, symmetricKey,
0309: dataCipher, context);
0310:
0311: } catch (WssSoapFaultException wssSfe) {
0312: log.log(Level.SEVERE,
0313: "WSS1229.Error.Processing.EncrpytedKey");
0314: throw wssSfe;
0315: } catch (Exception e) {
0316: log.log(Level.SEVERE,
0317: "WSS1229.Error.Processing.EncrpytedKey");
0318: throw new XWSSecurityException(e);
0319: }
0320: }
0321:
0322: private static void decryptReferenceList(
0323: SOAPElement refListSoapElement, SecretKey key,
0324: XMLCipher dataCipher, FilterProcessingContext context)
0325: throws XWSSecurityException {
0326:
0327: SecurableSoapMessage secureMessage = context
0328: .getSecurableSoapMessage();
0329: ReferenceListHeaderBlock refList = new ReferenceListHeaderBlock(
0330: refListSoapElement);
0331:
0332: NodeList dataRefElements = refList.getDataRefElements();
0333: int numberOfEncryptedElems = refList.size();
0334: EncryptionPolicy policy = null;
0335:
0336: ArrayList targets = null;
0337: //Set references = new HashSet();
0338:
0339: boolean partialReqsMet = false;
0340:
0341: ArrayList optionalTargets = null;
0342: ArrayList requiredTargets = null;
0343: ArrayList attachmentTargets = null;
0344: boolean skipAttachments = false;
0345: EncryptionTarget allCT = null;
0346: boolean verifyReq = false;
0347: if (context.getMode() == FilterProcessingContext.ADHOC) {
0348: policy = (EncryptionPolicy) context.getSecurityPolicy();
0349: targets = ((EncryptionPolicy.FeatureBinding) policy
0350: .getFeatureBinding()).getTargetBindings();
0351: optionalTargets = new ArrayList();
0352: requiredTargets = new ArrayList();
0353:
0354: int i = 0;
0355: while (i < targets.size()) {
0356: EncryptionTarget et = (EncryptionTarget) targets
0357: .get(i++);
0358: if (et.getEnforce()) {
0359: String value = et.getValue();
0360: if (value == MessageConstants.PROCESS_ALL_ATTACHMENTS) {
0361: if (attachmentTargets == null) {
0362: attachmentTargets = new ArrayList();
0363: }
0364: allCT = et;
0365: skipAttachments = true;
0366: } else {
0367: requiredTargets.add(et);
0368: }
0369: } else {
0370: optionalTargets.add(et);
0371: }
0372: }
0373: if (requiredTargets.size() > 0 || skipAttachments) {
0374: verifyReq = true;
0375: }
0376: } else if (context.getMode() == FilterProcessingContext.POSTHOC) {
0377: policy = new EncryptionPolicy();
0378: MessagePolicy messagePolicy = (MessagePolicy) context
0379: .getSecurityPolicy();
0380: messagePolicy.append(policy);
0381: //policy is passed to processencryptedata method.
0382: }
0383:
0384: for (int i = 0; i < numberOfEncryptedElems; i++) {
0385: String refURI = ((SOAPElement) dataRefElements.item(i))
0386: .getAttribute("URI");
0387: SOAPElement encDataElement = null;
0388: EncryptedData ed = null;
0389: try {
0390: encDataElement = (SOAPElement) XMLUtil.getElementById(
0391: secureMessage.getSOAPPart(), refURI
0392: .substring(1));
0393: if (encDataElement.getLocalName() == MessageConstants.ENCRYPTED_HEADER_LNAME
0394: || encDataElement
0395: .getLocalName()
0396: .equals(
0397: MessageConstants.ENCRYPTED_HEADER_LNAME)) {
0398: Iterator itr = encDataElement.getChildElements();
0399: SOAPElement encDataElementChild = null;
0400: while (itr.hasNext()) {
0401: encDataElementChild = (SOAPElement) itr.next();
0402: }
0403: if (encDataElementChild == null) {
0404: throw new XWSSecurityException(
0405: "No EncryptedData child element found in EncryptedHeader");
0406: }
0407: ed = processEncryptedData(encDataElementChild, key,
0408: dataCipher, context, requiredTargets,
0409: optionalTargets, policy, false);
0410: } else {
0411: ed = processEncryptedData(encDataElement, key,
0412: dataCipher, context, requiredTargets,
0413: optionalTargets, policy, false);
0414: }
0415: } catch (TransformerException te) {
0416: log.log(Level.SEVERE,
0417: "WSS1237.Error.Processing.EncrpytedData");
0418: throw new XWSSecurityException(te.getMessage(), te);
0419: }
0420:
0421: if (context.getMode() == FilterProcessingContext.ADHOC
0422: && verifyReq) {
0423: if (ed.isAttachmentData() && skipAttachments) {
0424: attachmentTargets.add(ed);
0425: continue;
0426: }
0427: //ArrayList targetElements = getAllTargetElements(secureMsg, requiredTargets, false);
0428: if (!verifyTargets(secureMessage, requiredTargets, ed,
0429: true)) {
0430: if (optionalTargets.size() == 0) {
0431: log.log(Level.SEVERE,
0432: "WSS1230.failed.receiverReq");
0433: throw new XWSSecurityException(
0434: "Receiver requirement " + "for URI"
0435: + refURI + " is not met");
0436: } else {
0437: if (!verifyTargets(secureMessage,
0438: optionalTargets, ed, false)) {
0439: log.log(Level.SEVERE,
0440: "WSS1230.failed.receiverReq");
0441: throw new XWSSecurityException(
0442: "Receiver requirement " + "for URI"
0443: + refURI + " is not met");
0444: }
0445: }
0446: }
0447: }
0448: }
0449: if (skipAttachments) {
0450: int count = secureMessage.countAttachments();
0451: if (count > attachmentTargets.size()) {
0452: log.log(Level.SEVERE,
0453: "WSS1238.failed.receiverReq.attachments");
0454: throw new XWSSecurityException(
0455: "Receiver requirement cid:* is not met,only "
0456: + attachmentTargets.size()
0457: + " attachments out of " + count
0458: + " were encrypted");
0459: }
0460: }
0461: if (context.getMode() == FilterProcessingContext.ADHOC
0462: && requiredTargets.size() > 0) {
0463: log.log(Level.SEVERE, "WSS1239.failed.receiverReq.more");
0464: throw new XWSSecurityException(
0465: "More receiver requirements specified "
0466: + "than present in the message");
0467: }
0468: }
0469:
0470: public static void processEncryptedData(SOAPElement encDataElement,
0471: SecretKey key, FilterProcessingContext context)
0472: throws XWSSecurityException {
0473: EncryptionPolicy policy = null;
0474: ArrayList optionalTargets = null;
0475: ArrayList requiredTargets = null;
0476: ArrayList attachmentTargets = null;
0477: boolean verifyReq = false;
0478: boolean isBSP = false;
0479: if (context.getMode() == FilterProcessingContext.POSTHOC) {
0480: policy = new EncryptionPolicy();
0481: MessagePolicy messagePolicy = (MessagePolicy) context
0482: .getSecurityPolicy();
0483: isBSP = messagePolicy.isBSP();
0484: policy.isBSP(isBSP);
0485: messagePolicy.append(policy);
0486: } else if (context.getMode() == FilterProcessingContext.ADHOC) {
0487: policy = (EncryptionPolicy) context.getSecurityPolicy();
0488: //isBSP = policy.isBSP();
0489: ArrayList targets = ((EncryptionPolicy.FeatureBinding) policy
0490: .getFeatureBinding()).getTargetBindings();
0491: optionalTargets = new ArrayList();
0492: requiredTargets = new ArrayList();
0493: int i = 0;
0494: while (i < targets.size()) {
0495: EncryptionTarget et = (EncryptionTarget) targets
0496: .get(i++);
0497: if (et.getEnforce()) {
0498: String value = et.getValue();
0499: if (value == MessageConstants.PROCESS_ALL_ATTACHMENTS) {
0500: //log
0501: //TODO: localize the strings
0502: log.log(Level.SEVERE,
0503: "WSS1201.cid_encrypt_all_notsupported");
0504: } else {
0505: requiredTargets.add(et);
0506: }
0507: } else {
0508: optionalTargets.add(et);
0509: }
0510: }
0511: if (requiredTargets.size() > 0) {
0512: verifyReq = true;
0513: }
0514: String id = encDataElement.getAttribute("Id");
0515: EncryptedElement ed = (EncryptedElement) processEncryptedData(
0516: encDataElement, key, null, context,
0517: requiredTargets, optionalTargets, policy, true);
0518:
0519: if (requiredTargets.size() > 1) {
0520: log.log(Level.SEVERE,
0521: "WSS1240.failed.receiverReq.moretargets");
0522: throw new XWSSecurityException(
0523: "Receiver requirement has more targets specified");
0524: }
0525:
0526: SecurableSoapMessage secureMsg = context
0527: .getSecurableSoapMessage();
0528: if (verifyReq
0529: && !verifyTargets(secureMsg, requiredTargets, ed,
0530: true)) {
0531: if (optionalTargets.size() == 0) {
0532: log.log(Level.SEVERE,
0533: "WSS1241.failed.receiverReq.encryptedData");
0534: throw new XWSSecurityException(
0535: "Receiver requirement "
0536: + "for EncryptedData with ID " + id
0537: + " is not met");
0538: } else {
0539: if (!verifyTargets(secureMsg, optionalTargets, ed,
0540: false)) {
0541: log
0542: .log(Level.SEVERE,
0543: "WSS1241.failed.receiverReq.encryptedData");
0544: throw new XWSSecurityException(
0545: "Receiver requirement "
0546: + "for EncryptedData ID " + id
0547: + " is not met");
0548: }
0549: }
0550: }
0551: } else if (context.getMode() == FilterProcessingContext.DEFAULT) {
0552:
0553: EncryptedElement ed = (EncryptedElement) processEncryptedData(
0554: encDataElement, key, null, context,
0555: requiredTargets, optionalTargets, policy, true);
0556:
0557: } else if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0558: context.getInferredSecurityPolicy().append(
0559: new EncryptionPolicy());
0560: EncryptedElement ed = (EncryptedElement) processEncryptedData(
0561: encDataElement, key, null, context,
0562: requiredTargets, optionalTargets, policy, true);
0563:
0564: }
0565: }
0566:
0567: public static EncryptedData processEncryptedData(
0568: SOAPElement encDataElement, SecretKey key,
0569: XMLCipher dataCipher, FilterProcessingContext context,
0570: ArrayList requiredTargets, ArrayList optionalTargets,
0571: EncryptionPolicy encryptionPolicy, boolean updateSH)
0572: throws XWSSecurityException {
0573:
0574: EncryptedDataHeaderBlock xencEncryptedData = new EncryptedDataHeaderBlock(
0575: encDataElement);
0576: SecurableSoapMessage secureMessage = context
0577: .getSecurableSoapMessage();
0578: KeyInfoHeaderBlock keyInfo = xencEncryptedData.getKeyInfo();
0579: String algorithm = null;
0580: algorithm = xencEncryptedData.getEncryptionMethodURI();
0581:
0582: EncryptionPolicy inferredPolicy = (EncryptionPolicy) context
0583: .getInferredPolicy();
0584: EncryptionPolicy.FeatureBinding fb = null;
0585:
0586: //used for WSDL_POLICY mode
0587: EncryptionPolicy inferredWsdlEncPolicy = null;
0588: if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0589: try {
0590: int i = context.getInferredSecurityPolicy().size() - 1;
0591: inferredWsdlEncPolicy = (EncryptionPolicy) context
0592: .getInferredSecurityPolicy().get(i);
0593: } catch (Exception e) {
0594: log.log(Level.SEVERE,
0595: "WSS1237.Error.Processing.EncrpytedData", e);
0596: throw new XWSSecurityException(e);
0597: }
0598: }
0599:
0600: if (inferredPolicy != null) {
0601: fb = (EncryptionPolicy.FeatureBinding) inferredPolicy
0602: .getFeatureBinding();
0603: fb.setDataEncryptionAlgorithm(algorithm);
0604:
0605: }
0606: SecretKey symmetricKey = null;
0607: if (keyInfo == null) {
0608: if (key == null) {
0609: log.log(Level.SEVERE, "WSS1231.null.SymmetricKey");
0610: throw new XWSSecurityException("Symmetric Key is null");
0611: }
0612: symmetricKey = key;
0613: } else {
0614: context.setDataEncryptionAlgorithm(algorithm);
0615: symmetricKey = (SecretKey) KeyResolver.getKey(keyInfo,
0616: false, context);
0617: context.setDataEncryptionAlgorithm(null);
0618: }
0619:
0620: if (symmetricKey == null) {
0621: log.log(Level.SEVERE,
0622: "WSS1202.couldnot.locate.symmetrickey");
0623: throw new XWSSecurityException(
0624: "Couldn't locate symmetricKey for decryption");
0625: }
0626:
0627: boolean isAttachment = false;
0628: String type = xencEncryptedData.getType();
0629: if (type.equals(MessageConstants.ATTACHMENT_CONTENT_ONLY_URI)
0630: || type
0631: .equals(MessageConstants.ATTACHMENT_COMPLETE_URI)) {
0632: isAttachment = true;
0633: }
0634:
0635: Node parent = null;
0636: Node prevSibling = null;
0637: boolean contentOnly = false;
0638:
0639: Element actualEncrypted = null;
0640: //String processedEncryptedDataId = xencEncryptedData.getId();
0641: AttachmentPart encryptedAttachment = null;
0642: com.sun.xml.messaging.saaj.soap.AttachmentPartImpl _attachmentBuffer = new com.sun.xml.messaging.saaj.soap.AttachmentPartImpl();
0643: if (isAttachment) {
0644: // decrypt attachment
0645: String uri = xencEncryptedData.getCipherReference(false,
0646: null).getAttribute("URI");
0647: contentOnly = type
0648: .equals(MessageConstants.ATTACHMENT_CONTENT_ONLY_URI);
0649:
0650: try {
0651: AttachmentPart p = secureMessage.getAttachmentPart(uri);
0652: Iterator j = p.getAllMimeHeaders();
0653: while (j.hasNext()) {
0654: MimeHeader mh = (MimeHeader) j.next();
0655: _attachmentBuffer.setMimeHeader(mh.getName(), mh
0656: .getValue());
0657: }
0658: _attachmentBuffer.setDataHandler(p.getDataHandler());
0659: encryptedAttachment = decryptAttachment(secureMessage,
0660: xencEncryptedData, symmetricKey);
0661:
0662: } catch (java.io.IOException ioe) {
0663: log.log(Level.SEVERE,
0664: "WSS1232.failedto.decrypt.attachment", ioe);
0665: throw new XWSSecurityException(ioe);
0666: } catch (javax.xml.soap.SOAPException se) {
0667: log.log(Level.SEVERE,
0668: "WSS1232.failedto.decrypt.attachment", se);
0669: throw new XWSSecurityException(se);
0670: } catch (javax.mail.MessagingException me) {
0671: log.log(Level.SEVERE,
0672: "WSS1232.failedto.decrypt.attachment", me);
0673: throw new XWSSecurityException(me);
0674: }
0675: encDataElement.detachNode();
0676: } else {
0677: parent = encDataElement.getParentNode();
0678: prevSibling = encDataElement.getPreviousSibling();
0679: if (dataCipher == null) {
0680: dataCipher = initXMLCipher(symmetricKey, algorithm);
0681: }
0682: if (parent.getLocalName() == MessageConstants.ENCRYPTED_HEADER_LNAME
0683: || parent.getLocalName().equals(
0684: MessageConstants.ENCRYPTED_HEADER_LNAME)) {
0685: try {
0686: encDataElement.getParentNode().getParentNode()
0687: .replaceChild(encDataElement, parent);
0688: parent = encDataElement.getParentNode();
0689: prevSibling = encDataElement.getPreviousSibling();
0690: } catch (DOMException e) {
0691: log.log(Level.SEVERE, "WSS1242.exception.dom", e);
0692: throw new XWSSecurityException(e);
0693: }
0694: }
0695: decryptElementWithCipher(dataCipher, encDataElement,
0696: secureMessage);
0697:
0698: SOAPElement currentNode = null;
0699: if (updateSH
0700: && secureMessage.findSecurityHeader()
0701: .getCurrentHeaderBlockElement() == encDataElement) {
0702: if (prevSibling == null) {
0703: currentNode = (SOAPElement) parent.getFirstChild();
0704: } else {
0705: currentNode = (SOAPElement) prevSibling
0706: .getNextSibling();
0707: }
0708: secureMessage.findSecurityHeader()
0709: .setCurrentHeaderElement(currentNode);
0710: }
0711:
0712: if (xencEncryptedData.getType().equals(
0713: MessageConstants.XENC_NS + "Content")) {
0714: actualEncrypted = (Element) resolveEncryptedNode(
0715: parent, prevSibling, true);
0716: contentOnly = true;
0717: } else {
0718: if (xencEncryptedData.getType().equals(
0719: MessageConstants.XENC_NS + "Element")) {
0720: actualEncrypted = (Element) resolveEncryptedNode(
0721: parent, prevSibling, false);
0722: contentOnly = false;
0723: }
0724: }
0725: }
0726:
0727: if (context.getMode() == FilterProcessingContext.POSTHOC) {
0728: //log;
0729: if (encryptionPolicy == null) {
0730: encryptionPolicy = new EncryptionPolicy();
0731: }
0732: EncryptionPolicy.FeatureBinding eFB = (EncryptionPolicy.FeatureBinding) encryptionPolicy
0733: .getFeatureBinding();
0734: EncryptionTarget encTarget = new EncryptionTarget();
0735: //target.addCipherReferenceTransform(transform
0736: encTarget.setDataEncryptionAlgorithm(algorithm);
0737: encTarget.setContentOnly(contentOnly);
0738: if (isAttachment) {
0739: encTarget.addCipherReferenceTransform(type);
0740: }
0741: if (encryptedAttachment != null) {
0742: encTarget.setValue(encryptedAttachment.getContentId());
0743: } else {
0744: String id = actualEncrypted.getAttribute("Id");
0745:
0746: if ("".equals(id)) {
0747: id = actualEncrypted.getAttributeNS(
0748: MessageConstants.WSU_NS, "Id");
0749: }
0750: encTarget.setValue(id);
0751: }
0752: encTarget.setType(Target.TARGET_TYPE_VALUE_URI);
0753: encTarget.setElementData(actualEncrypted);
0754: Iterator transformItr = xencEncryptedData.getTransforms();
0755: if (transformItr != null) {
0756: while (transformItr.hasNext()) {
0757: encTarget
0758: .addCipherReferenceTransform((String) transformItr
0759: .next());
0760: }
0761: }
0762: eFB.addTargetBinding(encTarget);
0763: return null;
0764: } else if (context.getMode() == FilterProcessingContext.ADHOC
0765: || context.getMode() == FilterProcessingContext.DEFAULT) {
0766: if (isAttachment) {
0767: return new AttachmentData(encryptedAttachment
0768: .getContentId(), contentOnly);
0769: }
0770: EncryptedElement encryptedElement = new EncryptedElement(
0771: actualEncrypted, contentOnly);
0772: return encryptedElement;
0773: } else if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0774: QName qname = new QName(actualEncrypted.getNamespaceURI(),
0775: actualEncrypted.getLocalName());
0776: EncryptionPolicy.FeatureBinding featureBinding = (EncryptionPolicy.FeatureBinding) inferredWsdlEncPolicy
0777: .getFeatureBinding();
0778: EncryptionTarget target = new EncryptionTarget();
0779: if (actualEncrypted.getNamespaceURI().equals(
0780: MessageConstants.WSSE_NS)
0781: || actualEncrypted.getNamespaceURI().equals(
0782: MessageConstants.WSSE11_NS)
0783: || actualEncrypted.getNamespaceURI().equals(
0784: MessageConstants.WSSC_NS)
0785: || actualEncrypted.getNamespaceURI().equals(
0786: MessageConstants.WSU_NS)) {
0787: String id = actualEncrypted.getAttribute("Id");
0788: if ("".equals(id)) {
0789: id = actualEncrypted.getAttributeNS(
0790: MessageConstants.WSU_NS, "Id");
0791: }
0792: target.setValue(id);
0793: target.setType(EncryptionTarget.TARGET_TYPE_VALUE_URI);
0794: } else {
0795: target.setQName(qname);
0796: target
0797: .setType(EncryptionTarget.TARGET_TYPE_VALUE_QNAME);
0798: }
0799:
0800: target.setDataEncryptionAlgorithm(algorithm);
0801: target.setContentOnly(contentOnly);
0802: featureBinding.addTargetBinding(target);
0803: if (qname.getLocalPart().equals("Assertion")) {
0804: //TODO: check NS URI also
0805: featureBinding.encryptsIssuedToken(true);
0806: }
0807: }
0808: return null;
0809: }
0810:
0811: private static String getDataEncryptionAlgorithm(
0812: SOAPElement referenceList) throws XWSSecurityException {
0813: try {
0814: ReferenceListHeaderBlock refList = new ReferenceListHeaderBlock(
0815: referenceList);
0816: NodeList dataRefElements = refList.getDataRefElements();
0817: Element dataRef = (Element) dataRefElements.item(0);
0818: String refURI = dataRef.getAttribute("URI");
0819:
0820: SOAPElement encDataElement = null;
0821: encDataElement = (SOAPElement) XMLUtil.getElementById(
0822: referenceList.getOwnerDocument(), refURI
0823: .substring(1));
0824: NodeList nodeList = encDataElement.getElementsByTagNameNS(
0825: MessageConstants.XENC_NS, "EncryptionMethod");
0826: if (nodeList.getLength() <= 0) {
0827: return MessageConstants.TRIPLE_DES_BLOCK_ENCRYPTION;
0828: }
0829: Element em = (Element) nodeList.item(0);
0830: if (em != null) {
0831: String algo = em.getAttribute("Algorithm");
0832: if ("".equals(algo)) {
0833: return MessageConstants.TRIPLE_DES_BLOCK_ENCRYPTION;
0834: }
0835: return algo;
0836: }
0837: } catch (XWSSecurityException xe) {
0838: log.log(Level.SEVERE,
0839: "WSS1233.failed.get.DataEncryptionAlgorithm", xe);
0840: throw xe;
0841: } catch (Exception ex) {
0842: log.log(Level.SEVERE,
0843: "WSS1233.failed.get.DataEncryptionAlgorithm", ex);
0844: throw new XWSSecurityException(ex);
0845: }
0846: return MessageConstants.TRIPLE_DES_BLOCK_ENCRYPTION;
0847: }
0848:
0849: private static AttachmentPart decryptAttachment(
0850: SecurableSoapMessage ssm, EncryptedDataHeaderBlock edhb,
0851: SecretKey symmetricKey) throws java.io.IOException,
0852: javax.xml.soap.SOAPException,
0853: javax.mail.MessagingException, XWSSecurityException {
0854:
0855: String uri = edhb.getCipherReference(false, null).getAttribute(
0856: "URI");
0857: boolean contentOnly = edhb.getType().equals(
0858: MessageConstants.ATTACHMENT_CONTENT_ONLY_URI);
0859: String mimeType = edhb.getMimeType();
0860: Element dsTransform = (Element) edhb.getTransforms().next();
0861: /*
0862: if ((dsTransform = (Element)edhb.getTransforms().next()) != null) {
0863: // log
0864: throw new XWSSecurityException("Only one ds:Transform element expected " +
0865: "in xenc:EncryptedData corresponding to " +
0866: "an AttachmentPart");
0867: }*/
0868:
0869: if (!dsTransform.getAttribute("Algorithm").equals(
0870: MessageConstants.ATTACHMENT_CONTENT_ONLY_TRANSFORM_URI)) {
0871: log.log(Level.SEVERE, "WSS1234.invalid.transform=");
0872: throw new XWSSecurityException("Unexpected ds:Transform, "
0873: + dsTransform.getAttribute("Algorithm"));
0874: }
0875:
0876: AttachmentPart part = ssm.getAttachmentPart(uri);
0877: ByteArrayOutputStream baos = new ByteArrayOutputStream();
0878: part.getDataHandler().writeTo(baos);
0879:
0880: byte[] cipherInput = ((ByteArrayOutputStream) baos)
0881: .toByteArray();
0882: String tmp = edhb.getEncryptionMethodURI();
0883:
0884: // initialize Cipher
0885: Cipher decryptor = null;
0886: byte[] cipherOutput = null;
0887: try {
0888: String dataAlgorithm = JCEMapper.translateURItoJCEID(tmp);
0889: decryptor = Cipher.getInstance(dataAlgorithm);
0890:
0891: //decryptor = Cipher.getInstance("DESede/CBC/ISO10126Padding");
0892:
0893: int ivLen = decryptor.getBlockSize();
0894: byte[] ivBytes = new byte[ivLen];
0895:
0896: System.arraycopy(cipherInput, 0, ivBytes, 0, ivLen);
0897: IvParameterSpec iv = new IvParameterSpec(ivBytes);
0898:
0899: decryptor.init(Cipher.DECRYPT_MODE, symmetricKey, iv);
0900:
0901: cipherOutput = decryptor.doFinal(cipherInput, ivLen,
0902: cipherInput.length - ivLen);
0903: } catch (Exception e) {
0904: log.log(Level.SEVERE,
0905: "WSS1232.failedto.decrypt.attachment", e);
0906: throw new XWSSecurityException(e);
0907: }
0908:
0909: InputStream is = new ByteArrayInputStream(cipherOutput);
0910: if (contentOnly) {
0911: // update headers and content
0912: part.setContentType(mimeType);
0913: //javax.mail.internet.ContentType contentType = new javax.mail.internet.ContentType(mimeType);
0914:
0915: String[] cLength = part
0916: .getMimeHeader(MimeConstants.CONTENT_LENGTH);
0917: if (cLength != null && !cLength[0].equals(""))
0918: part.setMimeHeader(MimeConstants.CONTENT_LENGTH,
0919: Integer.toString(cipherOutput.length));
0920:
0921: part.clearContent();
0922: part.setDataHandler(new javax.activation.DataHandler(
0923: new _DS(cipherOutput, mimeType)));
0924:
0925: } else {
0926: MimeBodyPart decryptedAttachment = new MimeBodyPart(is);
0927: // validate cid
0928: String dcId = decryptedAttachment.getContentID();
0929: if (dcId == null
0930: || !uri.substring(4).equals(
0931: dcId.substring(1, dcId.length() - 1))) {
0932: log.log(Level.SEVERE, "WSS1234.unmatched.content-id");
0933: throw new XWSSecurityException(
0934: "Content-Ids in encrypted and decrypted attachments donot match");
0935: }
0936:
0937: part.removeAllMimeHeaders();
0938:
0939: // copy headers
0940: Enumeration h_enum = decryptedAttachment.getAllHeaders();
0941: while (h_enum.hasMoreElements()) {
0942: Header hdr = (Header) h_enum.nextElement();
0943: String hname = hdr.getName();
0944: String hvale = hdr.getValue();
0945: part.setMimeHeader(hname, hvale);
0946: }
0947:
0948: // set content
0949: part.clearContent();
0950: part.setDataHandler(decryptedAttachment.getDataHandler());
0951: }
0952:
0953: return part;
0954: }
0955:
0956: private static boolean verifyTargets(SecurableSoapMessage ssm,
0957: ArrayList reqTargets, EncryptedData encData,
0958: boolean requiredTarget) throws XWSSecurityException {
0959: boolean found = false;
0960: for (int et = 0; et < reqTargets.size(); et++) {
0961: EncryptionTarget encTarget = (EncryptionTarget) reqTargets
0962: .get(et);
0963:
0964: if (encData.isElementData()) {
0965: EncryptedElement elementData = (EncryptedElement) encData;
0966: if (encTarget.getType() == Target.TARGET_TYPE_VALUE_URI) {
0967: if (encTarget.isAttachment()) {
0968: continue;
0969: }
0970: Element element = ssm.getElementById(encTarget
0971: .getValue());
0972: /*if(element == null && requiredTarget){
0973: throw new XWSSecurityException("Not able to resolve"+
0974: " receiver requirement target "+encTarget.getValue());
0975: }*/
0976: EncryptedElement ee = new EncryptedElement(element,
0977: encTarget.getContentOnly());
0978: if (ee.equals((EncryptedElement) encData)) {
0979: found = true;
0980: reqTargets.remove(et);
0981: break;
0982: }
0983: } else if (encTarget.getType() == encTarget.TARGET_TYPE_VALUE_QNAME) {
0984: QName qname = encTarget.getQName();
0985: String localPart = qname.getLocalPart();
0986: if (localPart.equals(elementData.getElement()
0987: .getLocalName())) {
0988: ArrayList list = getAllTargetElements(ssm,
0989: encTarget, requiredTarget);
0990: if (contains(list, (EncryptedElement) encData)) {
0991: reqTargets.remove(et);
0992: found = true;
0993: break;
0994: }
0995: }
0996: } else if (encTarget.getType() == encTarget.TARGET_TYPE_VALUE_XPATH) {
0997: ArrayList list = getAllTargetElements(ssm,
0998: encTarget, requiredTarget);
0999: if (contains(list, (EncryptedElement) encData)) {
1000: reqTargets.remove(et);
1001: found = true;
1002: break;
1003: }
1004: }
1005: } else {
1006: if (encTarget.getType() == Target.TARGET_TYPE_VALUE_URI
1007: && encTarget.isAttachment()) {
1008: if (encTarget.getValue().startsWith("cid:")
1009: && encTarget.getEnforce()) {
1010: AttachmentPart ap = (AttachmentPart) ssm
1011: .getAttachmentPart(encTarget.getValue());
1012: AttachmentData ad = (AttachmentData) encData;
1013: if (ap != null
1014: && (ad.getCID() == ap.getContentId())
1015: && (ad.isContentOnly() == encTarget
1016: .getContentOnly())) {
1017: found = true;
1018: reqTargets.remove(et);
1019: break;
1020: }
1021: } else {
1022: reqTargets.remove(et);
1023: found = true;
1024: break;
1025: }
1026: }
1027: }
1028: }
1029: return found;
1030: }
1031:
1032: private static boolean contains(List targetList, EncryptedElement ee) {
1033: for (int i = 0; i < targetList.size(); i++) {
1034: EncryptedElement ed = (EncryptedElement) targetList.get(i);
1035: if (ed.equals(ee))
1036: return true;
1037: }
1038: return false;
1039: }
1040:
1041: private static boolean isEquals(EncryptedData msgEd,
1042: EncryptedData reqEd) {
1043: if (msgEd.isElementData() && reqEd.isElementData()) {
1044: ((EncryptedElement) msgEd).equals((EncryptedElement) reqEd);
1045: } else if (msgEd.isAttachmentData() && reqEd.isAttachmentData()) {
1046: ((AttachmentData) msgEd).equals((AttachmentData) reqEd);
1047: }
1048: return false;
1049: }
1050:
1051: private static ArrayList getAllTargetElements(
1052: SecurableSoapMessage ssm, EncryptionTarget target,
1053: boolean reqElements) throws XWSSecurityException {
1054:
1055: ArrayList result = new ArrayList();
1056:
1057: boolean contentOnly = target.getContentOnly();
1058:
1059: try {
1060: Object obj = ssm.getMessageParts(target);
1061:
1062: if (obj instanceof SOAPElement) {
1063: contribute((Node) obj, result, contentOnly);
1064: } else if (obj instanceof NodeList) {
1065: contribute((NodeList) obj, result, contentOnly);
1066: } else if (obj instanceof Node) {
1067: contribute((Node) obj, result, contentOnly);
1068: }
1069: } catch (XWSSecurityException xwse) {
1070: if (reqElements) {
1071: log.log(Level.SEVERE,
1072: "WSS1235.failedto.get.targetElements", xwse);
1073: throw xwse;
1074: }
1075: }
1076:
1077: return result;
1078: }
1079:
1080: private static void contribute(NodeList targetElements,
1081: ArrayList result, boolean contentOnly) {
1082: for (int i = 0; i < targetElements.getLength(); i++)
1083: contribute((Node) targetElements.item(i), result,
1084: contentOnly);
1085: }
1086:
1087: private static void contribute(Node element, ArrayList result,
1088: boolean contentOnly) {
1089: EncryptedElement targetElement = new EncryptedElement(
1090: (Element) element, contentOnly);
1091: result.add(targetElement);
1092: }
1093:
1094: private static void contribute(AttachmentPart element,
1095: ArrayList result, boolean contentOnly) {
1096: AttachmentData targetElement = new AttachmentData(element
1097: .getContentId(), contentOnly);
1098: result.add(targetElement);
1099: }
1100:
1101: private static Node resolveEncryptedNode(Node parent,
1102: Node prevSibling, boolean contentOnly) {
1103: Node actualEncrypted = null;
1104: if (!contentOnly) {
1105: if (prevSibling == null)
1106: actualEncrypted = parent.getFirstChild();
1107: else
1108: actualEncrypted = prevSibling.getNextSibling();
1109: } else
1110: actualEncrypted = parent;
1111: return actualEncrypted;
1112: }
1113:
1114: private static XMLCipher initXMLCipher(Key key, String algorithm)
1115: throws XWSSecurityException {
1116:
1117: XMLCipher xmlCipher;
1118: try {
1119: xmlCipher = XMLCipher.getInstance(algorithm);
1120: xmlCipher.init(XMLCipher.DECRYPT_MODE, key);
1121: } catch (XMLEncryptionException xee) {
1122:
1123: log.log(Level.SEVERE, "WSS1203.unableto.decrypt.message",
1124: new Object[] { xee.getMessage() });
1125: throw new XWSSecurityException("Unable to decrypt message",
1126: xee);
1127: }
1128: return xmlCipher;
1129: }
1130:
1131: private static Document decryptElementWithCipher(
1132: XMLCipher xmlCipher, SOAPElement element,
1133: SecurableSoapMessage secureMessage)
1134: throws XWSSecurityException {
1135:
1136: Document document = null;
1137: // TODO the following normalize() call is a workaround for a bug
1138: // in xmlsec.jar where it appears to fail unless all Text
1139: // children are merged into one.
1140: element.normalize();
1141: try {
1142: document = xmlCipher.doFinal(secureMessage.getSOAPPart(),
1143: element);
1144: } catch (Exception e) {
1145: log.log(Level.SEVERE, "WSS1203.unableto.decrypt.message",
1146: new Object[] { e.getMessage() });
1147:
1148: XWSSecurityException xse = new XWSSecurityException(
1149: "Unable to decrypt message", e);
1150: throw SecurableSoapMessage.newSOAPFaultException(
1151: MessageConstants.WSSE_FAILED_CHECK,
1152: "Unable to decrypt message", xse);
1153: }
1154: return document;
1155: }
1156:
1157: private static interface EncryptedData {
1158: public boolean isElementData();
1159:
1160: public boolean isAttachmentData();
1161: }
1162:
1163: private static class AttachmentData implements EncryptedData {
1164: private String cid = null;
1165: private boolean contentOnly = false;
1166:
1167: public AttachmentData(String cid, boolean co) {
1168: this .cid = cid;
1169: contentOnly = co;
1170: }
1171:
1172: public String getCID() {
1173: return cid;
1174: }
1175:
1176: public boolean isContentOnly() {
1177: return contentOnly;
1178: }
1179:
1180: public boolean equals(AttachmentData data) {
1181: if (cid != null && cid.equals(data.getCID())
1182: && (contentOnly == data.isContentOnly())) {
1183: return true;
1184: }
1185: return false;
1186: }
1187:
1188: public boolean isElementData() {
1189: return false;
1190: }
1191:
1192: public boolean isAttachmentData() {
1193: return true;
1194: }
1195: }
1196:
1197: private static class EncryptedElement implements EncryptedData {
1198: private Element element;
1199: private boolean contentOnly;
1200: private EncryptionPolicy policy = null;
1201:
1202: public EncryptedElement(Element element, boolean contentOnly) {
1203: this .element = element;
1204: this .contentOnly = contentOnly;
1205: }
1206:
1207: public Element getElement() {
1208: return element;
1209: }
1210:
1211: public boolean getContentOnly() {
1212: return contentOnly;
1213: }
1214:
1215: public boolean equals(EncryptedElement element) {
1216: EncryptedElement encryptedElement = (EncryptedElement) element;
1217: return (encryptedElement.getElement() == this .element && encryptedElement
1218: .getContentOnly() == this .contentOnly);
1219: //&& this.policy.equals(encryptedElement.getPolicy()));
1220:
1221: }
1222:
1223: public void setpolicy(EncryptionPolicy policy) {
1224: this .policy = policy;
1225: }
1226:
1227: public EncryptionPolicy getPolicy() {
1228: return policy;
1229: }
1230:
1231: public boolean isElementData() {
1232: return true;
1233: }
1234:
1235: public boolean isAttachmentData() {
1236: return false;
1237: }
1238: }
1239:
1240: private static class _DS implements javax.activation.DataSource {
1241: byte[] _b = null;
1242: String _mt = null;
1243:
1244: _DS(byte[] b, String mt) {
1245: this ._b = b;
1246: this ._mt = mt;
1247: }
1248:
1249: public java.io.InputStream getInputStream()
1250: throws java.io.IOException {
1251: return new java.io.ByteArrayInputStream(_b);
1252: }
1253:
1254: public java.io.OutputStream getOutputStream()
1255: throws java.io.IOException {
1256: java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
1257: baos.write(_b, 0, _b.length);
1258: return baos;
1259: }
1260:
1261: public String getName() {
1262: return "_DS";
1263: }
1264:
1265: public String getContentType() {
1266: return _mt;
1267: }
1268: }
1269: }
|