0001: /*
0002: * $Id: SignatureProcessor.java,v 1.20 2007/08/22 11:00:27 ashutoshshahi Exp $
0003: */
0004:
0005: /*
0006: * The contents of this file are subject to the terms
0007: * of the Common Development and Distribution License
0008: * (the License). You may not use this file except in
0009: * compliance with the License.
0010: *
0011: * You can obtain a copy of the license at
0012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
0013: * See the License for the specific language governing
0014: * permissions and limitations under the License.
0015: *
0016: * When distributing Covered Code, include this CDDL
0017: * Header Notice in each file and include the License file
0018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
0019: * If applicable, add the following below the CDDL Header,
0020: * with the fields enclosed by brackets [] replaced by
0021: * you own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
0025: */
0026:
0027: package com.sun.xml.wss.impl.dsig;
0028:
0029: import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey;
0030: import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
0031: import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
0032: import com.sun.xml.wss.core.reference.KeyIdentifier;
0033: import com.sun.xml.wss.impl.misc.Base64;
0034: import com.sun.xml.ws.security.IssuedTokenContext;
0035: import com.sun.xml.ws.security.impl.DerivedKeyTokenImpl;
0036: import com.sun.xml.ws.security.DerivedKeyToken;
0037: import com.sun.xml.wss.core.DerivedKeyTokenHeaderBlock;
0038: import com.sun.xml.wss.core.reference.X509ThumbPrintIdentifier;
0039: import com.sun.xml.wss.impl.WssSoapFaultException;
0040: import com.sun.xml.wss.XWSSecurityException;
0041: import com.sun.xml.wss.impl.FilterProcessingContext;
0042: import com.sun.xml.wss.core.reference.X509SubjectKeyIdentifier;
0043: import com.sun.xml.wss.impl.policy.mls.DerivedTokenKeyBinding;
0044: import com.sun.xml.wss.impl.policy.mls.IssuedTokenKeyBinding;
0045: import com.sun.xml.wss.impl.policy.verifier.SignaturePolicyVerifier;
0046: import com.sun.xml.wss.logging.LogDomainConstants;
0047: import com.sun.xml.wss.impl.MessageConstants;
0048: import com.sun.xml.wss.impl.PolicyViolationException;
0049: import com.sun.xml.wss.impl.SecurableSoapMessage;
0050: import com.sun.xml.wss.impl.PolicyTypeUtil;
0051: import com.sun.xml.wss.impl.misc.SecurityUtil;
0052:
0053: import com.sun.xml.wss.core.SecurityHeader;
0054: import com.sun.xml.wss.core.SecurityTokenReference;
0055: import com.sun.xml.wss.core.SamlAssertionHeaderBlock;
0056: import com.sun.xml.wss.core.X509SecurityToken;
0057: import com.sun.xml.wss.core.reference.DirectReference;
0058: import com.sun.xml.wss.core.reference.X509IssuerSerial;
0059: import com.sun.xml.wss.core.reference.EncryptedKeySHA1Identifier;
0060: import com.sun.xml.wss.core.KeyInfoHeaderBlock;
0061:
0062: import com.sun.xml.wss.impl.policy.mls.MessagePolicy;
0063:
0064: import com.sun.xml.wss.impl.policy.mls.SignaturePolicy;
0065: import com.sun.xml.wss.impl.policy.mls.WSSPolicy;
0066: import com.sun.xml.wss.impl.policy.SecurityPolicy;
0067: import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
0068: import com.sun.xml.wss.impl.policy.mls.PrivateKeyBinding;
0069: import com.sun.xml.wss.impl.policy.mls.SignatureTarget;
0070: import com.sun.xml.wss.impl.policy.mls.SymmetricKeyBinding;
0071: import com.sun.xml.wss.impl.keyinfo.KeyIdentifierStrategy;
0072: import com.sun.xml.wss.impl.keyinfo.KeyInfoStrategy;
0073: import com.sun.xml.wss.core.SecurityContextTokenImpl;
0074: import com.sun.xml.ws.security.SecurityContextToken;
0075: import com.sun.xml.wss.impl.policy.mls.SecureConversationTokenKeyBinding;
0076: import com.sun.xml.wss.impl.AlgorithmSuite;
0077:
0078: import java.io.IOException;
0079: import java.io.InputStream;
0080:
0081: import java.security.Key;
0082: import java.security.cert.X509Certificate;
0083: import java.security.MessageDigest;
0084:
0085: import java.util.ArrayList;
0086: import java.util.Collections;
0087: import java.util.HashMap;
0088: import java.util.Iterator;
0089: import java.util.List;
0090: import java.util.logging.Level;
0091: import java.util.logging.Logger;
0092:
0093: import javax.xml.crypto.Data;
0094: import javax.xml.crypto.KeySelectorException;
0095: import javax.xml.crypto.NodeSetData;
0096: import javax.xml.crypto.OctetStreamData;
0097: import javax.xml.crypto.URIReference;
0098: import javax.xml.crypto.URIReferenceException;
0099: import javax.xml.crypto.dsig.Reference;
0100: import javax.xml.crypto.dsig.SignedInfo;
0101: import javax.xml.crypto.dsig.Transform;
0102: import javax.xml.crypto.dsig.TransformService;
0103: import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
0104: import javax.xml.crypto.dsig.XMLSignature;
0105: import javax.xml.crypto.dsig.XMLSignatureException;
0106: import javax.xml.crypto.dsig.XMLSignatureFactory;
0107: import javax.xml.crypto.dsig.dom.DOMSignContext;
0108: import javax.xml.crypto.dsig.dom.DOMValidateContext;
0109: import javax.xml.crypto.dsig.spec.TransformParameterSpec;
0110: import javax.xml.crypto.dsig.keyinfo.KeyInfo;
0111: import javax.crypto.spec.SecretKeySpec;
0112:
0113: import javax.xml.soap.SOAPElement;
0114: import javax.xml.soap.SOAPMessage;
0115: import javax.xml.namespace.QName;
0116:
0117: import org.w3c.dom.Node;
0118: import org.w3c.dom.Element;
0119: import org.w3c.dom.NodeList;
0120:
0121: import com.sun.xml.ws.security.trust.GenericToken;
0122:
0123: import com.sun.xml.wss.impl.XMLUtil;
0124: import java.security.NoSuchAlgorithmException;
0125: import javax.xml.soap.SOAPException;
0126:
0127: /*
0128: *
0129: * This class provides support for WSS 1.0 signature generation and verification.
0130: * This class depends on JSR105 Digital signature implementation.
0131: * @author K.Venugopal@sun.com
0132: *
0133: */
0134: public class SignatureProcessor {
0135: private static Logger logger = Logger.getLogger(
0136: LogDomainConstants.IMPL_SIGNATURE_DOMAIN,
0137: LogDomainConstants.IMPL_SIGNATURE_DOMAIN_BUNDLE);
0138:
0139: /**
0140: *
0141: * @param context FilterProcessingContext
0142: * @throws XWSSecurityException
0143: * @return errorCode
0144: */
0145: public static int sign(FilterProcessingContext context)
0146: throws XWSSecurityException {
0147:
0148: try {
0149: SignaturePolicy signaturePolicy = (SignaturePolicy) context
0150: .getSecurityPolicy();
0151: SOAPMessage soapMessage = context.getSOAPMessage();
0152: //Dependant on secure soap meesage.
0153: //discuss and refactor.
0154: SecurableSoapMessage secureMessage = context
0155: .getSecurableSoapMessage();
0156: WSSPolicy keyBinding = (WSSPolicy) signaturePolicy
0157: .getKeyBinding();
0158: if (logger.isLoggable(Level.FINEST)) {
0159: logger.log(Level.FINEST, "KeyBinding is " + keyBinding);
0160: }
0161:
0162: Key signingKey = null;
0163: Node nextSibling = null;
0164: //TODO :: Creation of WSSPolicyConsumerImpl every time.
0165: WSSPolicyConsumerImpl dsigHelper = WSSPolicyConsumerImpl
0166: .getInstance();
0167: KeyInfo keyInfo = null;
0168: SecurityHeader securityHeader = secureMessage
0169: .findOrCreateSecurityHeader();
0170:
0171: SignaturePolicy.FeatureBinding featureBinding = (SignaturePolicy.FeatureBinding) signaturePolicy
0172: .getFeatureBinding();
0173: AlgorithmSuite algSuite = context.getAlgorithmSuite();
0174:
0175: boolean wss11Receiver = "true"
0176: .equals(context
0177: .getExtraneousProperty("EnableWSS11PolicyReceiver"));
0178: boolean wss11Sender = "true".equals(context
0179: .getExtraneousProperty("EnableWSS11PolicySender"));
0180: boolean wss10 = !wss11Sender;
0181: boolean sendEKSHA1 = wss11Receiver && wss11Sender
0182: && (getEKSHA1Ref(context) != null);
0183:
0184: if (PolicyTypeUtil.usernameTokenPolicy(keyBinding)) {
0185: logger.log(Level.SEVERE,
0186: "WSS1326.unsupported.usernametoken.keybinding");
0187: throw new XWSSecurityException(
0188: "UsernameToken as KeyBinding for SignaturePolicy is Not Yet Supported");
0189: } else if (PolicyTypeUtil
0190: .derivedTokenKeyBinding(keyBinding)) {
0191: DerivedTokenKeyBinding dtk = (DerivedTokenKeyBinding) keyBinding
0192: .clone();
0193:
0194: WSSPolicy originalKeyBinding = dtk
0195: .getOriginalKeyBinding();
0196:
0197: String algorithm = null;
0198: if (algSuite != null) {
0199: algorithm = algSuite.getEncryptionAlgorithm();
0200: }
0201: String jceAlgo = SecurityUtil
0202: .getSecretKeyAlgorithm(algorithm);
0203: //The offset and length to be used for DKT
0204: //TODO: PLUGFEST the length here should be set correctly
0205: long offset = 0; // Default 0
0206: long length = SecurityUtil
0207: .getLengthFromAlgorithm(algorithm);
0208: if (length == 32)
0209: length = 24;
0210:
0211: if (PolicyTypeUtil
0212: .x509CertificateBinding(originalKeyBinding)) {
0213: // this is becuase SecurityPolicy Converter never produces this combination
0214: logger
0215: .log(Level.SEVERE,
0216: "WSS1327.unsupported.asymmetricbinding.derivedkey.x509token");
0217: throw new XWSSecurityException(
0218: "Asymmetric Binding with DerivedKeys under X509Token Policy Not Yet Supported");
0219: } else if (PolicyTypeUtil
0220: .symmetricKeyBinding(originalKeyBinding)) {
0221:
0222: SymmetricKeyBinding skb = null;
0223: if (context.getSymmetricKeyBinding() != null) {
0224: skb = context.getSymmetricKeyBinding();
0225: context.setSymmetricKeyBinding(null);
0226: }
0227: //Construct a derivedKeyToken to be used
0228: Key originalKey = null;
0229: if (context.getCurrentSecret() != null) {
0230: originalKey = context.getCurrentSecret();
0231: } else {
0232: originalKey = skb.getSecretKey();
0233: context.setCurrentSecret(originalKey);
0234: }
0235: byte[] secret = originalKey.getEncoded();
0236: DerivedKeyToken dkt = new DerivedKeyTokenImpl(
0237: offset, length, secret);
0238: //get the signing key for signature from derivedkeyToken
0239: signingKey = dkt.generateSymmetricKey(jceAlgo);
0240:
0241: Node[] nxtSiblingContainer = new Node[1];
0242: keyInfo = prepareForSymmetricKeySignature(context,
0243: keyBinding, originalKey, signaturePolicy,
0244: nxtSiblingContainer, null, dkt);
0245: nextSibling = nxtSiblingContainer[0];
0246:
0247: } else if (PolicyTypeUtil
0248: .issuedTokenKeyBinding(originalKeyBinding)) {
0249: byte[] prfKey = context.getTrustContext()
0250: .getProofKey();
0251: if (prfKey == null) {
0252: //handle Asymmetric Issued Token
0253: X509Certificate cert = context
0254: .getTrustContext()
0255: .getRequestorCertificate();
0256: if (cert == null) {
0257: logger
0258: .log(Level.SEVERE,
0259: "WSS1328.illegal.Certificate.key.null");
0260: throw new XWSSecurityException(
0261: "Requestor Certificate and Proof Key are both null for Issued Token");
0262: }
0263: signingKey = context
0264: .getSecurityEnvironment()
0265: .getPrivateKey(
0266: context
0267: .getExtraneousProperties(),
0268: cert);
0269:
0270: //Get the IssuedToken and insert it into the message
0271: GenericToken issuedToken = (GenericToken) context
0272: .getTrustContext().getSecurityToken();
0273: Element elem = (Element) issuedToken
0274: .getTokenValue();
0275: SOAPElement tokenElem = XMLUtil
0276: .convertToSoapElement(secureMessage
0277: .getSOAPPart(), elem);
0278: //FIX for Issue 26: We need an Id to cache and MS is not setting in
0279: //some cases
0280: String tokId = tokenElem.getAttribute("Id");
0281: if ("".equals(tokId)
0282: && MessageConstants.ENCRYPTED_DATA_LNAME
0283: .equals(tokenElem
0284: .getLocalName())) {
0285: tokenElem.setAttribute("Id", secureMessage
0286: .generateId());
0287: }
0288: context.getTokenCache().put(
0289: keyBinding.getUUID(), tokenElem);
0290: IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding) originalKeyBinding;
0291: boolean includeToken = (ikb.INCLUDE_ALWAYS
0292: .equals(ikb.getIncludeToken()) || (ikb.INCLUDE_ALWAYS_TO_RECIPIENT
0293: .equals(ikb.getIncludeToken())));
0294: Element strElem = null;
0295:
0296: if (includeToken) {
0297: strElem = (Element) context
0298: .getTrustContext()
0299: .getAttachedSecurityTokenReference()
0300: .getTokenValue();
0301: } else {
0302: strElem = (Element) context
0303: .getTrustContext()
0304: .getUnAttachedSecurityTokenReference()
0305: .getTokenValue();
0306: }
0307: //TODO: remove these expensive conversions
0308: Element imported = (Element) secureMessage
0309: .getSOAPPart()
0310: .importNode(strElem, true);
0311: SecurityTokenReference str = new SecurityTokenReference(
0312: XMLUtil.convertToSoapElement(
0313: secureMessage.getSOAPPart(),
0314: (Element) imported
0315: .cloneNode(true)),
0316: false);
0317:
0318: if (tokenElem != null) {
0319: if (includeToken) {
0320: secureMessage
0321: .findOrCreateSecurityHeader()
0322: .insertHeaderBlockElement(
0323: tokenElem);
0324: nextSibling = tokenElem
0325: .getNextSibling();
0326:
0327: } else {
0328: nextSibling = null;
0329: }
0330: context.setIssuedSAMLToken(tokenElem);
0331: }
0332: keyInfo = dsigHelper.constructKeyInfo(
0333: signaturePolicy, str);
0334: SecurityUtil.updateSamlVsKeyCache(str, context,
0335: cert.getPublicKey());
0336: } else {
0337: DerivedKeyToken dkt = new DerivedKeyTokenImpl(
0338: offset, length, prfKey);
0339: signingKey = dkt.generateSymmetricKey(jceAlgo);
0340: Node[] nxtSiblingContainer = new Node[1];
0341: //NOTE: passing the proofKey here as original key
0342: String secretKeyAlg = "AES";
0343: if (algSuite != null) {
0344: secretKeyAlg = SecurityUtil
0345: .getSecretKeyAlgorithm(algSuite
0346: .getEncryptionAlgorithm());
0347: }
0348: Key originalKey = new SecretKeySpec(prfKey,
0349: secretKeyAlg);
0350: keyInfo = prepareForSymmetricKeySignature(
0351: context, keyBinding, originalKey,
0352: signaturePolicy, nxtSiblingContainer,
0353: null, dkt);
0354: nextSibling = nxtSiblingContainer[0];
0355: }
0356: } else if (PolicyTypeUtil
0357: .secureConversationTokenKeyBinding(originalKeyBinding)) {
0358:
0359: DerivedKeyToken dkt = new DerivedKeyTokenImpl(
0360: offset, length, context
0361: .getSecureConversationContext()
0362: .getProofKey());
0363: //get the signing key for signature from derivedkeyToken
0364: signingKey = dkt.generateSymmetricKey(jceAlgo);
0365: Node[] nxtSiblingContainer = new Node[1];
0366: keyInfo = prepareForSymmetricKeySignature(context,
0367: keyBinding, null, signaturePolicy,
0368: nxtSiblingContainer, null, dkt);
0369: nextSibling = nxtSiblingContainer[0];
0370: }
0371:
0372: } else if (PolicyTypeUtil.issuedTokenKeyBinding(keyBinding)) {
0373: Node[] nxtSiblingContainer = new Node[1];
0374: // look for the proof token inside the IssuedToken
0375: byte[] proofKey = context.getTrustContext()
0376: .getProofKey();
0377: if (proofKey == null) {
0378: //handle Asymmetric Issued Token
0379: X509Certificate cert = context.getTrustContext()
0380: .getRequestorCertificate();
0381: if (cert == null) {
0382: logger.log(Level.SEVERE,
0383: "WSS1328.illegal.Certificate.key.null");
0384: throw new XWSSecurityException(
0385: "Requestor Certificate and Proof Key are both null for Issued Token");
0386: }
0387: signingKey = context.getSecurityEnvironment()
0388: .getPrivateKey(
0389: context.getExtraneousProperties(),
0390: cert);
0391:
0392: //Get the IssuedToken and insert it into the message
0393: GenericToken issuedToken = (GenericToken) context
0394: .getTrustContext().getSecurityToken();
0395: Element elem = (Element) issuedToken
0396: .getTokenValue();
0397: SOAPElement tokenElem = XMLUtil
0398: .convertToSoapElement(secureMessage
0399: .getSOAPPart(), elem);
0400: //FIX for Issue 26: We need an Id to cache and MS is not setting in
0401: //some cases
0402: String tokId = tokenElem.getAttribute("Id");
0403: if ("".equals(tokId)
0404: && MessageConstants.ENCRYPTED_DATA_LNAME
0405: .equals(tokenElem.getLocalName())) {
0406: tokenElem.setAttribute("Id", secureMessage
0407: .generateId());
0408: }
0409: context.getTokenCache().put(keyBinding.getUUID(),
0410: tokenElem);
0411: IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding) keyBinding;
0412: boolean includeToken = (ikb.INCLUDE_ALWAYS
0413: .equals(ikb.getIncludeToken()) || (ikb.INCLUDE_ALWAYS_TO_RECIPIENT
0414: .equals(ikb.getIncludeToken())));
0415: Element strElem = null;
0416:
0417: if (includeToken) {
0418: strElem = (Element) context.getTrustContext()
0419: .getAttachedSecurityTokenReference()
0420: .getTokenValue();
0421: } else {
0422: strElem = (Element) context.getTrustContext()
0423: .getUnAttachedSecurityTokenReference()
0424: .getTokenValue();
0425: }
0426: //TODO: remove these expensive conversions
0427: Element imported = (Element) secureMessage
0428: .getSOAPPart().importNode(strElem, true);
0429: SecurityTokenReference str = new SecurityTokenReference(
0430: XMLUtil.convertToSoapElement(secureMessage
0431: .getSOAPPart(), (Element) imported
0432: .cloneNode(true)), false);
0433:
0434: if (tokenElem != null) {
0435: if (includeToken) {
0436: secureMessage
0437: .findOrCreateSecurityHeader()
0438: .insertHeaderBlockElement(tokenElem);
0439: nextSibling = tokenElem.getNextSibling();
0440:
0441: } else {
0442: nextSibling = null;
0443: }
0444: context.setIssuedSAMLToken(tokenElem);
0445: }
0446: keyInfo = dsigHelper.constructKeyInfo(
0447: signaturePolicy, str);
0448: SecurityUtil.updateSamlVsKeyCache(str, context,
0449: cert.getPublicKey());
0450: } else {
0451: // symmetric issued
0452: String secretKeyAlg = "AES"; // hardcoding to AES for now
0453: if (algSuite != null) {
0454: secretKeyAlg = SecurityUtil
0455: .getSecretKeyAlgorithm(algSuite
0456: .getEncryptionAlgorithm());
0457: }
0458: //TODO: assuming proofkey is a byte array in case of Trust as well
0459: signingKey = new SecretKeySpec(proofKey,
0460: secretKeyAlg);
0461: keyInfo = prepareForSymmetricKeySignature(context,
0462: keyBinding, signingKey, signaturePolicy,
0463: nxtSiblingContainer, null, null);
0464: nextSibling = nxtSiblingContainer[0];
0465: }
0466:
0467: } else if (PolicyTypeUtil
0468: .secureConversationTokenKeyBinding(keyBinding)) {
0469:
0470: //Hack to get the nextSibling node from prepareForSymmetricKeySignature
0471: Node[] nxtSiblingContainer = new Node[1];
0472: keyInfo = prepareForSymmetricKeySignature(context,
0473: keyBinding, null, signaturePolicy,
0474: nxtSiblingContainer, null, null);
0475:
0476: // look for the proof token inside the secureConversationToken
0477: String secretKeyAlg = "AES"; // hardcoding to AES for now
0478: if (algSuite != null) {
0479: secretKeyAlg = SecurityUtil
0480: .getSecretKeyAlgorithm(algSuite
0481: .getEncryptionAlgorithm());
0482: }
0483: signingKey = new SecretKeySpec(context
0484: .getSecureConversationContext().getProofKey(),
0485: secretKeyAlg);
0486: nextSibling = nxtSiblingContainer[0];
0487:
0488: } else if (PolicyTypeUtil
0489: .x509CertificateBinding(keyBinding)) {
0490:
0491: AuthenticationTokenPolicy.X509CertificateBinding certInfo = null;
0492: if (context.getX509CertificateBinding() != null) {
0493: certInfo = context.getX509CertificateBinding();
0494: context.setX509CertificateBinding(null);
0495: } else {
0496: certInfo = (AuthenticationTokenPolicy.X509CertificateBinding) keyBinding;
0497: }
0498:
0499: PrivateKeyBinding privKBinding = (PrivateKeyBinding) certInfo
0500: .getKeyBinding();
0501: signingKey = privKBinding.getPrivateKey();
0502:
0503: Node[] nxtSiblingContainer = new Node[1];
0504: keyInfo = handleX509Binding(context, signaturePolicy,
0505: certInfo, nxtSiblingContainer);
0506: nextSibling = nxtSiblingContainer[0];
0507:
0508: } else if (PolicyTypeUtil.samlTokenPolicy(keyBinding)) {
0509: // populate the policy, the handler should also add a privateKey binding for HOK
0510:
0511: AuthenticationTokenPolicy.SAMLAssertionBinding samlBinding = (AuthenticationTokenPolicy.SAMLAssertionBinding) keyBinding;
0512: PrivateKeyBinding privKBinding = (PrivateKeyBinding) samlBinding
0513: .getKeyBinding();
0514: if (privKBinding == null) {
0515: logger
0516: .log(Level.SEVERE,
0517: "WSS1329.null.privatekeybinding.SAMLPolicy");
0518: throw new XWSSecurityException(
0519: "PrivateKey binding not set for SAML Policy by CallbackHandler");
0520: }
0521:
0522: signingKey = privKBinding.getPrivateKey();
0523:
0524: if (signingKey == null) {
0525: logger.log(Level.SEVERE,
0526: "WSS1330.null.privatekey.SAMLPolicy");
0527: throw new XWSSecurityException(
0528: "PrivateKey null inside PrivateKeyBinding set for SAML Policy ");
0529: }
0530:
0531: String referenceType = samlBinding.getReferenceType();
0532: if (referenceType
0533: .equals(MessageConstants.EMBEDDED_REFERENCE_TYPE)) {
0534: logger
0535: .log(Level.SEVERE,
0536: "WSS1331.unsupported.EmbeddedReference.SAML");
0537: throw new XWSSecurityException(
0538: "Embedded Reference Type for SAML Assertions not supported yet");
0539: }
0540:
0541: String assertionId = samlBinding.getAssertionId();
0542: Element _assertion = samlBinding.getAssertion();
0543: Element _authorityBinding = samlBinding
0544: .getAuthorityBinding();
0545:
0546: if (assertionId == null) {
0547: if (_assertion == null) {
0548: logger
0549: .log(Level.SEVERE,
0550: "WSS1332.null.SAMLAssertion.SAMLAssertionId");
0551: throw new XWSSecurityException(
0552: "None of SAML Assertion, SAML Assertion Id information was set into "
0553: + " the Policy by the CallbackHandler");
0554: }
0555: if (_assertion.getAttributeNode("ID") != null) {
0556: assertionId = _assertion.getAttribute("ID");
0557: } else {
0558: assertionId = _assertion
0559: .getAttribute("AssertionID");
0560: }
0561: }
0562:
0563: SecurityTokenReference tokenRef = new SecurityTokenReference(
0564: secureMessage.getSOAPPart());
0565: String strId = samlBinding.getSTRID();
0566: if (strId == null) {
0567: strId = secureMessage.generateId();
0568: }
0569: tokenRef.setWsuId(strId);
0570: // set wsse11:TokenType to SAML1.1 or SAML2.0
0571: if (_assertion.getAttributeNode("ID") != null) {
0572: tokenRef
0573: .setTokenType(MessageConstants.WSSE_SAML_v2_0_TOKEN_TYPE);
0574: } else {
0575: tokenRef
0576: .setTokenType(MessageConstants.WSSE_SAML_v1_1_TOKEN_TYPE);
0577: }
0578:
0579: if (_authorityBinding != null) {
0580: tokenRef.setSamlAuthorityBinding(_authorityBinding,
0581: secureMessage.getSOAPPart());
0582: }
0583:
0584: if ((_assertion != null) && (_authorityBinding == null)) {
0585: //insert the SAML Assertion
0586: SamlAssertionHeaderBlock samlHeaderblock = new SamlAssertionHeaderBlock(
0587: _assertion, secureMessage.getSOAPPart());
0588: secureMessage.findOrCreateSecurityHeader()
0589: .insertHeaderBlock(samlHeaderblock);
0590: // setting ValueType of Keydentifier to SAML1.1 0r SAML2.0
0591: KeyIdentifierStrategy strat = new KeyIdentifierStrategy(
0592: assertionId);
0593: strat.insertKey(tokenRef, secureMessage);
0594: keyInfo = dsigHelper.constructKeyInfo(
0595: signaturePolicy, tokenRef);
0596:
0597: nextSibling = samlHeaderblock.getAsSoapElement()
0598: .getNextSibling();
0599: } else {
0600: nextSibling = securityHeader
0601: .getNextSiblingOfTimestamp();
0602: }
0603: } else if (PolicyTypeUtil.symmetricKeyBinding(keyBinding)) {
0604: SymmetricKeyBinding skb = null;
0605: if (context.getSymmetricKeyBinding() != null) {
0606: skb = context.getSymmetricKeyBinding();
0607: context.setSymmetricKeyBinding(null);
0608: } else {
0609: skb = (SymmetricKeyBinding) keyBinding;
0610: }
0611:
0612: // sign method is HMACSHA-1 for symmetric keys
0613: if (!skb.getKeyIdentifier().equals(
0614: MessageConstants._EMPTY)) {
0615: signingKey = skb.getSecretKey();
0616: String symmetricKeyName = skb.getKeyIdentifier();
0617:
0618: keyInfo = dsigHelper.constructKeyInfo(
0619: signaturePolicy, symmetricKeyName);
0620: nextSibling = securityHeader
0621: .getNextSiblingOfTimestamp();
0622: } else if (sendEKSHA1) {
0623: //get the signing key and EKSHA1 reference from the Subject, it was stored from the incoming message
0624: String ekSha1Ref = getEKSHA1Ref(context);
0625: signingKey = skb.getSecretKey();
0626:
0627: SecurityTokenReference secTokenRef = new SecurityTokenReference(
0628: secureMessage.getSOAPPart());
0629:
0630: EncryptedKeySHA1Identifier refElem = new EncryptedKeySHA1Identifier(
0631: secureMessage.getSOAPPart());
0632: refElem.setReferenceValue(ekSha1Ref);
0633: secTokenRef.setReference(refElem);
0634:
0635: //set the wsse11:TokenType attribute as required by WSS 1.1
0636: //secTokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
0637:
0638: keyInfo = dsigHelper.constructKeyInfo(
0639: signaturePolicy, secTokenRef);
0640: nextSibling = securityHeader
0641: .getNextSiblingOfTimestamp();
0642:
0643: //TODO: the below condition is always true
0644: } else if (wss11Sender || wss10) {
0645: signingKey = skb.getSecretKey();
0646:
0647: AuthenticationTokenPolicy.X509CertificateBinding x509Binding = null;
0648: X509Certificate cert = null;
0649: if (!skb.getCertAlias().equals(
0650: MessageConstants._EMPTY)) {
0651: x509Binding = new AuthenticationTokenPolicy.X509CertificateBinding();
0652: x509Binding.newPrivateKeyBinding();
0653: x509Binding.setCertificateIdentifier(skb
0654: .getCertAlias());
0655: cert = context
0656: .getSecurityEnvironment()
0657: .getCertificate(
0658: context
0659: .getExtraneousProperties(),
0660: x509Binding
0661: .getCertificateIdentifier(),
0662: false);
0663: x509Binding.setX509Certificate(cert);
0664:
0665: x509Binding.setReferenceType("Direct");
0666: } else if (context.getX509CertificateBinding() != null) {
0667: x509Binding = context
0668: .getX509CertificateBinding();
0669: context.setX509CertificateBinding(null);
0670: cert = x509Binding.getX509Certificate();
0671: }
0672:
0673: HashMap tokenCache = context.getTokenCache();
0674: HashMap insertedX509Cache = context
0675: .getInsertedX509Cache();
0676: String x509id = x509Binding.getUUID();
0677: if (x509id == null || x509id.equals("")) {
0678: x509id = secureMessage.generateId();
0679: }
0680:
0681: SecurityUtil.checkIncludeTokenPolicy(context,
0682: x509Binding, x509id);
0683:
0684: String keyEncAlgo = XMLCipher.RSA_v1dot5; //<--Harcoding of Algo
0685: String tmp = null;
0686: if (algSuite != null) {
0687: tmp = algSuite.getAsymmetricKeyAlgorithm();
0688: }
0689: if (tmp != null && !"".equals(tmp)) {
0690: keyEncAlgo = tmp;
0691: }
0692: String referenceType = x509Binding
0693: .getReferenceType();
0694: if (referenceType.equals("Identifier")
0695: && x509Binding.getValueType().equals(
0696: MessageConstants.X509v1_NS)) {
0697: logger
0698: .log(Level.SEVERE,
0699: "WSS1333.unsupported.keyidentifer.X509v1");
0700: throw new XWSSecurityException(
0701: "Key Identifier strategy in X509v1 is not supported");
0702: }
0703: KeyInfoStrategy strategy = KeyInfoStrategy
0704: .getInstance(referenceType);
0705: KeyInfoHeaderBlock keyInfoBlock = null;
0706: secureMessage = context.getSecurableSoapMessage();
0707: dsigHelper = WSSPolicyConsumerImpl.getInstance();
0708:
0709: //Check to see if same x509 token used for Signature and Encryption
0710: X509SecurityToken token = null;
0711: cert = x509Binding.getX509Certificate();
0712: String x509TokenId = x509Binding.getUUID();
0713: //String x509TokenId = x509Binding.getPolicyToken().getTokenId();
0714: boolean tokenInserted = false;
0715:
0716: //insert x509 token in tokencache always irrespective of reference type
0717: if (x509TokenId == null || x509TokenId.equals("")) {
0718: x509TokenId = secureMessage.generateId();
0719: }
0720:
0721: token = (X509SecurityToken) tokenCache
0722: .get(x509TokenId);
0723:
0724: //reference type adjustment in checkIncludePolicy might
0725: // have inserted x509
0726: X509SecurityToken insertedx509 = (X509SecurityToken) context
0727: .getInsertedX509Cache().get(x509TokenId);
0728:
0729: if (token == null) {
0730: String valueType = x509Binding.getValueType();
0731: if (valueType == null || valueType.equals("")) {
0732: //default valueType for X509 as v3
0733: valueType = MessageConstants.X509v3_NS;
0734: }
0735: token = new X509SecurityToken(secureMessage
0736: .getSOAPPart(), cert, x509TokenId,
0737: valueType);
0738: tokenCache.put(x509TokenId, token);
0739: } else {
0740: tokenInserted = true;
0741: }
0742: String id = null;
0743: HashMap ekCache = context.getEncryptedKeyCache();
0744: if (!tokenInserted) {
0745: context.setCurrentSecret(signingKey);
0746: //Store SymmetricKey generated in ProcessingContext
0747: context.setExtraneousProperty("SecretKey",
0748: signingKey);
0749: keyInfoBlock = new KeyInfoHeaderBlock(
0750: secureMessage.getSOAPPart());
0751: strategy.setCertificate(cert);
0752: strategy.insertKey(keyInfoBlock, secureMessage,
0753: x509TokenId);
0754: com.sun.org.apache.xml.internal.security.keys.KeyInfo apacheKeyInfo = keyInfoBlock
0755: .getKeyInfo();
0756: //create an encrypted Key
0757: EncryptedKey encryptedKey = null;
0758: XMLCipher keyEncryptor = null;
0759: try {
0760: keyEncryptor = XMLCipher
0761: .getInstance(keyEncAlgo);
0762: keyEncryptor.init(XMLCipher.WRAP_MODE, cert
0763: .getPublicKey());
0764: if (keyEncryptor != null) {
0765: encryptedKey = keyEncryptor.encryptKey(
0766: secureMessage.getSOAPPart(),
0767: signingKey);
0768: }
0769: } catch (Exception e) {
0770: logger
0771: .log(Level.SEVERE,
0772: "WSS1334.error.creating.encryptedkey");
0773: throw new XWSSecurityException(e);
0774: }
0775: id = secureMessage.generateId();
0776: encryptedKey.setId(id);
0777: ekCache.put(x509TokenId, id);
0778: // set its KeyInfo
0779: encryptedKey.setKeyInfo(apacheKeyInfo);
0780:
0781: // insert the EK into the SOAPMessage
0782: SOAPElement se = (SOAPElement) keyEncryptor
0783: .martial(encryptedKey);
0784: if (insertedx509 == null) {
0785: secureMessage.findOrCreateSecurityHeader()
0786: .insertHeaderBlockElement(se);
0787: } else {
0788: secureMessage.findOrCreateSecurityHeader()
0789: .insertBefore(
0790: se,
0791: insertedx509
0792: .getNextSibling());
0793: }
0794:
0795: //store EKSHA1 of KeyValue contents in context
0796: Element cipherData = (Element) se
0797: .getChildElements(
0798: new QName(
0799: MessageConstants.XENC_NS,
0800: "CipherData",
0801: MessageConstants.XENC_PREFIX))
0802: .next();
0803: String cipherValue = cipherData
0804: .getElementsByTagNameNS(
0805: MessageConstants.XENC_NS,
0806: "CipherValue").item(0)
0807: .getTextContent();
0808: byte[] decodedCipher = Base64
0809: .decode(cipherValue);
0810: byte[] ekSha1 = MessageDigest.getInstance(
0811: "SHA-1").digest(decodedCipher);
0812: String encEkSha1 = Base64.encode(ekSha1);
0813: context.setExtraneousProperty(
0814: "EncryptedKeySHA1", encEkSha1);
0815: nextSibling = se.getNextSibling();
0816: } else {
0817:
0818: id = (String) ekCache.get(x509TokenId);
0819: signingKey = context.getCurrentSecret();
0820: nextSibling = secureMessage.getElementById(id)
0821: .getNextSibling();
0822: }
0823: //insert the token as the first child in SecurityHeader -- if same token was not already
0824: // inserted by Encryption
0825: if (MessageConstants.DIRECT_REFERENCE_TYPE
0826: .equals(referenceType)
0827: && insertedx509 == null) {
0828: secureMessage.findOrCreateSecurityHeader()
0829: .insertHeaderBlock(token);
0830: insertedX509Cache.put(x509TokenId, token);
0831: }
0832:
0833: //STR for the KeyInfo of signature
0834: SecurityTokenReference secTokenRef = new SecurityTokenReference(
0835: secureMessage.getSOAPPart());
0836: DirectReference reference = new DirectReference();
0837: String strId = x509Binding.getSTRID();
0838: if (strId == null) {
0839: strId = secureMessage.generateId();
0840: }
0841: secTokenRef.setWsuId(strId);
0842: //TODO: PLUGFEST Microsoft setting EK on reference inseatd of STR
0843: //secTokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
0844: //set id of encrypted key
0845: reference.setURI("#" + id);
0846: reference
0847: .setValueType(MessageConstants.EncryptedKey_NS);
0848: secTokenRef.setReference(reference);
0849: keyInfo = dsigHelper.constructKeyInfo(
0850: signaturePolicy, secTokenRef);
0851:
0852: }
0853: } else {
0854: logger
0855: .log(Level.SEVERE,
0856: "WSS1335.unsupported.keybinding.signaturepolicy");
0857: throw new XWSSecurityException(
0858: "Unsupported Key Binding for SignaturePolicy");
0859: }
0860:
0861: // Put UsernameToken above signature
0862: NodeList nodeList = securityHeader.getElementsByTagNameNS(
0863: MessageConstants.WSSE_NS,
0864: MessageConstants.USERNAME_TOKEN_LNAME);
0865: if (nodeList != null && nodeList.getLength() > 0) {
0866: nextSibling = nodeList.item(0).getNextSibling();
0867: }
0868:
0869: // if currentReflist is non-null it means we are doing E before S
0870: Node refList = context.getCurrentRefList();
0871: if (refList != null) {
0872: nextSibling = refList;
0873: //reset it after using once to null.
0874: context.setCurrentReferenceList(null);
0875: }
0876:
0877: if (featureBinding.isEndorsingSignature()) {
0878: nextSibling = securityHeader.getLastChild()
0879: .getNextSibling();
0880: }
0881:
0882: SignedInfo signedInfo = WSSPolicyConsumerImpl.getInstance()
0883: .constructSignedInfo(context);
0884: DOMSignContext signContext = null;
0885: if (nextSibling == null) {
0886: signContext = new DOMSignContext(signingKey,
0887: securityHeader.getAsSoapElement());//firstChildElement);
0888: } else {
0889: signContext = new DOMSignContext(signingKey,
0890: securityHeader.getAsSoapElement(), nextSibling);
0891: }
0892: signContext.setURIDereferencer(DSigResolver.getInstance());
0893: XMLSignature signature = dsigHelper.constructSignature(
0894: signedInfo, keyInfo, signaturePolicy.getUUID());
0895: signContext.put(MessageConstants.WSS_PROCESSING_CONTEXT,
0896: context);
0897: signContext.putNamespacePrefix(MessageConstants.DSIG_NS,
0898: MessageConstants.DSIG_PREFIX);
0899: // XMLUtils.circumventBug2650(context.getSecurableSoapMessage().getSOAPPart());
0900: signature.sign(signContext);
0901:
0902: //For SignatureConfirmation
0903: List scList = (ArrayList) context
0904: .getExtraneousProperty("SignatureConfirmation");
0905: if (scList != null) {
0906: scList.add(Base64.encode(signature.getSignatureValue()
0907: .getValue()));
0908: }
0909: //End SignatureConfirmation specific code
0910:
0911: } catch (XWSSecurityException xe) {
0912: logger.log(Level.SEVERE, "WSS1316.sign.failed", xe);
0913: throw xe;
0914: } catch (Exception ex) {
0915: logger.log(Level.SEVERE, "WSS1316.sign.failed", ex);
0916: throw new XWSSecurityException(ex);
0917: }
0918: return 0;
0919: }
0920:
0921: /**
0922: *
0923: * @param context FilterProcessingContext
0924: * @throws XWSSecurityException
0925: * @return errorCode.
0926: */
0927: public static int verify(FilterProcessingContext context)
0928: throws XWSSecurityException {
0929: try {
0930: WSSPolicyConsumerImpl dsigUtil = WSSPolicyConsumerImpl
0931: .getInstance();
0932: ;
0933: SOAPElement signElement = context.getSecurableSoapMessage()
0934: .findSecurityHeader().getCurrentHeaderElement();
0935: if (signElement == null
0936: || signElement.getLocalName() == null
0937: || !"Signature".equals(signElement.getLocalName())) {
0938: //throw new XWSSecurityException("No Signature Element found");
0939: String localName = signElement != null ? signElement
0940: .getLocalName() : "";
0941: context.setPVE(new PolicyViolationException(
0942: "Expected Signature Element as per receiver requirements, found "
0943: + localName));
0944: context.isPrimaryPolicyViolation(true);
0945: return 0;
0946: }
0947: DOMValidateContext validationContext = new DOMValidateContext(
0948: KeySelectorImpl.getInstance(), signElement);
0949: XMLSignatureFactory signatureFactory = WSSPolicyConsumerImpl
0950: .getInstance().getSignatureFactory();
0951: // unmarshal the XMLSignature
0952: XMLSignature signature = signatureFactory
0953: .unmarshalXMLSignature(validationContext);
0954:
0955: //For SignatureConfirmation
0956: List scList = (ArrayList) context
0957: .getExtraneousProperty("receivedSignValues");
0958: if (scList != null) {
0959: scList.add(Base64.encode(signature.getSignatureValue()
0960: .getValue()));
0961: }
0962: //End SignatureConfirmation specific code
0963:
0964: validationContext.setURIDereferencer(DSigResolver
0965: .getInstance());
0966: // Validate the XMLSignature (generated above)
0967: validationContext.put(
0968: MessageConstants.WSS_PROCESSING_CONTEXT, context);
0969: SignaturePolicy currentMessagePolicy = null;
0970: if (context.getMode() == FilterProcessingContext.ADHOC
0971: || context.getMode() == FilterProcessingContext.POSTHOC) {
0972: currentMessagePolicy = new SignaturePolicy();
0973: context.setInferredPolicy(currentMessagePolicy);
0974: } else if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
0975: currentMessagePolicy = new SignaturePolicy();
0976: context.getInferredSecurityPolicy().append(
0977: currentMessagePolicy);
0978: }
0979:
0980: // XMLUtils.circumventBug2650(context.getSecurableSoapMessage().getSOAPPart());
0981: boolean coreValidity = signature
0982: .validate(validationContext);
0983: SecurityPolicy securityPolicy = context.getSecurityPolicy();
0984:
0985: boolean isBSP = false;
0986: if (securityPolicy != null) {
0987: if (PolicyTypeUtil.messagePolicy(securityPolicy)) {
0988: isBSP = ((MessagePolicy) securityPolicy).isBSP();
0989: } else {
0990: isBSP = ((WSSPolicy) securityPolicy).isBSP();
0991: }
0992: }
0993:
0994: // Check core validation status
0995: if (coreValidity == false) {
0996:
0997: if (logger.isLoggable(Level.FINEST)) {
0998: logger.log(Level.FINEST,
0999: "Signature failed core validation");
1000: boolean sv = signature.getSignatureValue()
1001: .validate(validationContext);
1002: logger.log(Level.FINEST,
1003: "Signature validation status: " + sv);
1004: // check the validation status of each Reference
1005: Iterator i = signature.getSignedInfo()
1006: .getReferences().iterator();
1007: for (int j = 0; i.hasNext(); j++) {
1008: Reference ref = (Reference) i.next();
1009: logger.log(Level.FINEST, "Reference ID "
1010: + ref.getId());
1011: logger.log(Level.FINEST, "Reference URI "
1012: + ref.getURI());
1013: boolean refValid = ref
1014: .validate(validationContext);
1015: logger.log(Level.FINEST, "Reference[" + j
1016: + "] validity status: " + refValid);
1017: }
1018: }
1019: logger.log(Level.SEVERE,
1020: "WSS1315.signature.verification.failed");
1021: XWSSecurityException xwsse = new XWSSecurityException(
1022: "Signature verification failed");
1023: throw SecurableSoapMessage.newSOAPFaultException(
1024: MessageConstants.WSSE_FAILED_CHECK,
1025: "Signature verification failed ", xwsse);
1026: } else {
1027: if (logger.isLoggable(Level.FINEST)) {
1028: logger.log(Level.FINE,
1029: "Signature Passed Core Validation");
1030: }
1031: SignedInfo signInfo = signature.getSignedInfo();
1032: if (isBSP) {
1033: Iterator i = signInfo.getReferences().iterator();
1034: for (int j = 0; i.hasNext(); j++) {
1035: Reference reference = (Reference) i.next();
1036:
1037: Iterator t = reference.getTransforms()
1038: .iterator();
1039: for (int index = 0; t.hasNext(); index++) {
1040: Transform transform = (Transform) t.next();
1041: if (Transform.ENVELOPED.equals(transform
1042: .getAlgorithm())) {
1043: logger
1044: .log(Level.SEVERE,
1045: "WSS1336.illegal.envelopedsignature");
1046: throw new XWSSecurityException(
1047: "Enveloped signatures not permitted by BSP");
1048: }
1049: if (MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS
1050: .equals(transform.getAlgorithm())) {
1051: //check the inclusiveprefix list is not empty
1052: if (transform.getParameterSpec() != null) {
1053: ExcC14NParameterSpec spec = (ExcC14NParameterSpec) transform
1054: .getParameterSpec();
1055: if (spec.getPrefixList().isEmpty())
1056: logger
1057: .log(Level.SEVERE,
1058: "WSS1337.invalid.Emptyprefixlist");
1059: throw new XWSSecurityException(
1060: "Prefix List cannot be empty: violation of BSP 5407");
1061: }
1062: }
1063: }
1064: }
1065: }
1066: if (context.getMode() == FilterProcessingContext.POSTHOC) {
1067: //TODO: handle SAML KeyBinding here
1068: MessagePolicy policy = (MessagePolicy) context
1069: .getSecurityPolicy();
1070: dsigUtil.constructSignaturePolicy(signInfo, policy
1071: .isBSP(), currentMessagePolicy);
1072: policy.append(currentMessagePolicy);
1073: }
1074:
1075: if (context.getMode() == FilterProcessingContext.ADHOC) {
1076: //throws Exception for now , need to throw only
1077: //appropriate errors.
1078: //Next step do it more efficiently.
1079: verifyRequirements(context, signature,
1080: validationContext);
1081: SignaturePolicy policy = (SignaturePolicy) context
1082: .getSecurityPolicy();
1083: dsigUtil.constructSignaturePolicy(signInfo, policy
1084: .isBSP(), currentMessagePolicy);
1085: SignaturePolicyVerifier spv = new SignaturePolicyVerifier(
1086: context);
1087: spv.verifyPolicy(policy, currentMessagePolicy);
1088:
1089: if (logger.isLoggable(Level.FINEST)) {
1090: logger.log(Level.FINE,
1091: "Reciever Requirements are met");
1092: }
1093: }
1094:
1095: if (context.getMode() == FilterProcessingContext.WSDL_POLICY) {
1096: dsigUtil.constructSignaturePolicy(signInfo,
1097: currentMessagePolicy, context
1098: .getSecurableSoapMessage());
1099: }
1100: }
1101: } catch (XWSSecurityException xwe) {
1102: logger.log(Level.SEVERE, "WSS1338.error.verify");
1103: throw xwe;
1104: } catch (XMLSignatureException xse) {
1105:
1106: Throwable t1 = xse.getCause();
1107:
1108: if (t1 == null) {
1109: logger.log(Level.SEVERE, "WSS1338.error.verify");
1110: throw new XWSSecurityException(xse);
1111: }
1112: if (t1 instanceof KeySelectorException
1113: || t1 instanceof URIReferenceException) {
1114:
1115: Throwable t2 = t1.getCause();
1116:
1117: if (t2 != null && t2 instanceof WssSoapFaultException) {
1118: logger.log(Level.SEVERE, "WSS1338.error.verify");
1119: throw (WssSoapFaultException) t2;
1120: } else {
1121: logger.log(Level.SEVERE, "WSS1338.error.verify");
1122: throw new XWSSecurityException((Exception) t1);
1123: }
1124: }
1125: logger.log(Level.SEVERE, "WSS1338.error.verify");
1126: throw new XWSSecurityException(xse);
1127:
1128: } catch (Exception ex) {
1129: logger.log(Level.SEVERE, "WSS1338.error.verify");
1130: throw new XWSSecurityException(ex);
1131: } finally {
1132: context.setInferredPolicy(null);
1133: }
1134: return 0;
1135: }
1136:
1137: /**
1138: *
1139: * @param context
1140: * @param signature
1141: * @param validationContext
1142: * @throws Exception
1143: */
1144: public static void verifyRequirements(
1145: FilterProcessingContext context, XMLSignature signature,
1146: DOMValidateContext validationContext) throws Exception {
1147:
1148: SignaturePolicy policy = (SignaturePolicy) context
1149: .getSecurityPolicy();
1150: SignaturePolicy.FeatureBinding featureBinding = (SignaturePolicy.FeatureBinding) policy
1151: .getFeatureBinding();
1152: WSSPolicyConsumerImpl dsigUtil = WSSPolicyConsumerImpl
1153: .getInstance();
1154: ArrayList targets = featureBinding.getTargetBindings();
1155: if (targets == null || targets.size() == 0) {
1156: return;
1157: }
1158: SignedInfo signedInfo = signature.getSignedInfo();
1159: List signedReferences = signedInfo.getReferences();
1160: Iterator sr = signedReferences.listIterator();
1161: ArrayList signedDataList = new ArrayList();
1162: ArrayList signedReferenceList = new ArrayList();
1163: while (sr.hasNext()) {
1164: Reference reference = (Reference) sr.next();
1165: Data tmpObj = getData(reference, validationContext);
1166: signedDataList.add(new DataWrapper(tmpObj));
1167: //TODO:Should use cached data from References of already validated
1168: //messages when sean provides on . For now get the Data again.
1169: signedReferenceList.add(reference);
1170: }
1171:
1172: ArrayList optionalReqList = new ArrayList();
1173: ArrayList requiredDataList = new ArrayList();
1174: ArrayList requiredReferenceList = new ArrayList();
1175: ArrayList optionalDataList = new ArrayList();
1176: ArrayList optionalReferenceList = new ArrayList();
1177: //It would have been better If I had optional list
1178: //seperated
1179:
1180: Iterator targetItr = targets.iterator();
1181: SecurableSoapMessage secureMessage = context
1182: .getSecurableSoapMessage();
1183: while (targetItr.hasNext()) {
1184: SignatureTarget signatureTarget = (SignatureTarget) targetItr
1185: .next();
1186: boolean requiredTarget = signatureTarget.getEnforce();
1187: List referenceList = null;
1188: try {
1189: if (requiredTarget) {
1190: referenceList = dsigUtil.generateReferenceList(
1191: Collections.singletonList(signatureTarget),
1192: secureMessage, context, true,
1193: featureBinding.isEndorsingSignature());
1194: } else {
1195: //dont resolve it now.
1196: optionalReqList.add(signatureTarget);
1197: }
1198: } catch (Exception ex) {
1199: logger.log(Level.SEVERE, "WSS1302.reflist_error", ex);
1200: if (requiredTarget) {
1201: logger.log(Level.SEVERE,
1202: "WSS1339.invalid.ReceiverRequirements");
1203: throw new XWSSecurityException(
1204: "Receiver requirement for SignatureTarget "
1205: + signatureTarget.getValue()
1206: + " is not met");
1207: }
1208: //log
1209: }
1210: if (!requiredTarget) {
1211: continue;
1212: }
1213: if (referenceList.size() <= 0) {
1214: logger.log(Level.SEVERE,
1215: "WSS1339.invalid.ReceiverRequirements");
1216: throw new XWSSecurityException(
1217: "Receiver requirement for SignatureTarget "
1218: + signatureTarget.getValue()
1219: + " is not met");
1220: }
1221: boolean allRef = false;
1222: //Verify all attachments are signed. || all header elements are signed
1223: /* if(signatureTarget.getValue().startsWith("cid:*") || signatureTarget.getValue().equals(SignatureTarget.ALL_MESSAGE_HEADERS)){
1224: allRef = true;
1225: }*/
1226: for (int i = 0; i < referenceList.size(); i++) {
1227: Reference reference = (Reference) referenceList.get(i);
1228: Data data = null;
1229: try {
1230: data = getData(reference, validationContext);
1231: if (requiredTarget && data != null) {
1232: DataWrapper tmpObj = new DataWrapper(data);
1233: tmpObj.setTarget(signatureTarget);
1234: //It would still have cid:*
1235: requiredDataList.add(tmpObj);
1236: requiredReferenceList.add(reference);
1237: }
1238: } catch (Exception ex) {
1239: if (requiredTarget) {
1240: logger.log(Level.SEVERE,
1241: "WSS1339.invalid.ReceiverRequirements");
1242: throw new XWSSecurityException(
1243: "Receiver requirement for SignatureTarget "
1244: + signatureTarget.getValue()
1245: + " is not met");
1246: }
1247: }
1248: /*if(!allRef){
1249: break;
1250: }*/
1251: }
1252: }
1253:
1254: if (optionalReqList.size() == 0
1255: && requiredReferenceList.size() != signedReferenceList
1256: .size()) {
1257: logger.log(Level.SEVERE,
1258: "WSS1340.illegal.unmatched.NoofTargets");
1259: throw new XWSSecurityException(
1260: "Number of Targets in the message"
1261: + " dont match number of Targets in receiver requirements");
1262: }
1263:
1264: if (requiredDataList.size() == 0) {
1265: if (logger.isLoggable(Level.FINER)) {
1266: logger
1267: .log(Level.FINER,
1268: "No mandatory receiver requirements were provided");
1269: }
1270: return;
1271: }
1272:
1273: for (int i = 0; i < requiredDataList.size(); i++) {
1274: DataWrapper rData = (DataWrapper) requiredDataList.get(i);
1275: boolean found = false;
1276: for (int j = 0; j < signedDataList.size(); j++) {
1277: DataWrapper sData = null;
1278: sData = (DataWrapper) signedDataList.get(j);
1279: if (isEqual(rData, sData,
1280: (Reference) requiredReferenceList.get(i),
1281: (Reference) signedReferenceList.get(j))) {
1282: signedDataList.remove(j);
1283: signedReferenceList.remove(j);
1284: found = true;
1285: break;
1286: }
1287: }
1288: if (!found) {
1289: //Reference st = (Reference)requiredReferenceList.get(i);
1290: String uri = rData.getTarget().getValue();
1291: String type = rData.getTarget().getType();
1292: logger.log(Level.SEVERE,
1293: "WSS1341.illegal.unmatched.Type.Uri");
1294: throw new XWSSecurityException(
1295: "Receiver requirement for SignatureTarget "
1296: + "having " + type + " type and value "
1297: + uri + " is not met");
1298: }
1299: }
1300:
1301: if (signedDataList.size() == 0) {
1302: if (logger.isLoggable(Level.FINEST)) {
1303: logger.log(Level.FINEST,
1304: "All receiver requirements are met");
1305: }
1306: return;
1307: } else {
1308: List referenceList = null;
1309:
1310: //Resolve All optional references if any
1311: for (int i = 0; i < optionalReqList.size(); i++) {
1312: SignatureTarget signatureTarget = (SignatureTarget) optionalReqList
1313: .get(i);
1314: try {
1315: referenceList = null;
1316: referenceList = dsigUtil.generateReferenceList(
1317: Collections.singletonList(signatureTarget),
1318: secureMessage, context, true,
1319: featureBinding.isEndorsingSignature());
1320: } catch (Exception ex) {
1321: if (logger.isLoggable(Level.FINE)) {
1322: logger
1323: .log(
1324: Level.FINE,
1325: "Optional Target not found in the message ",
1326: ex);
1327: }
1328: }
1329: if (referenceList == null || referenceList.size() <= 0) {
1330: continue;
1331: }
1332: Reference reference = (Reference) referenceList.get(0);
1333: Data data = null;
1334: try {
1335: data = getData(reference, validationContext);
1336: } catch (Exception ex) {
1337: //log
1338: }
1339: if (data != null) {
1340: DataWrapper tmpObj = new DataWrapper(data);
1341: tmpObj.setTarget(signatureTarget);
1342: optionalDataList.add(tmpObj);
1343: optionalReferenceList.add(reference);
1344: }
1345: }
1346:
1347: for (int i = 0; i < signedDataList.size(); i++) {
1348: DataWrapper sData = (DataWrapper) signedDataList.get(i);
1349: DataWrapper oData = null;
1350: boolean found = false;
1351:
1352: for (int j = 0; j < optionalDataList.size(); j++) {
1353: oData = (DataWrapper) optionalDataList.get(j);
1354:
1355: if (isEqual(oData, sData,
1356: (Reference) optionalReferenceList.get(j),
1357: (Reference) signedReferenceList.get(i))) {
1358: optionalDataList.remove(j);
1359: optionalReferenceList.remove(j);
1360: found = true;
1361: break;
1362: }
1363: }
1364:
1365: if (!found) {
1366: Reference st = (Reference) signedReferenceList
1367: .get(i);
1368: logger.log(Level.SEVERE,
1369: "WSS1341.illegal.unmatched.Type.Uri");
1370: throw new XWSSecurityException(
1371: "SignatureTarget in the message "
1372: + "with URI "
1373: + st.getURI()
1374: + " has not met receiver requirements");
1375: }
1376: }
1377:
1378: if (logger.isLoggable(Level.FINEST)) {
1379: logger.log(Level.FINEST,
1380: "All receiver requirements are met");
1381: }
1382: }
1383: }
1384:
1385: private static boolean isEqual(DataWrapper data1,
1386: DataWrapper data2, Reference ref1, Reference ref2)
1387: throws XWSSecurityException {
1388: if (data1.isNodesetData() && data2.isNodesetData()) {
1389: NodeSetData ns1 = (NodeSetData) (data1.getData());
1390: NodeSetData ns2 = (NodeSetData) (data2.getData());
1391: //Fix for Issue#5 back porting from XWSS_2_0
1392: Node nsd1Root = null;
1393: Node nsd2Root = null;
1394:
1395: if (ns1 instanceof org.jcp.xml.dsig.internal.dom.DOMSubTreeData) {
1396: nsd1Root = ((org.jcp.xml.dsig.internal.dom.DOMSubTreeData) ns1)
1397: .getRoot();
1398: }
1399:
1400: if (ns2 instanceof org.jcp.xml.dsig.internal.dom.DOMSubTreeData) {
1401: nsd2Root = ((org.jcp.xml.dsig.internal.dom.DOMSubTreeData) ns2)
1402: .getRoot();
1403: }
1404:
1405: if (nsd1Root != null && nsd2Root != null) {
1406: if (nsd1Root.isSameNode(nsd2Root)
1407: || nsd1Root.isEqualNode(nsd2Root)) {
1408: return true;
1409: }
1410: }
1411: return false;
1412: /*
1413: Iterator itr1 = ns1.iterator();
1414: Iterator itr2 = ns2.iterator();
1415: //based of property set we can reduce checking all the
1416: //nodes we can check first and last node and if
1417: //possible parent and sibling
1418: while(itr1.hasNext() && itr2.hasNext()){
1419: Node node1 = (Node)itr1.next();
1420: Node node2 = (Node)itr2.next();
1421: if(!node1.isSameNode(node2)){
1422: if(MessageConstants.debug){
1423: logger.log(Level.FINEST, "Debug is Same Node returned false");
1424: }
1425: if(!node1.isEqualNode(node2)){
1426: if(MessageConstants.debug){
1427: logger.log(Level.FINEST, "Bail out");
1428: }
1429: return false;
1430: }
1431: }
1432: }
1433:
1434: if(itr1.hasNext() || itr2.hasNext()){
1435: return false;
1436: }
1437: return true;
1438: */
1439: } else if (data1.isOctectData() && data2.isOctectData()) {
1440: OctetStreamData osd1 = (OctetStreamData) data1.getData();
1441: OctetStreamData osd2 = (OctetStreamData) data2.getData();
1442: InputStream stream1 = (InputStream) osd1.getOctetStream();
1443: InputStream stream2 = (InputStream) osd2.getOctetStream();
1444: byte[] b1 = new byte[128];
1445: byte[] b2 = new byte[128];
1446: while (true) {
1447: int len1 = 0;
1448: int len2 = 0;
1449: try {
1450: len1 = stream1.read(b1);
1451: len2 = stream2.read(b2);
1452: } catch (IOException ioEx) {
1453: if (logger.isLoggable(Level.FINEST)) {
1454: logger.log(Level.FINEST, "Error occurred while"
1455: + "comparing OctetStreamData objects "
1456: + ioEx.getMessage());
1457: }
1458: return false;
1459: }
1460: if (len1 == -1 && len2 == -1) {
1461: break;
1462: }
1463: if (len1 != len2) {
1464: return false;
1465: } else {
1466: for (int i = 0; i < len1; i++) {
1467: if (b1[i] != b2[i])
1468: return false;
1469: }
1470: }
1471: }
1472: return true;
1473: } else if (data1.isAttachmentData() && data2.isAttachmentData()) {
1474: AttachmentData ad1 = (AttachmentData) data1.getData();
1475: AttachmentData ad2 = (AttachmentData) data2.getData();
1476: String uriOne = ad1.getAttachmentPart().getContentId();
1477: String uriTwo = ad2.getAttachmentPart().getContentId();
1478: if (uriOne != null && uriOne.equals(uriTwo)) {
1479: return isTransformsEqual(ref1, ref2);
1480: } else {
1481: return false;
1482: }
1483: }
1484: return false;
1485: }
1486:
1487: private static boolean isTransformsEqual(Reference ref1,
1488: Reference ref2) throws XWSSecurityException {
1489: List tList1 = ref1.getTransforms();
1490:
1491: List tList2 = ref2.getTransforms();
1492: if (tList1.size() != tList2.size()) {
1493: logger.log(Level.SEVERE,
1494: "WSS1342.illegal.unmatched.transforms");
1495: throw new XWSSecurityException(
1496: "Receiver Requirements for the transforms are not met");
1497: //return false;
1498: } else {
1499: int i = 0;
1500: while (i < tList1.size()) {
1501: Transform tr1 = (Transform) tList1.get(i);
1502: Transform tr2 = (Transform) tList2.get(i);
1503:
1504: String alg1 = tr1.getAlgorithm();
1505: String alg2 = tr2.getAlgorithm();
1506: i++;
1507: if (alg1 == alg2 || (alg1 != null && alg1.equals(alg2))) {
1508: continue;
1509: } else {
1510: logger.log(Level.SEVERE,
1511: "WSS1342.illegal.unmatched.transforms");
1512: throw new XWSSecurityException(
1513: "Receiver Requirements for the transforms are not met");
1514: //return false;
1515: }
1516:
1517: }
1518: }
1519: return true;
1520: }
1521:
1522: private static Data getData(Reference reference,
1523: DOMValidateContext context) throws Exception {
1524:
1525: final String uri = reference.getURI();
1526: URIReference uriRef = new URIReference() {
1527: public String getURI() {
1528: return uri;
1529: }
1530:
1531: public String getType() {
1532: return null;
1533: }
1534: };
1535: Data inputData = DSigResolver.getInstance().dereference(uriRef,
1536: context);
1537: if (inputData instanceof AttachmentData) {
1538: return inputData;
1539: }
1540: List transformList = reference.getTransforms();
1541: Iterator itr = transformList.iterator();
1542: while (itr.hasNext()) {
1543: Transform transform = (Transform) itr.next();
1544: inputData = getData(transform, inputData, context);
1545: }
1546: return inputData;
1547: }
1548:
1549: private static Data getData(Transform transform, Data inputData,
1550: DOMValidateContext context) throws Exception {
1551: String transformAlgo = transform.getAlgorithm();
1552: if (transformAlgo == Transform.XPATH
1553: || transformAlgo == Transform.XPATH2
1554: || transformAlgo == Transform.XSLT) {
1555: TransformService transformImpl = TransformService
1556: .getInstance(transformAlgo, "DOM");
1557: TransformParameterSpec transformParams = null;
1558: //transformParams = transform.getParamter();
1559: transformParams = (TransformParameterSpec) transform
1560: .getParameterSpec();
1561: transformImpl.init(transformParams);
1562: return transformImpl.transform(inputData, context);
1563: } else {
1564: //handle all other transforms based on flag set on processing context.
1565: //flag =STRICT_VERIFICATION {true,false}
1566: }
1567: return inputData;
1568: }
1569:
1570: /**
1571: *
1572: * @param signElement
1573: * @param context
1574: * @throws XWSSecurityException
1575: * @return
1576: */
1577: public static boolean verifySignature(Element signElement,
1578: FilterProcessingContext context)
1579: throws XWSSecurityException {
1580: try {
1581:
1582: DOMValidateContext validationContext = new DOMValidateContext(
1583: KeySelectorImpl.getInstance(), signElement);
1584: XMLSignatureFactory signatureFactory = WSSPolicyConsumerImpl
1585: .getInstance().getSignatureFactory();
1586: // unmarshal the XMLSignature
1587: XMLSignature signature = signatureFactory
1588: .unmarshalXMLSignature(validationContext);
1589: validationContext.setURIDereferencer(DSigResolver
1590: .getInstance());
1591: // Validate the XMLSignature (generated above)
1592: validationContext.put(
1593: MessageConstants.WSS_PROCESSING_CONTEXT, context);
1594: boolean coreValidity = signature
1595: .validate(validationContext);
1596: if (coreValidity == false) {
1597:
1598: if (logger.isLoggable(Level.FINEST)) {
1599: logger.log(Level.FINEST,
1600: "Signature failed core validation");
1601: boolean sv = signature.getSignatureValue()
1602: .validate(validationContext);
1603: logger.log(Level.FINEST,
1604: "Signature validation status: " + sv);
1605: // check the validation status of each Reference
1606: Iterator i = signature.getSignedInfo()
1607: .getReferences().iterator();
1608: for (int j = 0; i.hasNext(); j++) {
1609: Reference ref = (Reference) i.next();
1610: logger.log(Level.FINEST, "Reference ID "
1611: + ref.getId());
1612: logger.log(Level.FINEST, "Reference URI "
1613: + ref.getURI());
1614: boolean refValid = ref
1615: .validate(validationContext);
1616: logger.log(Level.FINEST, "Reference[" + j
1617: + "] validity status: " + refValid);
1618: }
1619: }
1620: }
1621: return coreValidity;
1622:
1623: } catch (Exception e) {
1624: //log here
1625: logger.log(Level.SEVERE,
1626: "Exception occurred during signature verification"
1627: + e.getMessage());
1628: throw new XWSSecurityException(e);
1629: }
1630: }
1631:
1632: private static KeyInfo prepareForSymmetricKeySignature(
1633: FilterProcessingContext context, WSSPolicy keyBinding,
1634: Key originalKey, SignaturePolicy signaturePolicy,
1635: Node[] nxtSiblingContainer,
1636: AuthenticationTokenPolicy.X509CertificateBinding certInfo,
1637: DerivedKeyToken dkt) throws XWSSecurityException {
1638:
1639: Node nextSibling = null;
1640: KeyInfo keyInfo = null;
1641:
1642: //depending on the ref type handle an X509Token
1643: //create an EK with keyInfo pointing to the X509
1644: String keyEncAlgo = XMLCipher.RSA_v1dot5; //<--Harcoding of Algo
1645: if (context.getAlgorithmSuite() != null) {
1646: keyEncAlgo = context.getAlgorithmSuite()
1647: .getAsymmetricKeyAlgorithm();
1648: }
1649:
1650: String referenceType = null;
1651: KeyInfoStrategy strategy = null;
1652: KeyInfoHeaderBlock keyInfoBlock = null;
1653: SecurableSoapMessage secureMessage = context
1654: .getSecurableSoapMessage();
1655: SecurityHeader securityHeader = secureMessage
1656: .findOrCreateSecurityHeader();
1657:
1658: WSSPolicyConsumerImpl dsigHelper = WSSPolicyConsumerImpl
1659: .getInstance();
1660:
1661: boolean wss11Receiver = "true".equals(context
1662: .getExtraneousProperty("EnableWSS11PolicyReceiver"));
1663: boolean wss11Sender = "true".equals(context
1664: .getExtraneousProperty("EnableWSS11PolicySender"));
1665: boolean sendEKSHA1 = wss11Receiver && wss11Sender
1666: && (getEKSHA1Ref(context) != null);
1667: boolean wss10 = !wss11Sender;
1668:
1669: try {
1670: if (PolicyTypeUtil.derivedTokenKeyBinding(keyBinding)) {
1671: DerivedTokenKeyBinding dtk = (DerivedTokenKeyBinding) keyBinding
1672: .clone();
1673:
1674: WSSPolicy originalKeyBinding = dtk
1675: .getOriginalKeyBinding();
1676:
1677: if (PolicyTypeUtil
1678: .x509CertificateBinding(originalKeyBinding)) {
1679: logger
1680: .log(Level.SEVERE,
1681: "WSS1327.unsupported.asymmetricbinding.derivedkey.x509token");
1682: throw new XWSSecurityException(
1683: "Asymmetric Binding with DerivedKeys under X509Token Policy Not Yet Supported");
1684: } else if (PolicyTypeUtil
1685: .symmetricKeyBinding(originalKeyBinding)) {
1686:
1687: if (sendEKSHA1) {
1688: String ekSha1Ref = getEKSHA1Ref(context);
1689:
1690: //STR for DerivedKeyToken
1691: SecurityTokenReference tokenRef = new SecurityTokenReference(
1692: secureMessage.getSOAPPart());
1693: EncryptedKeySHA1Identifier refElem = new EncryptedKeySHA1Identifier(
1694: secureMessage.getSOAPPart());
1695: refElem.setReferenceValue(ekSha1Ref);
1696: tokenRef.setReference(refElem);
1697: //set the wsse11:TokenType attribute as required by WSS 1.1
1698: //tokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
1699: //TODO: Temporary fix for signing
1700: String dktId = keyBinding.getUUID();
1701: if (dktId == null) {
1702: dktId = secureMessage.generateId();
1703: }
1704: String nonce = Base64.encode(dkt.getNonce());
1705: DerivedKeyTokenHeaderBlock dktHeadrBlock = new DerivedKeyTokenHeaderBlock(
1706: securityHeader.getOwnerDocument(),
1707: tokenRef, nonce, dkt.getOffset(), dkt
1708: .getLength(), dktId);
1709: // insert the derivedKey into SecurityHeader
1710: secureMessage.findOrCreateSecurityHeader()
1711: .insertHeaderBlock(dktHeadrBlock);
1712: // set the next sibling to next sibling of derived key token
1713: nextSibling = dktHeadrBlock.getAsSoapElement()
1714: .getNextSibling();
1715: nxtSiblingContainer[0] = nextSibling;
1716:
1717: //Construct the STR for signature
1718: DirectReference reference = new DirectReference();
1719: reference.setURI("#" + dktId);
1720: SecurityTokenReference sigTokenRef = new SecurityTokenReference(
1721: secureMessage.getSOAPPart());
1722: sigTokenRef.setReference(reference);
1723: keyInfo = dsigHelper.constructKeyInfo(
1724: signaturePolicy, sigTokenRef);
1725:
1726: return keyInfo;
1727:
1728: } else if (wss11Sender || wss10) {
1729:
1730: AuthenticationTokenPolicy.X509CertificateBinding x509Binding = null;
1731: X509Certificate cert = null;
1732: if (context.getX509CertificateBinding() != null) {
1733: x509Binding = context
1734: .getX509CertificateBinding();
1735: context.setX509CertificateBinding(null);
1736: }
1737:
1738: HashMap tokenCache = context.getTokenCache();
1739: HashMap insertedX509Cache = context
1740: .getInsertedX509Cache();
1741: String x509id = x509Binding.getUUID();
1742: if (x509id == null || x509id.equals("")) {
1743: x509id = secureMessage.generateId();
1744: }
1745:
1746: SecurityUtil.checkIncludeTokenPolicy(context,
1747: x509Binding, x509id);
1748:
1749: referenceType = x509Binding.getReferenceType();
1750: strategy = KeyInfoStrategy
1751: .getInstance(referenceType);
1752: X509SecurityToken token = null;
1753: cert = x509Binding.getX509Certificate();
1754: String x509TokenId = x509Binding.getUUID();
1755: //Check to see if same x509 token used for Signature and Encryption
1756: boolean tokenInserted = false;
1757:
1758: if (x509TokenId == null
1759: || x509TokenId.equals("")) {
1760: x509TokenId = secureMessage.generateId();
1761: }
1762: // ReferenceType adjustment in checkIncludeTokenPolicy is also currently
1763: // causing an insertion of the X509 into the Message
1764: X509SecurityToken insertedx509 = (X509SecurityToken) context
1765: .getInsertedX509Cache()
1766: .get(x509TokenId);
1767:
1768: // this one is used to determine if the whole BST + EK + DKT(opt)
1769: // has been inserted by another filter such as Encryption running before
1770: token = (X509SecurityToken) tokenCache
1771: .get(x509TokenId);
1772: if (token == null) {
1773: if (insertedx509 != null) {
1774: token = insertedx509;
1775: tokenCache.put(x509TokenId,
1776: insertedx509);
1777: } else {
1778: String valueType = x509Binding
1779: .getValueType();
1780: if (valueType == null
1781: || valueType.equals("")) {
1782: //default valueType for X509 as v3
1783: valueType = MessageConstants.X509v3_NS;
1784: }
1785: token = new X509SecurityToken(
1786: secureMessage.getSOAPPart(),
1787: cert, x509TokenId, valueType);
1788: tokenCache.put(x509TokenId, token);
1789: }
1790: context.setCurrentSecret(originalKey);
1791: } else {
1792: tokenInserted = true;
1793: }
1794:
1795: String dktId = keyBinding.getUUID();
1796: if (dktId == null) {
1797: dktId = secureMessage.generateId();
1798: }
1799: String nonce = Base64.encode(dkt.getNonce());
1800: HashMap ekCache = context
1801: .getEncryptedKeyCache();
1802: String ekId = (String) ekCache.get(x509TokenId);
1803: EncryptedKey encryptedKey = null;
1804: XMLCipher keyEncryptor = null;
1805: if (!tokenInserted) {
1806: //Store SymmetricKey generated in ProcessingContext
1807: context.setExtraneousProperty("SecretKey",
1808: originalKey); //this is the originalKey
1809: //keyinfo for encryptedKey
1810: keyInfoBlock = new KeyInfoHeaderBlock(
1811: secureMessage.getSOAPPart());
1812: strategy.setCertificate(cert);
1813: strategy.insertKey(keyInfoBlock,
1814: secureMessage, x509TokenId);
1815: com.sun.org.apache.xml.internal.security.keys.KeyInfo apacheKeyInfo = keyInfoBlock
1816: .getKeyInfo();
1817:
1818: //create an encrypted Key --- it encrypts the original key
1819: try {
1820: keyEncryptor = XMLCipher
1821: .getInstance(keyEncAlgo);
1822: keyEncryptor.init(XMLCipher.WRAP_MODE,
1823: cert.getPublicKey());
1824: if (keyEncryptor != null) {
1825: encryptedKey = keyEncryptor
1826: .encryptKey(secureMessage
1827: .getSOAPPart(),
1828: originalKey);
1829: }
1830: } catch (Exception e) {
1831: logger
1832: .log(Level.SEVERE,
1833: "WSS1334.error.creating.encryptedkey");
1834: throw new XWSSecurityException(e);
1835: }
1836: ekId = secureMessage.generateId();
1837: ekCache.put(x509TokenId, ekId);
1838: encryptedKey.setId(ekId);
1839: // set its KeyInfo
1840: encryptedKey.setKeyInfo(apacheKeyInfo);
1841: }
1842:
1843: //STR for DerivedKeyToken
1844: SecurityTokenReference tokenRef = new SecurityTokenReference(
1845: secureMessage.getSOAPPart());
1846: DirectReference reference = new DirectReference();
1847: //TODO: PLUGFEST commenting this as Microsoft puts Value type on reference itself
1848: //tokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
1849: //set id of encrypted key in STR of DKT
1850: reference
1851: .setValueType(MessageConstants.EncryptedKey_NS);
1852: reference.setURI("#" + ekId);
1853: tokenRef.setReference(reference);
1854: DerivedKeyTokenHeaderBlock dktHeadrBlock = new DerivedKeyTokenHeaderBlock(
1855: securityHeader.getOwnerDocument(),
1856: tokenRef, nonce, dkt.getOffset(), dkt
1857: .getLength(), dktId);
1858:
1859: if (!tokenInserted) {
1860: Node nsX509 = null;
1861: if (insertedx509 != null) {
1862: nsX509 = insertedx509.getNextSibling();
1863: }
1864: // move DKT below X509 if present
1865: if (nsX509 == null) {
1866: secureMessage
1867: .findOrCreateSecurityHeader()
1868: .insertHeaderBlock(
1869: dktHeadrBlock);
1870: } else {
1871: secureMessage
1872: .findOrCreateSecurityHeader()
1873: .insertBefore(dktHeadrBlock,
1874: nsX509);
1875: }
1876: // move EK above DKT but below X509
1877: if (insertedx509 != null) {
1878: nsX509 = insertedx509.getNextSibling();
1879: }
1880:
1881: // insert the EK into the SOAPMessage - this goes on top of DKT Header block
1882: SOAPElement se = (SOAPElement) keyEncryptor
1883: .martial(encryptedKey);
1884: if (nsX509 == null) {
1885: secureMessage
1886: .findOrCreateSecurityHeader()
1887: .insertHeaderBlockElement(se);
1888: } else {
1889: secureMessage
1890: .findOrCreateSecurityHeader()
1891: .insertBefore(se, nsX509);
1892: }
1893: //insert the token as the first child in SecurityHeader
1894: if (MessageConstants.DIRECT_REFERENCE_TYPE
1895: .equals(referenceType)
1896: && insertedX509Cache
1897: .get(x509TokenId) == null) {
1898: secureMessage
1899: .findOrCreateSecurityHeader()
1900: .insertHeaderBlock(token);
1901: insertedX509Cache.put(x509TokenId,
1902: token);
1903: }
1904: //store EKSHA1 of KeyValue contents in context
1905: Element cipherData = (Element) se
1906: .getChildElements(
1907: new QName(
1908: MessageConstants.XENC_NS,
1909: "CipherData",
1910: MessageConstants.XENC_PREFIX))
1911: .next();
1912: String cipherValue = cipherData
1913: .getElementsByTagNameNS(
1914: MessageConstants.XENC_NS,
1915: "CipherValue").item(0)
1916: .getTextContent();
1917: byte[] decodedCipher = Base64
1918: .decode(cipherValue);
1919: byte[] ekSha1 = MessageDigest.getInstance(
1920: "SHA-1").digest(decodedCipher);
1921: String encEkSha1 = Base64.encode(ekSha1);
1922: context.setExtraneousProperty(
1923: "EncryptedKeySHA1", encEkSha1);
1924: } else {
1925: //insert derived key after the existing EK
1926: Element ekElem = secureMessage
1927: .getElementById(ekId);
1928: secureMessage.findOrCreateSecurityHeader()
1929: .insertBefore(dktHeadrBlock,
1930: ekElem.getNextSibling());
1931: }
1932:
1933: //Construct the STR for signature
1934: DirectReference refSig = new DirectReference();
1935: refSig.setURI("#" + dktId);
1936: SecurityTokenReference sigTokenRef = new SecurityTokenReference(
1937: secureMessage.getSOAPPart());
1938: sigTokenRef.setReference(refSig);
1939: keyInfo = dsigHelper.constructKeyInfo(
1940: signaturePolicy, sigTokenRef);
1941:
1942: // set the next sibling to next sibling of derived key token
1943: nextSibling = dktHeadrBlock.getAsSoapElement()
1944: .getNextSibling();
1945: nxtSiblingContainer[0] = nextSibling;
1946:
1947: return keyInfo;
1948:
1949: }
1950: } else if (PolicyTypeUtil
1951: .issuedTokenKeyBinding(originalKeyBinding)) {
1952:
1953: IssuedTokenKeyBinding itk = (IssuedTokenKeyBinding) originalKeyBinding;
1954:
1955: IssuedTokenContext issuedTokenContext = context
1956: .getTrustContext();
1957:
1958: //Get the IssuedToken and insert it into the message
1959: GenericToken issuedToken = (GenericToken) issuedTokenContext
1960: .getSecurityToken();
1961: SOAPElement tokenElem = null;
1962: SecurityTokenReference str = null;
1963: Element strElem = null;
1964:
1965: // check if the token is already present
1966: IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding) originalKeyBinding;
1967: //String ikbPolicyId = ikb.getPolicyToken().getTokenId();
1968: String ikbPolicyId = ikb.getUUID();
1969:
1970: //Look for TrustToken in TokenCache
1971: HashMap tokCache = context.getTokenCache();
1972: Object tok = tokCache.get(ikbPolicyId);
1973: SOAPElement issuedTokenElementFromMsg = null;
1974: boolean includeIST = (ikb.INCLUDE_ALWAYS_TO_RECIPIENT
1975: .equals(ikb.getIncludeToken()) || ikb.INCLUDE_ALWAYS
1976: .equals(ikb.getIncludeToken()));
1977:
1978: if (includeIST && (issuedToken == null)) {
1979: logger.log(Level.SEVERE,
1980: "WSS1343.null.IssuedToken");
1981: throw new XWSSecurityException(
1982: "Issued Token to be inserted into the Message was Null");
1983: }
1984:
1985: if (issuedToken != null) {
1986: // treat the token as an Opaque entity and just insert the token into message
1987: Element elem = (Element) issuedToken
1988: .getTokenValue();
1989: if (tok == null) {
1990: //TODO: remove these expensive conversions DOM Imports
1991: tokenElem = XMLUtil.convertToSoapElement(
1992: secureMessage.getSOAPPart(), elem);
1993: //FIX for Issue 26: We need an Id to cache and MS is not setting in some cases
1994: String tokId = tokenElem.getAttribute("Id");
1995: if ("".equals(tokId)
1996: && MessageConstants.ENCRYPTED_DATA_LNAME
1997: .equals(tokenElem
1998: .getLocalName())) {
1999: tokenElem.setAttribute("Id",
2000: secureMessage.generateId());
2001: }
2002: tokCache.put(ikbPolicyId, tokenElem);
2003: } else {
2004: // it will be SOAPElement retrieve its wsuId attr
2005: String wsuId = SecurityUtil
2006: .getWsuIdOrId((Element) tok);
2007: issuedTokenElementFromMsg = (SOAPElement) secureMessage
2008: .getElementById(wsuId);
2009: if (issuedTokenElementFromMsg == null) {
2010: logger
2011: .log(Level.SEVERE,
2012: "WSS1344.error.locateIssueToken.Message");
2013: throw new XWSSecurityException(
2014: "Could not locate Issued Token in Message");
2015: }
2016: }
2017: }
2018:
2019: if (includeIST) {
2020: strElem = (Element) issuedTokenContext
2021: .getAttachedSecurityTokenReference()
2022: .getTokenValue();
2023: } else {
2024: strElem = (Element) issuedTokenContext
2025: .getUnAttachedSecurityTokenReference()
2026: .getTokenValue();
2027: }
2028:
2029: //TODO: remove these expensive conversions
2030: Element imported = (Element) secureMessage
2031: .getSOAPPart().importNode(strElem, true);
2032: str = new SecurityTokenReference(XMLUtil
2033: .convertToSoapElement(secureMessage
2034: .getSOAPPart(), imported), false);
2035:
2036: if (originalKey != null) {
2037: SecurityUtil.updateSamlVsKeyCache(str, context,
2038: originalKey);
2039: }
2040:
2041: String dktId = keyBinding.getUUID();
2042: if (dktId == null) {
2043: dktId = secureMessage.generateId();
2044: }
2045:
2046: DerivedKeyTokenHeaderBlock derivedKeyTokenHeaderBlock = new DerivedKeyTokenHeaderBlock(
2047: secureMessage.getSOAPPart(), str, Base64
2048: .encode(dkt.getNonce()), dkt
2049: .getOffset(), dkt.getLength(),
2050: dktId);
2051:
2052: if (issuedTokenElementFromMsg != null) {
2053: SecurityHeader _secHeader = secureMessage
2054: .findOrCreateSecurityHeader();
2055: _secHeader.insertBefore(
2056: derivedKeyTokenHeaderBlock,
2057: issuedTokenElementFromMsg
2058: .getNextSibling());
2059: } else {
2060: Node reflist = context.getCurrentRefList();
2061: if (reflist != null) {
2062: secureMessage.findOrCreateSecurityHeader()
2063: .insertBefore(
2064: derivedKeyTokenHeaderBlock,
2065: reflist);
2066: context.setCurrentReferenceList(null);
2067: } else {
2068: secureMessage.findOrCreateSecurityHeader()
2069: .insertHeaderBlock(
2070: derivedKeyTokenHeaderBlock);
2071: }
2072: }
2073:
2074: // insert the Issued Token after the DKT
2075: if (tokenElem != null) {
2076: if (includeIST) {
2077: secureMessage
2078: .findOrCreateSecurityHeader()
2079: .insertHeaderBlockElement(tokenElem);
2080: }
2081: // also store the token in Packet.invocationProperties to be used by
2082: // client side response processing
2083: context.setIssuedSAMLToken(tokenElem);
2084: }
2085:
2086: //Construct the STR for signature
2087: DirectReference refSig = new DirectReference();
2088: refSig.setURI("#" + dktId);
2089: SecurityTokenReference sigTokenRef = new SecurityTokenReference(
2090: secureMessage.getSOAPPart());
2091: sigTokenRef.setReference(refSig);
2092: keyInfo = dsigHelper.constructKeyInfo(
2093: signaturePolicy, sigTokenRef);
2094:
2095: // set the next sibling to next sibling of derived key token
2096: nextSibling = derivedKeyTokenHeaderBlock
2097: .getAsSoapElement().getNextSibling();
2098: nxtSiblingContainer[0] = nextSibling;
2099: return keyInfo;
2100:
2101: } else if (PolicyTypeUtil
2102: .samlTokenPolicy(originalKeyBinding)) {
2103: logger
2104: .log(Level.SEVERE,
2105: "WSS1345.unsupported.derivedkeys.SAMLToken");
2106: throw new UnsupportedOperationException(
2107: "DerivedKeys with SAMLToken not yet supported");
2108:
2109: } else if (PolicyTypeUtil
2110: .secureConversationTokenKeyBinding(originalKeyBinding)) {
2111: SecureConversationTokenKeyBinding sctBinding = (SecureConversationTokenKeyBinding) originalKeyBinding;
2112: //STR for DerivedKeyToken
2113: SecurityTokenReference tokenRef = new SecurityTokenReference(
2114: secureMessage.getSOAPPart());
2115: SOAPElement sctElement = insertSCT(context,
2116: sctBinding, tokenRef);
2117: String dktId = keyBinding.getUUID();
2118: if (dktId == null) {
2119: dktId = secureMessage.generateId();
2120: }
2121: String nonce = Base64.encode(dkt.getNonce());
2122: DerivedKeyTokenHeaderBlock dktHeaderBlock = new DerivedKeyTokenHeaderBlock(
2123: securityHeader.getOwnerDocument(),
2124: tokenRef, nonce, dkt.getOffset(), dkt
2125: .getLength(), dktId);
2126:
2127: Node next = (sctElement != null) ? sctElement
2128: .getNextSibling() : null;
2129:
2130: if (next == null) {
2131: Node reflist = context.getCurrentRefList();
2132: if (reflist != null) {
2133: next = reflist;
2134: context.setCurrentReferenceList(null);
2135: }
2136: }
2137:
2138: SOAPElement dktElem = (SOAPElement) securityHeader
2139: .insertBefore(dktHeaderBlock
2140: .getAsSoapElement(), next);
2141: //Construct the STR for signature
2142: DirectReference refSig = new DirectReference();
2143: refSig.setURI("#" + dktId);
2144: SecurityTokenReference sigTokenRef = new SecurityTokenReference(
2145: secureMessage.getSOAPPart());
2146: sigTokenRef.setReference(refSig);
2147:
2148: // signature should be below DKT
2149: nextSibling = dktElem.getNextSibling();
2150: nxtSiblingContainer[0] = nextSibling;
2151:
2152: keyInfo = dsigHelper.constructKeyInfo(
2153: signaturePolicy, sigTokenRef);
2154: return keyInfo;
2155: }
2156:
2157: } else if (PolicyTypeUtil.issuedTokenKeyBinding(keyBinding)) {
2158: //Get the IssuedToken and insert it into the message
2159: IssuedTokenContext issuedTokenContext = context
2160: .getTrustContext();
2161: GenericToken issuedToken = (GenericToken) issuedTokenContext
2162: .getSecurityToken();
2163: SOAPElement tokenElem = null;
2164: SecurityTokenReference str = null;
2165: Element strElem = null;
2166: SOAPElement issuedTokenElementFromMsg = null;
2167:
2168: // check if the token is already present
2169: IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding) keyBinding;
2170: //String ikbPolicyId = ikb.getPolicyToken().getTokenId();
2171: String ikbPolicyId = ikb.getUUID();
2172:
2173: //Look for TrustToken in TokenCache
2174: HashMap tokCache = context.getTokenCache();
2175: Object tok = tokCache.get(ikbPolicyId);
2176:
2177: boolean includeIST = (ikb.INCLUDE_ALWAYS_TO_RECIPIENT
2178: .equals(ikb.getIncludeToken()) || ikb.INCLUDE_ALWAYS
2179: .equals(ikb.getIncludeToken()));
2180:
2181: if (includeIST && (issuedToken == null)) {
2182: logger
2183: .log(Level.SEVERE,
2184: "WSS1343.null.IssuedToken");
2185: throw new XWSSecurityException(
2186: "Issued Token to be inserted into the Message was Null");
2187: }
2188:
2189: if (issuedToken != null) {
2190: // treat the token as an Opaque entity and just insert the token into message
2191: Element elem = (Element) issuedToken
2192: .getTokenValue();
2193: if (tok == null) {
2194: //TODO: remove these expensive conversions DOM Imports
2195: tokenElem = XMLUtil.convertToSoapElement(
2196: secureMessage.getSOAPPart(), elem);
2197: //FIX for Issue 26: We need an Id to cache and MS is not setting in some cases
2198: String tokId = tokenElem.getAttribute("Id");
2199: if ("".equals(tokId)
2200: && MessageConstants.ENCRYPTED_DATA_LNAME
2201: .equals(tokenElem
2202: .getLocalName())) {
2203: tokenElem.setAttribute("Id", secureMessage
2204: .generateId());
2205: }
2206: tokCache.put(ikbPolicyId, tokenElem);
2207: } else {
2208: // it will be SOAPElement retrieve its wsuId attr
2209: String wsuId = SecurityUtil
2210: .getWsuIdOrId((Element) tok);
2211: issuedTokenElementFromMsg = (SOAPElement) secureMessage
2212: .getElementById(wsuId);
2213: if (issuedTokenElementFromMsg == null) {
2214: logger
2215: .log(Level.SEVERE,
2216: "WSS1344.error.locateIssueToken.Message");
2217: throw new XWSSecurityException(
2218: "Could not locate Issued Token in Message");
2219: }
2220: }
2221: }
2222:
2223: if (includeIST) {
2224: strElem = SecurityUtil
2225: .convertSTRToElement(
2226: issuedTokenContext
2227: .getAttachedSecurityTokenReference()
2228: .getTokenValue(),
2229: secureMessage.getSOAPPart());
2230: } else {
2231: strElem = SecurityUtil
2232: .convertSTRToElement(
2233: issuedTokenContext
2234: .getUnAttachedSecurityTokenReference()
2235: .getTokenValue(),
2236: secureMessage.getSOAPPart());
2237: }
2238:
2239: if (strElem == null) {
2240: logger.log(Level.SEVERE,
2241: "WSS1378.unableto.refer.IssueToken");
2242: throw new XWSSecurityException(
2243: "Cannot determine how to reference the Issued Token in the Message");
2244: }
2245:
2246: //TODO: remove these expensive conversions
2247: Element imported = (Element) secureMessage
2248: .getSOAPPart().importNode(strElem, true);
2249: str = new SecurityTokenReference(XMLUtil
2250: .convertToSoapElement(secureMessage
2251: .getSOAPPart(), (Element) imported
2252: .cloneNode(true)), false);
2253:
2254: if (originalKey != null) {
2255: SecurityUtil.updateSamlVsKeyCache(str, context,
2256: originalKey);
2257: }
2258:
2259: if (tokenElem != null) {
2260: if (includeIST) {
2261:
2262: secureMessage.findOrCreateSecurityHeader()
2263: .insertHeaderBlockElement(tokenElem);
2264: nxtSiblingContainer[0] = tokenElem
2265: .getNextSibling();
2266: } else {
2267: nxtSiblingContainer[0] = null;
2268: }
2269: // also store the token in Packet.invocationProperties to be used by
2270: // client side response processing
2271: context.setIssuedSAMLToken(tokenElem);
2272: } else if (issuedTokenElementFromMsg != null) {
2273: nxtSiblingContainer[0] = issuedTokenElementFromMsg
2274: .getNextSibling();
2275: }
2276:
2277: keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,
2278: str);
2279: return keyInfo;
2280:
2281: } else if (PolicyTypeUtil
2282: .secureConversationTokenKeyBinding(keyBinding)) {
2283:
2284: SecurityTokenReference secTokenRef = new SecurityTokenReference(
2285: secureMessage.getSOAPPart());
2286: SecureConversationTokenKeyBinding sctBinding = (SecureConversationTokenKeyBinding) keyBinding;
2287: SOAPElement sctElement = insertSCT(context, sctBinding,
2288: secTokenRef);
2289:
2290: // signature should be below SCT
2291: nextSibling = (sctElement != null) ? sctElement
2292: .getNextSibling() : null;
2293: nxtSiblingContainer[0] = nextSibling;
2294:
2295: keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,
2296: secTokenRef);
2297: return keyInfo;
2298: }
2299:
2300: } catch (SOAPException ex) {
2301: logger.log(Level.SEVERE,
2302: "WSS1346.error.preparing.symmetrickey.signature",
2303: ex);
2304: throw new XWSSecurityException(ex);
2305: } catch (Base64DecodingException ex) {
2306: logger.log(Level.SEVERE,
2307: "WSS1346.error.preparing.symmetrickey.signature",
2308: ex);
2309: throw new XWSSecurityException(ex);
2310: } catch (NoSuchAlgorithmException ex) {
2311: logger.log(Level.SEVERE,
2312: "WSS1346.error.preparing.symmetrickey.signature",
2313: ex);
2314: throw new XWSSecurityException(ex);
2315: }
2316:
2317: return null;
2318: }
2319:
2320: public static SOAPElement insertSCT(
2321: FilterProcessingContext context,
2322: SecureConversationTokenKeyBinding sctBinding,
2323: SecurityTokenReference secTokenRef)
2324: throws XWSSecurityException {
2325: SecurableSoapMessage secureMessage = context
2326: .getSecurableSoapMessage();
2327: //String sctPolicyId = sctBinding.getPolicyToken().getTokenId();
2328: String sctPolicyId = sctBinding.getUUID();
2329:
2330: //Look for SCT in TokenCache
2331: HashMap tokCache = context.getTokenCache();
2332: SecurityContextTokenImpl sct = null;
2333: sct = (SecurityContextTokenImpl) tokCache.get(sctPolicyId);
2334: boolean tokenInserted = false;
2335: SOAPElement sctElement = null;
2336:
2337: IssuedTokenContext ictx = context
2338: .getSecureConversationContext();
2339:
2340: if (sct == null) {
2341: SecurityContextToken sct1 = (SecurityContextToken) ictx
2342: .getSecurityToken();
2343: if (sct1 == null) {
2344: logger.log(Level.SEVERE,
2345: "WSS1347.null.SecureConversationToken");
2346: throw new XWSSecurityException(
2347: "SecureConversation Token not Found");
2348: }
2349:
2350: sct = new SecurityContextTokenImpl(secureMessage
2351: .getSOAPPart(), sct1.getIdentifier().toString(),
2352: sct1.getInstance(), sct1.getWsuId(), sct1
2353: .getExtElements());
2354: // put back in token cache
2355: tokCache.put(sctPolicyId, sct);
2356: } else {
2357: tokenInserted = true;
2358: // record the element
2359: sctElement = secureMessage
2360: .getElementByWsuId(sct.getWsuId());
2361: }
2362:
2363: String sctWsuId = sct.getWsuId();
2364: if (sctWsuId == null) {
2365: sct.setId(secureMessage.generateId());
2366: }
2367: sctWsuId = sct.getWsuId();
2368:
2369: if (sctBinding.INCLUDE_ALWAYS_TO_RECIPIENT.equals(sctBinding
2370: .getIncludeToken())
2371: || sctBinding.INCLUDE_ALWAYS.equals(sctBinding
2372: .getIncludeToken())) {
2373:
2374: if (!tokenInserted) {
2375: secureMessage.findOrCreateSecurityHeader()
2376: .insertHeaderBlock(sct);
2377: // record the element
2378: sctElement = secureMessage.getElementByWsuId(sct
2379: .getWsuId());
2380: }
2381:
2382: DirectReference reference = new DirectReference();
2383:
2384: reference.setURI("#" + sctWsuId);
2385: secTokenRef.setReference(reference);
2386: } else {
2387: // we have to insert SCT Session Id instead of wsuId
2388: DirectReference reference = new DirectReference();
2389: reference.setSCTURI(sct.getIdentifier().toString(), sct
2390: .getInstance());
2391: secTokenRef.setReference(reference);
2392: }
2393:
2394: return sctElement;
2395: }
2396:
2397: private static KeyInfo handleX509Binding(
2398: FilterProcessingContext context,
2399: SignaturePolicy signaturePolicy,
2400: AuthenticationTokenPolicy.X509CertificateBinding certInfo,
2401: Node[] nxtSiblingContainer) throws XWSSecurityException {
2402:
2403: Node nextSibling = null;
2404: KeyInfo keyInfo = null;
2405: SecurableSoapMessage secureMessage = context
2406: .getSecurableSoapMessage();
2407: SecurityHeader securityHeader = secureMessage
2408: .findOrCreateSecurityHeader();
2409: WSSPolicyConsumerImpl dsigHelper = WSSPolicyConsumerImpl
2410: .getInstance();
2411:
2412: HashMap tokenCache = context.getTokenCache();
2413: HashMap insertedX509Cache = context.getInsertedX509Cache();
2414: String x509id = certInfo.getUUID();
2415: if (x509id == null || x509id.equals("")) {
2416: x509id = secureMessage.generateId();
2417: }
2418:
2419: SecurityUtil.checkIncludeTokenPolicy(context, certInfo, x509id);
2420:
2421: String referenceType = certInfo.getReferenceType();
2422: String strId = certInfo.getSTRID();
2423: if (strId == null) {
2424: strId = secureMessage.generateId();
2425: }
2426:
2427: try {
2428: if (referenceType.equals("Direct")) {
2429: DirectReference reference = new DirectReference();
2430: // this is an X509 certificate binding
2431: String valueType = certInfo.getValueType();
2432: if (valueType == null || valueType.equals("")) {
2433: valueType = MessageConstants.X509v3_NS;
2434:
2435: }
2436: reference.setValueType(valueType);
2437: //Use DirectReferenceStrategy -
2438: //Revisit :: Move is generation to filters.
2439: String id = certInfo.getUUID();
2440: if (id == null || id.equals("")) {
2441: id = secureMessage.generateId();
2442: }
2443: reference.setURI("#" + id);
2444: SecurityTokenReference secTokenRef = new SecurityTokenReference(
2445: secureMessage.getSOAPPart());
2446: secTokenRef.setReference(reference);
2447: secTokenRef.setWsuId(strId);
2448: keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,
2449: secTokenRef);
2450: X509SecurityToken token = null;
2451: token = (X509SecurityToken) tokenCache.get(id);
2452: if (token == null) {
2453: valueType = certInfo.getValueType();
2454: if (valueType == null || valueType.equals("")) {
2455: //default valueType for X509 as v3
2456: valueType = MessageConstants.X509v3_NS;
2457: }
2458: token = new X509SecurityToken(secureMessage
2459: .getSOAPPart(), certInfo
2460: .getX509Certificate(), id, valueType);
2461: tokenCache.put(id, token);
2462: }
2463: if (insertedX509Cache.get(id) == null) {
2464: secureMessage.findOrCreateSecurityHeader()
2465: .insertHeaderBlock(token);
2466: insertedX509Cache.put(id, token);
2467: }
2468: nextSibling = token.getAsSoapElement().getNextSibling();
2469: nxtSiblingContainer[0] = nextSibling;
2470: return keyInfo;
2471: } else if (referenceType.equals("Identifier")) {
2472: String valueType = certInfo.getValueType();
2473: if (valueType == MessageConstants.X509v1_NS
2474: || valueType.equals(MessageConstants.X509v1_NS)) {
2475: logger.log(Level.SEVERE,
2476: "WSS1333.unsupported.keyidentifer.X509v1");
2477: throw new XWSSecurityException(
2478: "Key Identifier reference Type is not allowed for X509v1 Certificates");
2479: }
2480: KeyIdentifierStrategy keyIdentifier = new KeyIdentifierStrategy(
2481: certInfo.getCertificateIdentifier(), true);
2482: keyIdentifier.setCertificate(certInfo
2483: .getX509Certificate());
2484: SecurityTokenReference secTokenRef = new SecurityTokenReference(
2485: secureMessage.getSOAPPart());
2486: keyIdentifier.insertKey(secTokenRef, secureMessage);
2487: secTokenRef.setWsuId(strId);
2488: X509SubjectKeyIdentifier re = (X509SubjectKeyIdentifier) secTokenRef
2489: .getReference();
2490: String id = re.getReferenceValue();
2491: tokenCache.put(id, re);
2492: re.setCertificate(certInfo.getX509Certificate());
2493: keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,
2494: secTokenRef);
2495: nextSibling = securityHeader
2496: .getNextSiblingOfTimestamp();
2497: nxtSiblingContainer[0] = nextSibling;
2498: return keyInfo;
2499: } else if (referenceType
2500: .equals(MessageConstants.THUMB_PRINT_TYPE)) {
2501: String valueType = certInfo.getValueType();
2502: if (valueType == MessageConstants.X509v1_NS
2503: || valueType.equals(MessageConstants.X509v1_NS)) {
2504: logger.log(Level.SEVERE,
2505: "WSS1348.illegal.thumbprint.x509v1");
2506: throw new XWSSecurityException(
2507: "Thumb reference Type is not allowed for X509v1 Certificates");
2508: }
2509: KeyIdentifierStrategy keyIdentifier = new KeyIdentifierStrategy(
2510: certInfo.getCertificateIdentifier(), true, true);
2511: keyIdentifier.setCertificate(certInfo
2512: .getX509Certificate());
2513: SecurityTokenReference secTokenRef = new SecurityTokenReference(
2514: secureMessage.getSOAPPart());
2515: keyIdentifier.insertKey(secTokenRef, secureMessage);
2516: secTokenRef.setWsuId(strId);
2517: X509ThumbPrintIdentifier re = (X509ThumbPrintIdentifier) secTokenRef
2518: .getReference();
2519: String id = re.getReferenceValue();
2520: tokenCache.put(id, re);
2521: re.setCertificate(certInfo.getX509Certificate());
2522: keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,
2523: secTokenRef);
2524: nextSibling = securityHeader
2525: .getNextSiblingOfTimestamp();
2526: nxtSiblingContainer[0] = nextSibling;
2527: return keyInfo;
2528: } else if (referenceType
2529: .equals(MessageConstants.X509_ISSUER_TYPE)) {
2530: X509Certificate xCert = certInfo.getX509Certificate();
2531: X509IssuerSerial xis = new X509IssuerSerial(
2532: secureMessage.getSOAPPart(), xCert
2533: .getIssuerDN().getName(), xCert
2534: .getSerialNumber());
2535: SecurityTokenReference secTokenRef = new SecurityTokenReference(
2536: secureMessage.getSOAPPart());
2537: secTokenRef.setReference(xis);
2538: secTokenRef.setWsuId(strId);
2539: xis.setCertificate(xCert);
2540: tokenCache.put(xis.getIssuerName()
2541: + xis.getSerialNumber(), xis);
2542: keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,
2543: secTokenRef);
2544: nextSibling = securityHeader
2545: .getNextSiblingOfTimestamp();
2546: nxtSiblingContainer[0] = nextSibling;
2547: return keyInfo;
2548: } else {
2549: logger.log(Level.SEVERE,
2550: "WSS1308.unsupported.reference.mechanism");
2551: throw new XWSSecurityException("Reference type "
2552: + referenceType + "not supported");
2553: }
2554: } catch (Exception e) {
2555: logger.log(Level.SEVERE,
2556: "WSS1349.error.handlingX509Binding", e);
2557: throw new XWSSecurityException(e);
2558: }
2559: }
2560:
2561: private static String getEKSHA1Ref(FilterProcessingContext context) {
2562: String ekSha1Ref = null;
2563: ekSha1Ref = (String) context
2564: .getExtraneousProperty(MessageConstants.EK_SHA1_VALUE);
2565: return ekSha1Ref;
2566: }
2567:
2568: }
|