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 2009/03/04 21:46:29 UTC
svn commit: r750151 - in
/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security: ./
policy/builders/ tokenstore/ trust/ wss4j/policyhandlers/
Author: dkulp
Date: Wed Mar 4 20:46:28 2009
New Revision: 750151
URL: http://svn.apache.org/viewvc?rev=750151&view=rev
Log:
Wire in the new KeyValue stuff Colm added to WSS4J
We now pass 100% MS InteropPlugFest ws-trust10 cxf client -> MS services
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/KeyValueTokenBuilder.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=750151&r1=750150&r2=750151&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java Wed Mar 4 20:46:28 2009
@@ -43,16 +43,21 @@
public static final String TOKEN = "ws-security.token";
public static final String TOKEN_ID = "ws-security.token.id";
-
+
public static final String STS_CLIENT = "ws-security.sts.client";
/**
* WCF's trust server sometimes will encrypt the token in the response IN ADDITION TO
* the full security on the message. These properties control the way the STS client
* will decrypt the EncryptedData elements in the response
+ *
+ * These are also used by the STSClient to send/process any RSA/DSAKeyValue tokens
+ * used if the KeyType is "PublicKey"
*/
public static final String STS_TOKEN_CRYPTO = "ws-security.sts.token.crypto";
public static final String STS_TOKEN_PROPERTIES = "ws-security.sts.token.properties";
+ public static final String STS_TOKEN_USERNAME = "ws-security.sts.token.username";
+
public static final Set<String> ALL_PROPERTIES;
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/KeyValueTokenBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/KeyValueTokenBuilder.java?rev=750151&r1=750150&r2=750151&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/KeyValueTokenBuilder.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/builders/KeyValueTokenBuilder.java Wed Mar 4 20:46:28 2009
@@ -25,6 +25,7 @@
import org.w3c.dom.Element;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.ws.policy.AssertionBuilder;
import org.apache.cxf.ws.policy.PolicyAssertion;
@@ -36,21 +37,30 @@
public class KeyValueTokenBuilder implements AssertionBuilder {
+ private static final String MS_NS = "http://schemas.microsoft.com/ws/2005/07/securitypolicy";
private static final List<QName> KNOWN_ELEMENTS
- = Arrays.asList(SP12Constants.KEYVALUE_TOKEN);
+ = Arrays.asList(SP12Constants.KEYVALUE_TOKEN,
+ new QName(MS_NS, "RsaToken"));
public KeyValueTokenBuilder() {
}
public PolicyAssertion build(Element element) {
- SPConstants consts = SP11Constants.SP_NS.equals(element.getNamespaceURI())
+ SPConstants consts = MS_NS.equals(element.getNamespaceURI())
? SP11Constants.INSTANCE : SP12Constants.INSTANCE;
KeyValueToken token = new KeyValueToken(consts);
String attribute = element.getAttributeNS(element.getNamespaceURI(), SPConstants.ATTR_INCLUDE_TOKEN);
- if (attribute != null) {
+ if (StringUtils.isEmpty(attribute)) {
+ attribute = element.getAttributeNS(consts.getNamespace(), SPConstants.ATTR_INCLUDE_TOKEN);
+ }
+ if (StringUtils.isEmpty(attribute)) {
+ attribute = element.getAttributeNS(SP11Constants.INSTANCE.getNamespace(),
+ SPConstants.ATTR_INCLUDE_TOKEN);
+ }
+ if (!StringUtils.isEmpty(attribute)) {
token.setInclusion(consts.getInclusionFromAttributeValue(attribute));
}
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java?rev=750151&r1=750150&r2=750151&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/SecurityToken.java Wed Mar 4 20:46:28 2009
@@ -19,6 +19,7 @@
package org.apache.cxf.ws.security.tokenstore;
+import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Properties;
@@ -31,6 +32,7 @@
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.staxutils.W3CDOMStreamWriter;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.message.token.Reference;
@@ -126,6 +128,10 @@
* The tokenType
*/
private String tokenType;
+
+ private X509Certificate x509cert;
+
+ private Crypto crypto;
public SecurityToken() {
@@ -399,6 +405,16 @@
}
return null;
}
+ public void setX509Certificate(X509Certificate cert, Crypto cpt) {
+ x509cert = cert;
+ crypto = cpt;
+ }
+ public X509Certificate getX509Certificate() {
+ return x509cert;
+ }
+ public Crypto getCrypto() {
+ return crypto;
+ }
}
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java?rev=750151&r1=750150&r2=750151&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java Wed Mar 4 20:46:28 2009
@@ -21,7 +21,10 @@
import java.io.IOException;
import java.net.URL;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
import java.util.Date;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -80,6 +83,7 @@
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyComponent;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
@@ -91,6 +95,8 @@
import org.apache.ws.security.util.Base64;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.ws.security.util.XmlSchemaDateFormat;
+import org.apache.xml.security.keys.content.keyvalues.DSAKeyValue;
+import org.apache.xml.security.keys.content.keyvalues.RSAKeyValue;
/**
*
@@ -309,22 +315,11 @@
writer.writeCharacters(namespace + requestType);
writer.writeEndElement();
addAppliesTo(writer, appliesTo);
- if (isSecureConv) {
- addLifetime(writer);
- if (keyType == null) {
- writer.writeStartElement("wst", "TokenType", namespace);
- writer.writeCharacters(STSUtils.getTokenTypeSCT(namespace));
- writer.writeEndElement();
- keyType = namespace + "/SymmetricKey";
- }
- } else if (keyType == null) {
- writer.writeStartElement("wst", "KeyType", namespace);
- writer.writeCharacters(namespace + "/SymmetricKey");
- writer.writeEndElement();
- keyType = namespace + "/SymmetricKey";
- }
+ keyType = writeKeyType(writer, keyType);
byte[] requestorEntropy = null;
+ X509Certificate cert = null;
+ Crypto crypto = null;
if (keyType.endsWith("SymmetricKey")) {
if (!wroteKeySize && !isSecureConv) {
@@ -352,14 +347,17 @@
writer.writeStartElement("wst", "UseKey", namespace);
writer.writeStartElement("http://www.w3.org/2000/09/xmldsig#", "KeyInfo");
writer.writeStartElement("http://www.w3.org/2000/09/xmldsig#", "KeyValue");
-
- /*
- //REVISIT - KeyValueToken support - how to get the key?
- RSAPublicKey key = getPublicKey();
-
- RSAKeyValue value = new RSAKeyValue(writer.getDocument(), key);
- StaxUtils.copy(value.getElement(), writer);
- */
+ crypto = createCrypto(false);
+ cert = getCert(crypto);
+ PublicKey key = cert.getPublicKey();
+ String pubKeyAlgo = key.getAlgorithm();
+ if ("DSA".equalsIgnoreCase(pubKeyAlgo)) {
+ DSAKeyValue dsaKeyValue = new DSAKeyValue(writer.getDocument(), key);
+ writer.getCurrentNode().appendChild(dsaKeyValue.getElement());
+ } else if ("RSA".equalsIgnoreCase(pubKeyAlgo)) {
+ RSAKeyValue rsaKeyValue = new RSAKeyValue(writer.getDocument(), key);
+ writer.getCurrentNode().appendChild(rsaKeyValue.getElement());
+ }
writer.writeEndElement();
writer.writeEndElement();
@@ -379,7 +377,11 @@
Object obj[] = client.invoke(boi,
new DOMSource(writer.getDocument().getDocumentElement()));
- return createSecurityToken((Document)((DOMSource)obj[0]).getNode(), requestorEntropy);
+ SecurityToken token = createSecurityToken((Document)((DOMSource)obj[0]).getNode(), requestorEntropy);
+ if (cert != null) {
+ token.setX509Certificate(cert, crypto);
+ }
+ return token;
}
public void renewSecurityToken(SecurityToken tok) throws Exception {
String action = null;
@@ -388,7 +390,40 @@
}
requestSecurityToken(tok.getIssuerAddress(), action, "/Renew", tok);
}
-
+
+ private String writeKeyType(W3CDOMStreamWriter writer, String keyType) throws XMLStreamException {
+ if (isSecureConv) {
+ addLifetime(writer);
+ if (keyType == null) {
+ writer.writeStartElement("wst", "TokenType", namespace);
+ writer.writeCharacters(STSUtils.getTokenTypeSCT(namespace));
+ writer.writeEndElement();
+ keyType = namespace + "/SymmetricKey";
+ }
+ } else if (keyType == null) {
+ writer.writeStartElement("wst", "KeyType", namespace);
+ writer.writeCharacters(namespace + "/SymmetricKey");
+ writer.writeEndElement();
+ keyType = namespace + "/SymmetricKey";
+ }
+ return keyType;
+ }
+ private X509Certificate getCert(Crypto crypto) throws Exception {
+ String alias = (String)getProperty(SecurityConstants.STS_TOKEN_USERNAME);
+ if (alias == null) {
+ alias = crypto.getDefaultX509Alias();
+ }
+ if (alias == null) {
+ Enumeration<String> as = crypto.getKeyStore().aliases();
+ if (as.hasMoreElements()) {
+ alias = as.nextElement();
+ }
+ if (as.hasMoreElements()) {
+ throw new Fault("No alias specified for retrieving PublicKey", LOG);
+ }
+ }
+ return crypto.getCertificates(alias)[0];
+ }
private void addLifetime(XMLStreamWriter writer) throws XMLStreamException {
Date creationTime = new Date();
Date expirationTime = new Date();
@@ -417,7 +452,8 @@
}
}
- private SecurityToken createSecurityToken(Document document, byte[] requestorEntropy)
+ private SecurityToken createSecurityToken(Document document,
+ byte[] requestorEntropy)
throws WSSecurityException {
Element el = document.getDocumentElement();
@@ -460,17 +496,14 @@
} catch (IOException e1) {
throw new TrustException(e1);
}
-
String id = findID(rar, rur, rstDec);
if (StringUtils.isEmpty(id)) {
throw new TrustException(new Message("NO_ID", LOG));
- }
-
+ }
SecurityToken token = new SecurityToken(id, rstDec, lte);
token.setAttachedReference(rar);
token.setUnattachedReference(rur);
token.setIssuerAddress(location);
-
byte[] secret = null;
@@ -487,7 +520,7 @@
EncryptedKeyProcessor processor = new EncryptedKeyProcessor();
- processor.handleToken(child, null, createCrypto(),
+ processor.handleToken(child, null, createCrypto(true),
createHandler(), null, new Vector(),
null);
@@ -526,21 +559,20 @@
secret = requestorEntropy;
}
token.setSecret(secret);
-
+
return token;
}
protected Element decrypt(Element firstElement) throws IOException {
if ("EncryptedData".equals(firstElement.getLocalName())
&& "http://www.w3.org/2001/04/xmlenc#".equals(firstElement.getNamespaceURI())) {
-
Node parent = firstElement.getParentNode();
Node prev = firstElement.getPreviousSibling();
//encrypted even more. WCF seems to do this periodically
EncryptedDataProcessor processor = new EncryptedDataProcessor();
- processor.handleToken(firstElement, null, createCrypto(),
+ processor.handleToken(firstElement, null, createCrypto(true),
createHandler(), null, new Vector(),
null);
@@ -549,7 +581,6 @@
} else {
firstElement = (Element)prev.getNextSibling();
}
-
}
return firstElement;
}
@@ -582,14 +613,15 @@
return o;
}
- private Crypto createCrypto() throws IOException {
- Crypto crypto = (Crypto)getProperty(SecurityConstants.STS_TOKEN_CRYPTO);
+ private Crypto createCrypto(boolean decrypt) throws IOException {
+ WSSConfig.getDefaultWSConfig();
+ Crypto crypto = (Crypto)getProperty(SecurityConstants.STS_TOKEN_CRYPTO + (decrypt ? ".decrypt" : ""));
if (crypto != null) {
return crypto;
}
- Object o = getProperty(SecurityConstants.STS_TOKEN_PROPERTIES);
+ Object o = getProperty(SecurityConstants.STS_TOKEN_PROPERTIES + (decrypt ? ".decrypt" : ""));
Properties properties = null;
if (o instanceof Properties) {
properties = (Properties)o;
@@ -613,6 +645,9 @@
if (properties != null) {
return CryptoFactory.getInstance(properties);
}
+ if (decrypt) {
+ return createCrypto(false);
+ }
return null;
}
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java?rev=750151&r1=750150&r2=750151&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java Wed Mar 4 20:46:28 2009
@@ -61,6 +61,7 @@
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.helpers.MapNamespaceContext;
+import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.ws.policy.AssertionInfo;
@@ -75,6 +76,7 @@
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.KeyValueToken;
import org.apache.cxf.ws.security.policy.model.Layout;
import org.apache.cxf.ws.security.policy.model.SecureConversationToken;
import org.apache.cxf.ws.security.policy.model.SignedEncryptedElements;
@@ -417,8 +419,49 @@
this.encryptedTokensIdList.add(secToken.getId());
}
- //Add the extracted token
- ret.put(token, new WSSecurityTokenHolder(secToken));
+ if (secToken.getX509Certificate() == null) {
+ //Add the extracted token
+ ret.put(token, new WSSecurityTokenHolder(secToken));
+ } else {
+ WSSecSignature sig = new WSSecSignature();
+ sig.setX509Certificate(secToken.getX509Certificate());
+ sig.setCustomTokenId(secToken.getId());
+ sig.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
+ if (secToken.getTokenType() == null) {
+ sig.setCustomTokenValueType(WSConstants.WSS_SAML_NS
+ + WSConstants.SAML_ASSERTION_ID);
+ } else {
+ sig.setCustomTokenValueType(secToken.getTokenType());
+ }
+ sig.setSignatureAlgorithm(binding.getAlgorithmSuite().getAsymmetricSignature());
+ sig.setSigCanonicalization(binding.getAlgorithmSuite().getInclusiveC14n());
+
+ Crypto crypto = secToken.getCrypto();
+ String uname = null;
+ try {
+ uname = crypto.getKeyStore().getCertificateAlias(secToken.getX509Certificate());
+ } catch (KeyStoreException e1) {
+ throw new Fault(e1);
+ }
+
+ String password = getPassword(uname, token, WSPasswordCallback.SIGNATURE);
+ if (password == null) {
+ password = "";
+ }
+ sig.setUserInfo(uname, password);
+ try {
+ sig.prepare(saaj.getSOAPPart(),
+ secToken.getCrypto(),
+ secHeader);
+ } catch (WSSecurityException e) {
+ throw new Fault(e);
+ }
+
+ if (suppTokens.isEncryptedToken()) {
+ encryptedTokensIdList.add(sig.getBSTTokenId());
+ }
+ ret.put(token, sig);
+ }
} else if (token instanceof X509Token) {
//We have to use a cert
@@ -432,7 +475,13 @@
encryptedTokensIdList.add(sig.getBSTTokenId());
}
ret.put(token, sig);
- }
+ } else if (token instanceof KeyValueToken) {
+ WSSecSignature sig = getSignatureBuider(suppTokens, token, endorse);
+ if (suppTokens.isEncryptedToken()) {
+ encryptedTokensIdList.add(sig.getBSTTokenId());
+ }
+ ret.put(token, sig);
+ }
}
return ret;
@@ -880,7 +929,10 @@
secBase.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
tokenTypeSet = true;
}
- }
+ } else if (token instanceof KeyValueToken) {
+ secBase.setKeyIdentifierType(WSConstants.KEY_VALUE);
+ tokenTypeSet = true;
+ }
if (!tokenTypeSet) {
policyAsserted(token);
@@ -1104,7 +1156,8 @@
}
protected void doEndorsedSignatures(Map<Token, WSSecBase> tokenMap,
- boolean isTokenProtection) {
+ boolean isTokenProtection,
+ boolean isSigProtect) {
for (Map.Entry<Token, WSSecBase> ent : tokenMap.entrySet()) {
WSSecBase tempTok = ent.getValue();
@@ -1123,6 +1176,9 @@
sig.appendToHeader(secHeader);
signatures.add(sig.getSignatureValue());
+ if (isSigProtect) {
+ encryptedTokensIdList.add(sig.getId());
+ }
} catch (WSSecurityException e) {
policyNotAsserted(ent.getKey(), e);
}
@@ -1344,20 +1400,23 @@
protected void doEndorse() {
boolean tokenProtect = false;
+ boolean sigProtect = false;
if (binding instanceof AsymmetricBinding) {
tokenProtect = ((AsymmetricBinding)binding).isTokenProtection();
+ sigProtect = ((AsymmetricBinding)binding).isSignatureProtection();
} else if (binding instanceof SymmetricBinding) {
tokenProtect = ((SymmetricBinding)binding).isTokenProtection();
+ sigProtect = ((SymmetricBinding)binding).isSignatureProtection();
}
// Adding the endorsing encrypted supporting tokens to endorsing supporting tokens
endSuppTokMap.putAll(endEncSuppTokMap);
// Do endorsed signatures
- doEndorsedSignatures(endSuppTokMap, tokenProtect);
+ doEndorsedSignatures(endSuppTokMap, tokenProtect, sigProtect);
//Adding the signed endorsed encrypted tokens to signed endorsed supporting tokens
sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
// Do signed endorsing signatures
- doEndorsedSignatures(sgndEndSuppTokMap, tokenProtect);
+ doEndorsedSignatures(sgndEndSuppTokMap, tokenProtect, sigProtect);
}
protected void addSignatureConfirmation(Vector<WSEncryptionPart> sigParts) {