You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2008/09/22 20:51:10 UTC
svn commit: r697942 [2/2] - in /cxf/trunk:
api/src/main/java/org/apache/cxf/service/model/
api/src/main/java/org/apache/cxf/ws/policy/
common/common/src/main/java/org/apache/cxf/helpers/
rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/ rt/ws/policy...
Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java?rev=697942&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java Mon Sep 22 11:51:08 2008
@@ -0,0 +1,503 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.ws.security.wss4j.policyhandlers;
+
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.xml.soap.SOAPMessage;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.ws.policy.AssertionInfo;
+import org.apache.cxf.ws.policy.AssertionInfoMap;
+import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.SPConstants;
+import org.apache.cxf.ws.security.policy.model.AlgorithmSuite;
+import org.apache.cxf.ws.security.policy.model.AsymmetricBinding;
+import org.apache.cxf.ws.security.policy.model.RecipientToken;
+import org.apache.cxf.ws.security.policy.model.SupportingToken;
+import org.apache.cxf.ws.security.policy.model.Token;
+import org.apache.cxf.ws.security.policy.model.TokenWrapper;
+import org.apache.cxf.ws.security.policy.model.Wss10;
+import org.apache.cxf.ws.security.policy.model.Wss11;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.WSSecBase;
+import org.apache.ws.security.message.WSSecDKEncrypt;
+import org.apache.ws.security.message.WSSecDKSign;
+import org.apache.ws.security.message.WSSecEncrypt;
+import org.apache.ws.security.message.WSSecEncryptedKey;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecSignatureConfirmation;
+import org.apache.ws.security.message.WSSecTimestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+
+/**
+ *
+ */
+public class AsymmetricBindingHandler extends BindingBuilder {
+ AsymmetricBinding abinding;
+
+ private WSSecEncryptedKey encrKey;
+ private String encryptedKeyId;
+ private byte[] encryptedKeyValue;
+
+ private Map<Token, WSSecBase> sigSuppTokMap;
+ private Map<Token, WSSecBase> sgndEndSuppTokMap;
+ private Map<Token, WSSecBase> sgndEncSuppTokMap;
+ private Map<Token, WSSecBase> sgndEndEncSuppTokMap;
+ private Map<Token, WSSecBase> endSuppTokMap;
+ private Map<Token, WSSecBase> endEncSuppTokMap;
+
+
+ public AsymmetricBindingHandler(AsymmetricBinding binding,
+ SOAPMessage saaj,
+ WSSecHeader secHeader,
+ AssertionInfoMap aim,
+ SoapMessage message) {
+ super(binding, saaj, secHeader, aim, message);
+ this.abinding = binding;
+ }
+
+ public void handleBinding() {
+ WSSecTimestamp timestamp = createTimestamp();
+ timestamp = handleLayout(timestamp);
+
+ if (abinding.getProtectionOrder() == SPConstants.ProtectionOrder.EncryptBeforeSigning) {
+ doEncryptBeforeSign();
+ } else {
+ doSignBeforeEncrypt();
+ }
+
+ if (timestamp != null) {
+ timestamp.prependToHeader(secHeader);
+ }
+ }
+
+
+ private void doSignBeforeEncrypt() {
+ try {
+ Vector<WSEncryptionPart> sigs = getSignedParts();
+ if (isRequestor()) {
+ SupportingToken sgndSuppTokens =
+ (SupportingToken)findPolicy(SP12Constants.SIGNED_SUPPORTING_TOKENS);
+
+ sigSuppTokMap = this.handleSupportingTokens(sgndSuppTokens);
+
+ SupportingToken endSuppTokens =
+ (SupportingToken)findPolicy(SP12Constants.ENDORSING_SUPPORTING_TOKENS);
+
+ endSuppTokMap = this.handleSupportingTokens(endSuppTokens);
+
+ SupportingToken sgndEndSuppTokens
+ = (SupportingToken)findPolicy(SP12Constants.SIGNED_ENDORSING_SUPPORTING_TOKENS);
+ sgndEndSuppTokMap = this.handleSupportingTokens(sgndEndSuppTokens);
+
+ SupportingToken sgndEncryptedSuppTokens
+ = (SupportingToken)findPolicy(SP12Constants.SIGNED_ENCRYPTED_SUPPORTING_TOKENS);
+ sgndEncSuppTokMap = this.handleSupportingTokens(sgndEncryptedSuppTokens);
+
+ SupportingToken endorsingEncryptedSuppTokens
+ = (SupportingToken)findPolicy(SP12Constants.ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
+ endEncSuppTokMap = this.handleSupportingTokens(endorsingEncryptedSuppTokens);
+
+ SupportingToken sgndEndEncSuppTokens
+ = (SupportingToken)findPolicy(SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
+ sgndEndEncSuppTokMap = this.handleSupportingTokens(sgndEndEncSuppTokens);
+
+ SupportingToken supportingToks
+ = (SupportingToken)findPolicy(SP12Constants.SUPPORTING_TOKENS);
+ this.handleSupportingTokens(supportingToks);
+
+ SupportingToken encryptedSupportingToks
+ = (SupportingToken)findPolicy(SP12Constants.ENCRYPTED_SUPPORTING_TOKENS);
+ this.handleSupportingTokens(encryptedSupportingToks);
+
+ //Setup signature parts
+ addSignatureParts(sigSuppTokMap, sigs);
+ addSignatureParts(sgndEncSuppTokMap, sigs);
+ addSignatureParts(sgndEndSuppTokMap, sigs);
+ addSignatureParts(sgndEndEncSuppTokMap, sigs);
+
+
+ //Add timestamp
+ if (timestampEl != null) {
+ Element el = timestampEl.getElement();
+ sigs.add(new WSEncryptionPart(addWsuIdToElement(el)));
+ }
+ doSignature(sigs);
+ doEndorse();
+
+ } else {
+ //confirm sig
+ addSignatureConfirmation(sigs);
+ doSignature(sigs);
+ }
+
+ Vector<WSEncryptionPart> enc = getEncryptedParts();
+ doEncyption(enc);
+ } catch (Exception e) {
+ e.printStackTrace();
+ //REVISIT!!
+ }
+ }
+
+ private void doEncryptBeforeSign() {
+ // REVISIT
+
+ }
+
+
+ protected void addSignatureConfirmation(Vector<WSEncryptionPart> sigParts) {
+ Wss10 wss10 = getWss10();
+
+ if (!(wss10 instanceof Wss11)
+ || !((Wss11)wss10).isRequireSignatureConfirmation()) {
+ //If we don't require sig confirmation simply go back :-)
+ return;
+ }
+
+ Vector results = (Vector)message.getExchange().getInMessage().get(WSHandlerConstants.RECV_RESULTS);
+ /*
+ * loop over all results gathered by all handlers in the chain. For each
+ * handler result get the various actions. After that loop we have all
+ * signature results in the signatureActions vector
+ */
+ Vector signatureActions = new Vector();
+ for (int i = 0; i < results.size(); i++) {
+ WSHandlerResult wshResult = (WSHandlerResult) results.get(i);
+
+ WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),
+ WSConstants.SIGN, signatureActions);
+ WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),
+ WSConstants.ST_SIGNED, signatureActions);
+ WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),
+ WSConstants.UT_SIGN, signatureActions);
+ }
+
+ // prepare a SignatureConfirmation token
+ WSSecSignatureConfirmation wsc = new WSSecSignatureConfirmation();
+ if (signatureActions.size() > 0) {
+ for (int i = 0; i < signatureActions.size(); i++) {
+ WSSecurityEngineResult wsr = (WSSecurityEngineResult) signatureActions
+ .get(i);
+ byte[] sigVal = (byte[]) wsr.get(WSSecurityEngineResult.TAG_SIGNATURE_VALUE);
+ wsc.setSignatureValue(sigVal);
+ wsc.prepare(saaj.getSOAPPart());
+ wsc.prependToHeader(secHeader);
+ if (sigParts != null) {
+ sigParts.add(new WSEncryptionPart(wsc.getId()));
+ }
+ }
+ } else {
+ //No Sig value
+ wsc.prepare(saaj.getSOAPPart());
+ wsc.prependToHeader(secHeader);
+ if (sigParts != null) {
+ sigParts.add(new WSEncryptionPart(wsc.getId()));
+ }
+ }
+ }
+
+
+ private void doEndorse() {
+ // Adding the endorsing encrypted supporting tokens to endorsing supporting tokens
+ endSuppTokMap.putAll(endEncSuppTokMap);
+ // Do endorsed signatures
+ doEndorsedSignatures(endSuppTokMap, abinding.isTokenProtection());
+
+ //Adding the signed endorsed encrypted tokens to signed endorsed supporting tokens
+ sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
+ // Do signed endorsing signatures
+ doEndorsedSignatures(sgndEndSuppTokMap, abinding.isTokenProtection());
+ }
+
+ private void doEncyption(Vector<WSEncryptionPart> encrParts) {
+ //Check for signature protection
+ if (abinding.isSignatureProtection() && mainSigId != null) {
+ encrParts.add(new WSEncryptionPart(mainSigId, "Element"));
+ }
+
+ if (isRequestor()) {
+ for (String id : encryptedTokensIdList) {
+ encrParts.add(new WSEncryptionPart(id, "Element"));
+ }
+ }
+
+ //Do encryption
+ RecipientToken recToken = abinding.getRecipientToken();
+ if (recToken != null && recToken.getRecipientToken() != null && encrParts.size() > 0) {
+ Token encrToken = recToken.getRecipientToken();
+ policyAsserted(recToken);
+ policyAsserted(encrToken);
+ Element refList = null;
+ AlgorithmSuite algorithmSuite = abinding.getAlgorithmSuite();
+ if (encrToken.isDerivedKeys()) {
+ try {
+ WSSecDKEncrypt dkEncr = new WSSecDKEncrypt();
+
+ if (encrKey == null) {
+ setupEncryptedKey(recToken, encrToken);
+ }
+
+ dkEncr.setExternalKey(this.encryptedKeyValue, this.encryptedKeyId);
+ dkEncr.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
+ + WSConstants.ENC_KEY_VALUE_TYPE);
+ dkEncr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
+ dkEncr.setDerivedKeyLength(algorithmSuite.getEncryptionDerivedKeyLength() / 8);
+ dkEncr.prepare(saaj.getSOAPPart());
+
+ dkEncr.prependDKElementToHeader(secHeader);
+ refList = dkEncr.encryptForExternalRef(null, encrParts);
+
+ } catch (Exception e) {
+ policyNotAsserted(recToken, e);
+ }
+ } else {
+ try {
+ WSSecEncrypt encr = new WSSecEncrypt();
+
+ setKeyIdentifierType(encr, recToken, encrToken);
+
+ encr.setDocument(saaj.getSOAPPart());
+ setEncryptionUser(encr, encrToken, false);
+ encr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
+ encr.setKeyEncAlgo(algorithmSuite.getAsymmetricKeyWrap());
+
+ encr.prepare(saaj.getSOAPPart(),
+ getEncryptionCrypto(recToken));
+
+ if (encr.getBSTTokenId() != null) {
+ encr.appendBSTElementToHeader(secHeader);
+ }
+
+
+ Element encryptedKeyElement = encr.getEncryptedKeyElement();
+
+ //Encrypt, get hold of the ref list and add it
+ refList = encr.encryptForInternalRef(null, encrParts);
+
+ //Add internal refs
+ encryptedKeyElement.appendChild(refList);
+
+ encr.prependToHeader(secHeader);
+
+ } catch (WSSecurityException e) {
+ policyNotAsserted(recToken, e.getMessage());
+ }
+ }
+ }
+ }
+
+ private void assertUnusedTokens(TokenWrapper wrapper) {
+ Collection<AssertionInfo> ais = aim.getAssertionInfo(wrapper.getName());
+ for (AssertionInfo ai : ais) {
+ if (ai.getAssertion() == wrapper) {
+ ai.setAsserted(true);
+ }
+ }
+ ais = aim.getAssertionInfo(wrapper.getToken().getName());
+ for (AssertionInfo ai : ais) {
+ if (ai.getAssertion() == wrapper.getToken()) {
+ ai.setAsserted(true);
+ }
+ }
+ }
+ private void doSignature(Vector<WSEncryptionPart> sigParts) throws WSSecurityException {
+ Token sigToken = null;
+ TokenWrapper wrapper = null;
+ if (isRequestor()) {
+ wrapper = abinding.getInitiatorToken();
+ } else {
+ wrapper = abinding.getRecipientToken();
+ assertUnusedTokens(abinding.getInitiatorToken());
+ }
+ sigToken = wrapper.getToken();
+
+ if (sigToken.isDerivedKeys()) {
+ // Set up the encrypted key to use
+ setupEncryptedKey(wrapper, sigToken);
+
+ WSSecDKSign dkSign = new WSSecDKSign();
+ dkSign.setExternalKey(this.encryptedKeyValue, this.encryptedKeyId);
+
+ // Set the algo info
+ dkSign.setSignatureAlgorithm(abinding.getAlgorithmSuite()
+ .getSymmetricSignature());
+ dkSign.setDerivedKeyLength(abinding.getAlgorithmSuite()
+ .getSignatureDerivedKeyLength() / 8);
+ dkSign.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
+ + WSConstants.ENC_KEY_VALUE_TYPE);
+
+ try {
+ dkSign.prepare(saaj.getSOAPPart(), secHeader);
+
+ if (abinding.isTokenProtection()) {
+ sigParts.add(new WSEncryptionPart(encrKey.getId()));
+ }
+
+ dkSign.setParts(sigParts);
+
+ dkSign.addReferencesToSign(sigParts, secHeader);
+
+ // Do signature
+ dkSign.computeSignature();
+
+ // Add elements to header
+ dkSign.appendDKElementToHeader(secHeader);
+ dkSign.appendSigToHeader(secHeader);
+
+ mainSigId = addWsuIdToElement(dkSign.getSignatureElement());
+ } catch (Exception e) {
+ //REVISIT
+ e.printStackTrace();
+ }
+ } else {
+ WSSecSignature sig = getSignatureBuider(wrapper, sigToken);
+ sig.prependBSTElementToHeader(secHeader);
+
+ if (abinding.isTokenProtection()
+ && sig.getBSTTokenId() != null) {
+ sigParts.add(new WSEncryptionPart(sig.getBSTTokenId()));
+ }
+
+ sig.addReferencesToSign(sigParts, secHeader);
+ sig.computeSignature();
+
+ sig.prependToHeader(secHeader);
+
+ mainSigId = addWsuIdToElement(sig.getSignatureElement());
+ }
+ }
+
+ private void setupEncryptedKey(TokenWrapper wrapper, Token token) throws WSSecurityException {
+ if (!isRequestor() && token.isDerivedKeys()) {
+ //If we already have them, simply return
+ if (encryptedKeyId != null && encryptedKeyValue != null) {
+ return;
+ }
+
+ //Use the secret from the incoming EncryptedKey element
+ Object resultsObj = message.getExchange().getInMessage().get(WSHandlerConstants.RECV_RESULTS);
+ if (resultsObj != null) {
+ encryptedKeyId = getRequestEncryptedKeyId((Vector)resultsObj);
+ encryptedKeyValue = getRequestEncryptedKeyValue((Vector)resultsObj);
+
+ //In the case where we don't have the EncryptedKey in the
+ //request, for the control to have reached this state,
+ //the scenario MUST be a case where this is the response
+ //message by a listener created for an async client
+ //Therefor we will create a new EncryptedKey
+ if (encryptedKeyId == null && encryptedKeyValue == null) {
+ createEncryptedKey(wrapper, token);
+ }
+ } else {
+ policyNotAsserted(token, "No security results found");
+ }
+ } else {
+ createEncryptedKey(wrapper, token);
+ }
+ }
+ public static String getRequestEncryptedKeyId(Vector results) {
+
+ for (int i = 0; i < results.size(); i++) {
+ WSHandlerResult rResult =
+ (WSHandlerResult) results.get(i);
+
+ Vector wsSecEngineResults = rResult.getResults();
+ /*
+ * Scan the results for the first Signature action. Use the
+ * certificate of this Signature to set the certificate for the
+ * encryption action :-).
+ */
+ for (int j = 0; j < wsSecEngineResults.size(); j++) {
+ WSSecurityEngineResult wser =
+ (WSSecurityEngineResult) wsSecEngineResults.get(j);
+ Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+ String encrKeyId = (String)wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID);
+ if (actInt.intValue() == WSConstants.ENCR
+ && encrKeyId != null) {
+ return encrKeyId;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public static byte[] getRequestEncryptedKeyValue(Vector results) {
+
+ for (int i = 0; i < results.size(); i++) {
+ WSHandlerResult rResult =
+ (WSHandlerResult) results.get(i);
+
+ Vector wsSecEngineResults = rResult.getResults();
+ /*
+ * Scan the results for the first Signature action. Use the
+ * certificate of this Signature to set the certificate for the
+ * encryption action :-).
+ */
+ for (int j = 0; j < wsSecEngineResults.size(); j++) {
+ WSSecurityEngineResult wser =
+ (WSSecurityEngineResult) wsSecEngineResults.get(j);
+ Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+ byte[] decryptedKey = (byte[])wser.get(WSSecurityEngineResult.TAG_DECRYPTED_KEY);
+ if (actInt.intValue() == WSConstants.ENCR
+ && decryptedKey != null) {
+ return decryptedKey;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private void createEncryptedKey(TokenWrapper wrapper, Token token)
+ throws WSSecurityException {
+ //Set up the encrypted key to use
+ encrKey = this.getEncryptedKeyBuilder(wrapper, token);
+ Element bstElem = encrKey.getBinarySecurityTokenElement();
+ if (bstElem != null) {
+ // If a BST is available then use it
+ encrKey.prependBSTElementToHeader(secHeader);
+ }
+
+ // Add the EncryptedKey
+ encrKey.prependToHeader(secHeader);
+ encryptedKeyValue = encrKey.getEphemeralKey();
+ encryptedKeyId = encrKey.getId();
+
+ //Store the token for client - response verification
+ // and server - response creation
+ message.put(WSSecEncryptedKey.class.getName(), encrKey);
+ }
+
+
+
+}
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java Mon Sep 22 11:51:08 2008
@@ -19,35 +19,99 @@
package org.apache.cxf.ws.security.wss4j.policyhandlers;
+import java.io.IOException;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.cxf.Bus;
import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.helpers.MapNamespaceContext;
+import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.ws.policy.AssertionInfo;
import org.apache.cxf.ws.policy.AssertionInfoMap;
+import org.apache.cxf.ws.policy.PolicyAssertion;
+import org.apache.cxf.ws.policy.PolicyConstants;
import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.SPConstants;
import org.apache.cxf.ws.security.policy.model.Binding;
+import org.apache.cxf.ws.security.policy.model.Header;
+import org.apache.cxf.ws.security.policy.model.IssuedToken;
+import org.apache.cxf.ws.security.policy.model.Layout;
+import org.apache.cxf.ws.security.policy.model.SignedEncryptedElements;
+import org.apache.cxf.ws.security.policy.model.SignedEncryptedParts;
import org.apache.cxf.ws.security.policy.model.SupportingToken;
import org.apache.cxf.ws.security.policy.model.Token;
+import org.apache.cxf.ws.security.policy.model.TokenWrapper;
import org.apache.cxf.ws.security.policy.model.UsernameToken;
+import org.apache.cxf.ws.security.policy.model.Wss10;
+import org.apache.cxf.ws.security.policy.model.Wss11;
+import org.apache.cxf.ws.security.policy.model.X509Token;
+import org.apache.cxf.wsdl.WSDLConstants;
import org.apache.velocity.util.ClassUtils;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSUsernameTokenPrincipal;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.WSSecBase;
+import org.apache.ws.security.message.WSSecEncryptedKey;
import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecTimestamp;
import org.apache.ws.security.message.WSSecUsernameToken;
/**
*
*/
public class BindingBuilder {
- SOAPMessage saaj;
- WSSecHeader secHeader;
- AssertionInfoMap aim;
- Binding binding;
- SoapMessage message;
+ private static final Logger LOG = LogUtils.getL7dLogger(BindingBuilder.class);
+
+ protected SOAPMessage saaj;
+ protected WSSecHeader secHeader;
+ protected AssertionInfoMap aim;
+ protected Binding binding;
+ protected SoapMessage message;
+ protected WSSecTimestamp timestampEl;
+ protected String mainSigId;
+
+ protected Set<String> encryptedTokensIdList = new HashSet<String>();
+
+
public BindingBuilder(Binding binding,
SOAPMessage saaj,
@@ -62,25 +126,156 @@
}
- private boolean isRequestor() {
+ protected boolean isRequestor() {
return Boolean.TRUE.equals(message.containsKey(
org.apache.cxf.message.Message.REQUESTOR_ROLE));
}
+ protected void policyNotAsserted(PolicyAssertion assertion, Exception reason) {
+ LOG.log(Level.INFO, "Not asserting " + assertion.getName(), reason);
+ Collection<AssertionInfo> ais;
+ ais = aim.get(assertion.getName());
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ if (ai.getAssertion() == assertion) {
+ ai.setNotAsserted(reason.getMessage());
+ }
+ }
+ }
+ }
+ protected void policyNotAsserted(PolicyAssertion assertion, String reason) {
+ Collection<AssertionInfo> ais;
+ ais = aim.get(assertion.getName());
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ if (ai.getAssertion() == assertion) {
+ ai.setNotAsserted(reason);
+ }
+ }
+ }
+ }
+ protected void policyAsserted(PolicyAssertion assertion) {
+ Collection<AssertionInfo> ais;
+ ais = aim.get(assertion.getName());
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ if (ai.getAssertion() == assertion) {
+ ai.setAsserted(true);
+ }
+ }
+ }
+ }
+ protected PolicyAssertion findPolicy(QName n) {
+ Collection<AssertionInfo> ais = aim.getAssertionInfo(n);
+ if (ais != null && !ais.isEmpty()) {
+ return ais.iterator().next().getAssertion();
+ }
+ return null;
+ }
+
+ protected WSSecTimestamp createTimestamp() {
+ Collection<AssertionInfo> ais;
+ ais = aim.get(SP12Constants.INCLUDE_TIMESTAMP);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ timestampEl = new WSSecTimestamp();
+ timestampEl.prepare(saaj.getSOAPPart());
+ ai.setAsserted(true);
+ }
+ }
+ return timestampEl;
+ }
- protected void handleSupportingTokens(SupportingToken suppTokens) {
+ protected WSSecTimestamp handleLayout(WSSecTimestamp timestamp) {
+ Collection<AssertionInfo> ais;
+ ais = aim.get(SP12Constants.LAYOUT);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ Layout layout = (Layout)ai.getAssertion();
+ if (SPConstants.Layout.LaxTimestampLast == layout.getValue()) {
+ if (timestamp == null) {
+ ai.setNotAsserted(SPConstants.Layout.LaxTimestampLast + " requires a timestamp");
+ } else {
+ ai.setAsserted(true);
+ //get the timestamp into the header first before anything else
+ timestamp.prependToHeader(secHeader);
+ timestamp = null;
+ }
+ } else if (SPConstants.Layout.Strict == layout.getValue()) {
+ //FIXME - don't have strict writing working yet
+ ai.setAsserted(false);
+ } else if (SPConstants.Layout.Lax == layout.getValue()) {
+ ai.setAsserted(true);
+ //go ahead and put the timestamp in
+ timestamp.prependToHeader(secHeader);
+ timestamp = null;
+ } else {
+ ai.setAsserted(true);
+ }
+ }
+ }
+ return timestamp;
+ }
+
+ protected Map<Token, WSSecBase> handleSupportingTokens(SupportingToken suppTokens) {
+ Map<Token, WSSecBase> ret = new HashMap<Token, WSSecBase>();
+ if (suppTokens == null) {
+ return ret;
+ }
for (Token token : suppTokens.getTokens()) {
if (token instanceof UsernameToken) {
WSSecUsernameToken utBuilder = addUsernameToken((UsernameToken)token);
if (utBuilder != null) {
utBuilder.prepare(saaj.getSOAPPart());
utBuilder.appendToHeader(secHeader);
+ ret.put(token, utBuilder);
+ encryptedTokensIdList.add(utBuilder.getId());
}
- }
+ } else if (token instanceof IssuedToken && isRequestor()) {
+ //ws-trust stuff.......
+ //REVISIT
+ policyNotAsserted(token, "Issued token not yet supported");
+ } else if (token instanceof X509Token) {
+
+ //We have to use a cert
+ //Prepare X509 signature
+ WSSecSignature sig = getSignatureBuider(suppTokens, token);
+ Element bstElem = sig.getBinarySecurityTokenElement();
+ if (bstElem != null) {
+ sig.appendBSTElementToHeader(secHeader);
+ }
+ if (suppTokens.isEncryptedToken()) {
+ encryptedTokensIdList.add(sig.getBSTTokenId());
+ }
+ ret.put(token, sig);
+ }
+
}
+ return ret;
}
-
+ protected void addSignatureParts(Map<Token, WSSecBase> tokenMap,
+ List<WSEncryptionPart> sigParts) {
+
+ for (Map.Entry<Token, WSSecBase> entry : tokenMap.entrySet()) {
+
+ Object tempTok = entry.getValue();
+ WSEncryptionPart part = null;
+
+ if (tempTok instanceof WSSecSignature) {
+ WSSecSignature tempSig = (WSSecSignature) tempTok;
+ if (tempSig.getBSTTokenId() != null) {
+ part = new WSEncryptionPart(tempSig.getBSTTokenId());
+ }
+ } else {
+ policyNotAsserted(entry.getKey(), "UnsupportedTokenInSupportingToken");
+ }
+ if (part != null) {
+ sigParts.add(part);
+ }
+ }
+ }
+
protected WSSecUsernameToken addUsernameToken(UsernameToken token) {
@@ -110,35 +305,7 @@
String password = (String)message.getContextualProperty(SecurityConstants.PASSWORD);
if (StringUtils.isEmpty(password)) {
-
- //Then try to get the password from the given callback handler
- Object o = message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
-
- CallbackHandler handler = null;
- if (o instanceof CallbackHandler) {
- handler = (CallbackHandler)o;
- } else if (o instanceof String) {
- try {
- handler = (CallbackHandler)ClassUtils.getNewInstance(o.toString());
- } catch (Exception e) {
- handler = null;
- }
- }
- if (handler == null) {
- info.setNotAsserted("No callback handler and not password available");
- return null;
- }
-
- WSPasswordCallback[] cb = {new WSPasswordCallback(userName,
- WSPasswordCallback.USERNAME_TOKEN)};
- try {
- handler.handle(cb);
- } catch (Exception e) {
- //REVISIT - Exception?
- }
-
- //get the password
- password = cb[0].getPassword();
+ password = getPassword(userName, token, WSPasswordCallback.USERNAME_TOKEN);
}
if (!StringUtils.isEmpty(password)) {
@@ -161,5 +328,528 @@
}
return null;
}
+ public String getPassword(String userName, PolicyAssertion info, int type) {
+ //Then try to get the password from the given callback handler
+ Object o = message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
+
+ CallbackHandler handler = null;
+ if (o instanceof CallbackHandler) {
+ handler = (CallbackHandler)o;
+ } else if (o instanceof String) {
+ try {
+ handler = (CallbackHandler)ClassUtils.getNewInstance(o.toString());
+ } catch (Exception e) {
+ handler = null;
+ }
+ }
+ if (handler == null) {
+ policyNotAsserted(info, "No callback handler and no password available");
+ return null;
+ }
+
+ WSPasswordCallback[] cb = {new WSPasswordCallback(userName,
+ type)};
+ try {
+ handler.handle(cb);
+ } catch (Exception e) {
+ policyNotAsserted(info, e);
+ }
+
+ //get the password
+ return cb[0].getPassword();
+ }
+
+ public String addWsuIdToElement(Element elem) {
+ String id;
+
+ //first try to get the Id attr
+ Attr idAttr = elem.getAttributeNode("Id");
+ if (idAttr == null) {
+ //then try the wsu:Id value
+ idAttr = elem.getAttributeNodeNS(PolicyConstants.WSU_NAMESPACE_URI, "Id");
+ }
+
+ if (idAttr != null) {
+ id = idAttr.getValue();
+ } else {
+ //Add an id
+ id = "Id-" + elem.hashCode();
+ String pfx = elem.lookupPrefix(PolicyConstants.WSU_NAMESPACE_URI);
+ boolean found = !StringUtils.isEmpty(pfx);
+ int cnt = 0;
+ while (StringUtils.isEmpty(pfx)) {
+ pfx = "wsu" + (cnt == 0 ? "" : cnt);
+ if (!StringUtils.isEmpty(elem.lookupNamespaceURI(pfx))) {
+ pfx = null;
+ cnt++;
+ }
+ }
+ if (!found) {
+ idAttr = elem.getOwnerDocument().createAttributeNS(WSDLConstants.NS_XMLNS, "xmlns:" + pfx);
+ idAttr.setValue(PolicyConstants.WSU_NAMESPACE_URI);
+ elem.setAttributeNodeNS(idAttr);
+ }
+ idAttr = elem.getOwnerDocument().createAttributeNS(PolicyConstants.WSU_NAMESPACE_URI,
+ pfx + ":Id");
+ idAttr.setValue(id);
+ elem.setAttributeNodeNS(idAttr);
+ }
+
+ return id;
+ }
+
+ public Vector<WSEncryptionPart> getEncryptedParts()
+ throws SOAPException {
+
+ boolean isBody = false;
+
+ SignedEncryptedParts parts = null;
+ SignedEncryptedElements elements = null;
+
+ Collection<AssertionInfo> ais = aim.getAssertionInfo(SP12Constants.ENCRYPTED_PARTS);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ parts = (SignedEncryptedParts)ai.getAssertion();
+ ai.setAsserted(true);
+ }
+ }
+ ais = aim.getAssertionInfo(SP12Constants.ENCRYPTED_ELEMENTS);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ elements = (SignedEncryptedElements)ai.getAssertion();
+ ai.setAsserted(true);
+ }
+ }
+
+ List<WSEncryptionPart> signedParts = new ArrayList<WSEncryptionPart>();
+ if (parts != null) {
+ isBody = parts.isBody();
+ for (Header head : parts.getHeaders()) {
+ WSEncryptionPart wep = new WSEncryptionPart(head.getName(),
+ head.getNamespace(),
+ "Content");
+ signedParts.add(wep);
+ }
+ }
+
+
+ return getPartsAndElements(false,
+ isBody,
+ signedParts,
+ elements == null ? null : elements.getXPathExpressions(),
+ elements == null ? null : elements.getDeclaredNamespaces());
+ }
+
+ public Vector<WSEncryptionPart> getSignedParts()
+ throws SOAPException {
+
+ boolean isSignBody = false;
+
+ SignedEncryptedParts parts = null;
+ SignedEncryptedElements elements = null;
+
+ Collection<AssertionInfo> ais = aim.getAssertionInfo(SP12Constants.SIGNED_PARTS);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ parts = (SignedEncryptedParts)ai.getAssertion();
+ ai.setAsserted(true);
+ }
+ }
+ ais = aim.getAssertionInfo(SP12Constants.SIGNED_ELEMENTS);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ elements = (SignedEncryptedElements)ai.getAssertion();
+ ai.setAsserted(true);
+ }
+ }
+
+ List<WSEncryptionPart> signedParts = new ArrayList<WSEncryptionPart>();
+ if (parts != null) {
+ isSignBody = parts.isBody();
+ for (Header head : parts.getHeaders()) {
+ WSEncryptionPart wep = new WSEncryptionPart(head.getName(),
+ head.getNamespace(),
+ "Content");
+ signedParts.add(wep);
+ }
+ }
+
+
+ return getPartsAndElements(true,
+ isSignBody,
+ signedParts,
+ elements == null ? null : elements.getXPathExpressions(),
+ elements == null ? null : elements.getDeclaredNamespaces());
+ }
+ public Vector<WSEncryptionPart> getPartsAndElements(boolean sign,
+ boolean includeBody,
+ List<WSEncryptionPart> parts,
+ List<String> xpaths,
+ Map<String, String> namespaces)
+ throws SOAPException {
+
+ Vector<WSEncryptionPart> result = new Vector<WSEncryptionPart>();
+ List<Element> found = new ArrayList<Element>();
+ if (includeBody) {
+ if (sign) {
+ result.add(new WSEncryptionPart(addWsuIdToElement(saaj.getSOAPBody())));
+ } else {
+ result.add(new WSEncryptionPart(addWsuIdToElement(saaj.getSOAPBody()),
+ "Content", WSConstants.PART_TYPE_BODY));
+ }
+ found.add(saaj.getSOAPBody());
+ }
+ SOAPHeader header = saaj.getSOAPHeader();
+ for (WSEncryptionPart part : parts) {
+ if (StringUtils.isEmpty(part.getName())) {
+ //an entire namespace
+ Element el = DOMUtils.getFirstElement(header);
+ while (el != null) {
+ if (part.getNamespace().equals(el.getNamespaceURI())
+ && !found.contains(el)) {
+ found.add(el);
+
+ if (sign) {
+ result.add(new WSEncryptionPart(el.getLocalName(),
+ part.getNamespace(),
+ "Content"));
+ } else {
+ WSEncryptionPart encryptedHeader
+ = new WSEncryptionPart(el.getLocalName(),
+ part.getNamespace(),
+ "Element",
+ WSConstants.PART_TYPE_HEADER);
+ String wsuId = el.getAttributeNS(WSConstants.WSU_NS, "Id");
+
+ if (!StringUtils.isEmpty(wsuId)) {
+ encryptedHeader.setEncId(wsuId);
+ }
+ result.add(encryptedHeader);
+ }
+ }
+ }
+ el = DOMUtils.getNextElement(el);
+ } else {
+ Element el = DOMUtils.getFirstElement(header);
+ while (el != null) {
+ if (part.getName().equals(el.getLocalName())
+ && part.getNamespace().equals(el.getNamespaceURI())
+ && !found.contains(el)) {
+ found.add(el);
+ part.setType(WSConstants.PART_TYPE_HEADER);
+ String wsuId = el.getAttributeNS(WSConstants.WSU_NS, "Id");
+
+ if (!StringUtils.isEmpty(wsuId)) {
+ part.setEncId(wsuId);
+ }
+
+ result.add(part);
+ }
+ el = DOMUtils.getNextElement(el);
+ }
+ }
+ }
+ if (xpaths != null && !xpaths.isEmpty()) {
+ XPathFactory factory = XPathFactory.newInstance();
+ for (String expression : xpaths) {
+ XPath xpath = factory.newXPath();
+ if (namespaces != null) {
+ xpath.setNamespaceContext(new MapNamespaceContext(namespaces));
+ }
+ try {
+ NodeList list = (NodeList)xpath.evaluate(expression, saaj.getSOAPPart().getEnvelope(),
+ XPathConstants.NODESET);
+ for (int x = 0; x < list.getLength(); x++) {
+ Element el = (Element)list.item(x);
+ if (sign) {
+ result.add(new WSEncryptionPart(el.getLocalName(),
+ el.getNamespaceURI(),
+ "Content"));
+ } else {
+ WSEncryptionPart encryptedElem = new WSEncryptionPart(el.getLocalName(),
+ el.getNamespaceURI(),
+ "Element");
+ String wsuId = el.getAttributeNS(WSConstants.WSU_NS, "Id");
+
+ if (!StringUtils.isEmpty(wsuId)) {
+ encryptedElem.setEncId(wsuId);
+ }
+ result.add(encryptedElem);
+ }
+ }
+ } catch (XPathExpressionException e) {
+ //REVISIT!!!!
+ }
+ }
+ }
+ return result;
+ }
+
+
+ protected WSSecEncryptedKey getEncryptedKeyBuilder(TokenWrapper wrapper,
+ Token token) throws WSSecurityException {
+ WSSecEncryptedKey encrKey = new WSSecEncryptedKey();
+
+ setKeyIdentifierType(encrKey, wrapper, token);
+ setEncryptionUser(encrKey, token, false);
+ encrKey.setKeySize(binding.getAlgorithmSuite().getMaximumSymmetricKeyLength());
+ encrKey.setKeyEncAlgo(binding.getAlgorithmSuite().getAsymmetricKeyWrap());
+
+ encrKey.prepare(saaj.getSOAPPart(), getEncryptionCrypto(wrapper));
+
+ return encrKey;
+ }
+ public Crypto getSignatureCrypto(TokenWrapper wrapper) {
+ return getCrypto(wrapper, true);
+ }
+ public Crypto getEncryptionCrypto(TokenWrapper wrapper) {
+ return getCrypto(wrapper, false);
+ }
+ public Crypto getCrypto(TokenWrapper wrapper, boolean sign) {
+ Object o = message.getContextualProperty(sign
+ ? SecurityConstants.SIGNATURE_PROPERTIES
+ : SecurityConstants.ENCRYPT_PROPERTIES);
+ Properties properties = null;
+ if (o instanceof Properties) {
+ properties = (Properties)o;
+ } else if (o instanceof String) {
+ ResourceManager rm = message.getExchange().get(Bus.class).getExtension(ResourceManager.class);
+ URL url = rm.resolveResource((String)o, URL.class);
+ try {
+ if (url == null) {
+ url = ClassLoaderUtils.getResource((String)o, this.getClass());
+ }
+ if (url != null) {
+ properties = new Properties();
+ properties.load(url.openStream());
+ } else {
+ policyNotAsserted(wrapper, "Could not find properties file " + o);
+ }
+ } catch (IOException e) {
+ policyNotAsserted(wrapper, e);
+ }
+ } else if (o instanceof URL) {
+ properties = new Properties();
+ try {
+ properties.load(((URL)o).openStream());
+ } catch (IOException e) {
+ policyNotAsserted(wrapper, e);
+ }
+ }
+
+ if (properties != null) {
+ return CryptoFactory.getInstance(properties);
+ }
+ return null;
+ }
+
+ public void setKeyIdentifierType(WSSecBase secBase, TokenWrapper wrapper, Token token) {
+
+ if (token.getInclusion() == SPConstants.IncludeTokenType.INCLUDE_TOKEN_NEVER) {
+ boolean tokenTypeSet = false;
+
+ if (token instanceof X509Token) {
+ X509Token x509Token = (X509Token)token;
+ if (x509Token.isRequireIssuerSerialReference()) {
+ secBase.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ tokenTypeSet = true;
+ } else if (x509Token.isRequireKeyIdentifierReference()) {
+ secBase.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
+ tokenTypeSet = true;
+ } else if (x509Token.isRequireThumbprintReference()) {
+ secBase.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+ tokenTypeSet = true;
+ }
+ }
+
+ if (!tokenTypeSet) {
+ policyAsserted(token);
+ policyAsserted(wrapper);
+
+ Wss10 wss = getWss10();
+ policyAsserted(wss);
+ if (wss.isMustSupportRefKeyIdentifier()) {
+ secBase.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
+ } else if (wss.isMustSupportRefIssuerSerial()) {
+ secBase.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ } else if (wss instanceof Wss11
+ && ((Wss11) wss).isMustSupportRefThumbprint()) {
+ secBase.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+ }
+ }
+
+ } else {
+ policyAsserted(token);
+ policyAsserted(wrapper);
+ secBase.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+ }
+ }
+ public void setEncryptionUser(WSSecEncryptedKey encrKeyBuilder, Token token, boolean sign) {
+ String encrUser = (String)message.getContextualProperty(sign
+ ? SecurityConstants.USERNAME
+ : SecurityConstants.ENCRYPT_USERNAME);
+ if (encrUser == null || "".equals(encrUser)) {
+ policyNotAsserted(token, "No " + (sign ? "signature" : "encryption") + " username found.");
+ }
+ if (encrUser.equals(WSHandlerConstants.USE_REQ_SIG_CERT)) {
+ Object resultsObj = message.getExchange().getInMessage().get(WSHandlerConstants.RECV_RESULTS);
+ if (resultsObj != null) {
+ encrKeyBuilder.setUseThisCert(getReqSigCert((Vector)resultsObj));
+
+ //TODO This is a hack, this should not come under USE_REQ_SIG_CERT
+ if (encrKeyBuilder.isCertSet()) {
+ encrKeyBuilder.setUserInfo(getUsername((Vector)resultsObj));
+ }
+ } else {
+ policyNotAsserted(token, "No security results in incoming message");
+ }
+ } else {
+ encrKeyBuilder.setUserInfo(encrUser);
+ }
+ }
+ private static X509Certificate getReqSigCert(Vector results) {
+ /*
+ * Scan the results for a matching actor. Use results only if the
+ * receiving Actor and the sending Actor match.
+ */
+ for (int i = 0; i < results.size(); i++) {
+ WSHandlerResult rResult =
+ (WSHandlerResult) results.get(i);
+
+ Vector wsSecEngineResults = rResult.getResults();
+ /*
+ * Scan the results for the first Signature action. Use the
+ * certificate of this Signature to set the certificate for the
+ * encryption action :-).
+ */
+ for (int j = 0; j < wsSecEngineResults.size(); j++) {
+ WSSecurityEngineResult wser =
+ (WSSecurityEngineResult) wsSecEngineResults.get(j);
+ Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+ if (actInt.intValue() == WSConstants.SIGN) {
+ return (X509Certificate)wser.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Scan through <code>WSHandlerResult<code> vector for a Username token and return
+ * the username if a Username Token found
+ * @param results
+ * @return
+ */
+
+ public static String getUsername(Vector results) {
+ /*
+ * Scan the results for a matching actor. Use results only if the
+ * receiving Actor and the sending Actor match.
+ */
+ for (int i = 0; i < results.size(); i++) {
+ WSHandlerResult rResult =
+ (WSHandlerResult) results.get(i);
+
+ Vector wsSecEngineResults = rResult.getResults();
+ /*
+ * Scan the results for a username token. Use the username
+ * of this token to set the alias for the encryption user
+ */
+ for (int j = 0; j < wsSecEngineResults.size(); j++) {
+ WSSecurityEngineResult wser =
+ (WSSecurityEngineResult) wsSecEngineResults.get(j);
+ Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+ if (actInt.intValue() == WSConstants.UT) {
+ WSUsernameTokenPrincipal principal
+ = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+ return principal.getName();
+ }
+ }
+ }
+
+ return null;
+ }
+ protected Wss10 getWss10() {
+ Collection<AssertionInfo> ais = aim.getAssertionInfo(SP12Constants.WSS10);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ return (Wss10)ai.getAssertion();
+ }
+ }
+ ais = aim.getAssertionInfo(SP12Constants.WSS11);
+ if (ais != null) {
+ for (AssertionInfo ai : ais) {
+ return (Wss10)ai.getAssertion();
+ }
+ }
+ return null;
+ }
+
+ private void checkForX509PkiPath(WSSecSignature sig, Token token) {
+ if (token instanceof X509Token) {
+ X509Token x509Token = (X509Token) token;
+ if (x509Token.getTokenVersionAndType().equals(SPConstants.WSS_X509_PKI_PATH_V1_TOKEN10)
+ || x509Token.getTokenVersionAndType().equals(SPConstants.WSS_X509_PKI_PATH_V1_TOKEN11)) {
+ sig.setUseSingleCertificate(false);
+ }
+ }
+ }
+ protected WSSecSignature getSignatureBuider(TokenWrapper wrapper, Token token) {
+ WSSecSignature sig = new WSSecSignature();
+ checkForX509PkiPath(sig, token);
+
+ setKeyIdentifierType(sig, wrapper, token);
+
+ String user = (String)message.getContextualProperty(SecurityConstants.USERNAME);
+ if (StringUtils.isEmpty(user)) {
+ policyNotAsserted(token, "No signature username found.");
+ }
+
+ String password = getPassword(user, token, WSPasswordCallback.SIGNATURE);
+ if (StringUtils.isEmpty(password)) {
+ policyNotAsserted(token, "No password found.");
+ }
+
+ sig.setUserInfo(user, password);
+ sig.setSignatureAlgorithm(binding.getAlgorithmSuite().getAsymmetricSignature());
+ sig.setSigCanonicalization(binding.getAlgorithmSuite().getInclusiveC14n());
+
+ try {
+ sig.prepare(saaj.getSOAPPart(),
+ getSignatureCrypto(wrapper),
+ secHeader);
+ } catch (WSSecurityException e) {
+ policyNotAsserted(token, e);
+ }
+
+ return sig;
+ }
+
+ protected void doEndorsedSignatures(Map<Token, WSSecBase> tokenMap,
+ boolean isTokenProtection) {
+
+ for (Map.Entry<Token, WSSecBase> ent : tokenMap.entrySet()) {
+ WSSecBase tempTok = ent.getValue();
+
+ Vector<WSEncryptionPart> sigParts = new Vector<WSEncryptionPart>();
+ sigParts.add(new WSEncryptionPart(mainSigId));
+
+ if (tempTok instanceof WSSecSignature) {
+ WSSecSignature sig = (WSSecSignature)tempTok;
+ if (isTokenProtection && sig.getBSTTokenId() != null) {
+ sigParts.add(new WSEncryptionPart(sig.getBSTTokenId()));
+ }
+ try {
+ sig.addReferencesToSign(sigParts, secHeader);
+ sig.computeSignature();
+ sig.appendToHeader(secHeader);
+ } catch (WSSecurityException e) {
+ policyNotAsserted(ent.getKey(), e);
+ }
+
+ }
+ }
+ }
}
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java Mon Sep 22 11:51:08 2008
@@ -27,8 +27,6 @@
import org.apache.cxf.ws.policy.AssertionInfo;
import org.apache.cxf.ws.policy.AssertionInfoMap;
import org.apache.cxf.ws.security.policy.SP12Constants;
-import org.apache.cxf.ws.security.policy.SPConstants;
-import org.apache.cxf.ws.security.policy.model.Layout;
import org.apache.cxf.ws.security.policy.model.SupportingToken;
import org.apache.cxf.ws.security.policy.model.TransportBinding;
import org.apache.ws.security.message.WSSecHeader;
@@ -51,36 +49,9 @@
public void handleBinding() {
Collection<AssertionInfo> ais;
- WSSecTimestamp timestamp = null;
- ais = aim.get(SP12Constants.INCLUDE_TIMESTAMP);
- if (ais != null) {
- for (AssertionInfo ai : ais) {
- timestamp = new WSSecTimestamp();
- timestamp.prepare(saaj.getSOAPPart());
- ai.setAsserted(true);
- }
- }
- ais = aim.get(SP12Constants.LAYOUT);
- if (ais != null) {
- for (AssertionInfo ai : ais) {
- Layout layout = (Layout)ai.getAssertion();
- if (SPConstants.Layout.LaxTimestampLast == layout.getValue()) {
- if (timestamp == null) {
- ai.setAsserted(false);
- } else {
- ai.setAsserted(true);
- //get the timestamp into the header first before anything else
- timestamp.prependToHeader(secHeader);
- timestamp = null;
- }
- } else if (SPConstants.Layout.Strict == layout.getValue()) {
- //FIXME - don't have strict writing working yet
- ai.setAsserted(false);
- } else {
- ai.setAsserted(true);
- }
- }
- }
+ WSSecTimestamp timestamp = createTimestamp();
+ timestamp = handleLayout(timestamp);
+
ais = aim.get(SP12Constants.SIGNED_SUPPORTING_TOKENS);
if (ais != null) {
SupportingToken sgndSuppTokens = null;
Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java Mon Sep 22 11:51:08 2008
@@ -33,6 +33,7 @@
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.policytest.doubleit.DoubleItPortType;
import org.apache.cxf.policytest.doubleit.DoubleItService;
+import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
import org.apache.cxf.ws.policy.PolicyEngine;
import org.apache.cxf.ws.security.SecurityConstants;
@@ -44,6 +45,7 @@
public class SecurityPolicyTest extends AbstractBusClientServerTestBase {
public static final String POLICY_ADDRESS = "http://localhost:9010/SecPolTest";
public static final String POLICY_HTTPS_ADDRESS = "https://localhost:9009/SecPolTest";
+ public static final String POLICY_ENC_ADDRESS = "http://localhost:9010/SecPolTestEncrypt";
public static class ServerPasswordCallback implements CallbackHandler {
@@ -73,6 +75,20 @@
new ServerPasswordCallback());
Endpoint.publish(POLICY_ADDRESS,
new DoubleItImpl());
+
+ ep = (EndpointImpl)Endpoint.publish(POLICY_ENC_ADDRESS,
+ new DoubleItImplEncrypt());
+
+ EndpointInfo ei = ep.getServer().getEndpoint().getEndpointInfo();
+ ei.setProperty(SecurityConstants.CALLBACK_HANDLER, new ServerPasswordCallback());
+
+ ei.setProperty(SecurityConstants.USERNAME, "alice");
+ ei.setProperty(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());
+ ei.setProperty(SecurityConstants.SIGNATURE_PROPERTIES,
+ SecurityPolicyTest.class.getResource("alice.properties").toString());
+ ei.setProperty(SecurityConstants.ENCRYPT_USERNAME, "bob");
+ ei.setProperty(SecurityConstants.ENCRYPT_PROPERTIES,
+ SecurityPolicyTest.class.getResource("bob.properties").toString());
}
@Test
@@ -80,6 +96,17 @@
DoubleItService service = new DoubleItService();
DoubleItPortType pt;
+ pt = service.getDoubleItPortEncrypt();
+ ((BindingProvider)pt).getRequestContext().put(SecurityConstants.USERNAME, "alice");
+ ((BindingProvider)pt).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER,
+ new KeystorePasswordCallback());
+ ((BindingProvider)pt).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES,
+ getClass().getResource("alice.properties"));
+ ((BindingProvider)pt).getRequestContext().put(SecurityConstants.ENCRYPT_USERNAME, "Bob");
+ ((BindingProvider)pt).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES,
+ getClass().getResource("bob.properties"));
+ pt.doubleIt(BigInteger.valueOf(5));
+
pt = service.getDoubleItPortHttps();
try {
pt.doubleIt(BigInteger.valueOf(25));
@@ -131,4 +158,15 @@
return numberToDouble.multiply(new BigInteger("2"));
}
}
+ @WebService(targetNamespace = "http://cxf.apache.org/policytest/DoubleIt",
+ portName = "DoubleItPortEncrypt",
+ serviceName = "DoubleItService",
+ endpointInterface = "org.apache.cxf.policytest.doubleit.DoubleItPortType",
+ wsdlLocation = "classpath:/wsdl_systest/DoubleIt.wsdl")
+ public static class DoubleItImplEncrypt implements DoubleItPortType {
+ /** {@inheritDoc}*/
+ public BigInteger doubleIt(BigInteger numberToDouble) {
+ return numberToDouble.multiply(new BigInteger("2"));
+ }
+ }
}
Modified: cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl (original)
+++ cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl Mon Sep 22 11:51:08 2008
@@ -68,6 +68,16 @@
<wsdl:output><soap:body use="literal"/></wsdl:output>
</wsdl:operation>
</wsdl:binding>
+ <wsdl:binding name="DoubleItBindingEncrypt" type="tns:DoubleItPortType">
+ <wsp:PolicyReference URI="#DoubleItEncryptPolicy"/>
+ <soap:binding style="document"
+ transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="DoubleIt">
+ <soap:operation soapAction=""/>
+ <wsdl:input><soap:body use="literal"/></wsdl:input>
+ <wsdl:output><soap:body use="literal"/></wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
<wsdl:service name="DoubleItService">
<wsdl:port name="DoubleItPortHttps" binding="tns:DoubleItBinding">
<soap:address
@@ -77,6 +87,10 @@
<soap:address
location="http://localhost:9010/SecPolTest"/>
</wsdl:port>
+ <wsdl:port name="DoubleItPortEncrypt" binding="tns:DoubleItBindingEncrypt">
+ <soap:address
+ location="http://localhost:9010/SecPolTestEncrypt"/>
+ </wsdl:port>
</wsdl:service>
<wsp:Policy wsu:Id="DoubleItBindingPolicy">
@@ -123,5 +137,58 @@
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
+ <wsp:Policy wsu:Id="DoubleItEncryptPolicy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:InitiatorToken>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:WssX509V1Token11/>
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:InitiatorToken>
+ <sp:RecipientToken>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
+ <wsp:Policy>
+ <sp:WssX509V1Token11/>
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:RecipientToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:TripleDesRsa15/>
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Lax/>
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp/>
+ <sp:EncryptSignature/>
+ <sp:OnlySignEntireHeadersAndBody/>
+ </wsp:Policy>
+ </sp:AsymmetricBinding>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body/>
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body/>
+ </sp:EncryptedParts>
+ <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <!-- sp:MustSupportRefKeyIdentifier/-->
+ <sp:MustSupportRefIssuerSerial/>
+ </wsp:Policy>
+ </sp:Wss10>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
</wsdl:definitions>
Modified: cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java
URL: http://svn.apache.org/viewvc/cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java (original)
+++ cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java Mon Sep 22 11:51:08 2008
@@ -174,7 +174,7 @@
}
inProcessServer.startInProcess();
serverIsReady = true;
- } catch (Exception ex) {
+ } catch (Throwable ex) {
ex.printStackTrace();
serverLaunchFailed = true;
}