You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by co...@apache.org on 2010/05/17 16:22:03 UTC
svn commit: r945177 - in /webservices/wss4j/trunk:
src/org/apache/ws/security/processor/ src/org/apache/ws/security/transform/
test/ test/wssec/
Author: coheigea
Date: Mon May 17 14:22:02 2010
New Revision: 945177
URL: http://svn.apache.org/viewvc?rev=945177&view=rev
Log:
[WSS-222] - Applied patch for "SignatureProcessor does not provide correct signature coverage results with STR Dereference Transform"
- Thanks to David for the patch and test-case.
- This took me a while to modify, due to the use of JSR-105 on trunk.
Added:
webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java (with props)
Modified:
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java
webservices/wss4j/trunk/test/log4j.properties
webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java?rev=945177&r1=945176&r2=945177&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java Mon May 17 14:22:02 2010
@@ -43,20 +43,25 @@ import org.apache.ws.security.message.to
import org.apache.ws.security.message.token.X509Security;
import org.apache.ws.security.saml.SAMLKeyInfo;
import org.apache.ws.security.saml.SAMLUtil;
+import org.apache.ws.security.transform.STRApacheTransform;
+import org.apache.ws.security.transform.STRTransformUtil;
import org.apache.ws.security.util.WSSecurityUtil;
import org.opensaml.SAMLAssertion;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.NodeSetData;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.XMLValidateContext;
@@ -381,6 +386,7 @@ public class SignatureProcessor implemen
key = WSSecurityUtil.prepareSecretKey(signatureMethod, secretKey);
}
XMLValidateContext context = new DOMValidateContext(key, elem);
+ context.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
try {
XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
boolean signatureOk = xmlSignature.validate(context);
@@ -388,7 +394,7 @@ public class SignatureProcessor implemen
signatureValue = xmlSignature.getSignatureValue().getValue();
protectedRefs =
buildProtectedRefs(
- elem.getOwnerDocument(), xmlSignature.getSignedInfo(), protectedRefs
+ elem.getOwnerDocument(), xmlSignature.getSignedInfo(), wsDocInfo, protectedRefs
);
return principal;
@@ -778,15 +784,50 @@ public class SignatureProcessor implemen
*/
private static List buildProtectedRefs(
Document doc,
- SignedInfo signedInfo,
+ SignedInfo signedInfo,
+ WSDocInfo wsDocInfo,
List protectedRefs
) throws WSSecurityException {
List referencesList = signedInfo.getReferences();
for (int i = 0; i < referencesList.size(); i++) {
Reference siRef = (Reference)referencesList.get(i);
String uri = siRef.getURI();
+
if (!"".equals(uri)) {
- Element se = WSSecurityUtil.getElementByWsuId(doc, uri);
+ Element se = null;
+
+ List transformsList = siRef.getTransforms();
+
+ for (int j = 0; j < transformsList.size(); j++) {
+
+ Transform transform = (Transform)transformsList.get(j);
+
+ if (STRApacheTransform.TRANSFORM_URI.equals(transform.getAlgorithm())) {
+ NodeSetData data = (NodeSetData)siRef.getDereferencedData();
+ if (data != null) {
+ java.util.Iterator iter = data.iterator();
+
+ Node securityTokenReference = null;
+ while (iter.hasNext()) {
+ Node node = (Node)iter.next();
+ if ("SecurityTokenReference".equals(node.getLocalName())) {
+ securityTokenReference = node;
+ break;
+ }
+ }
+
+ if (securityTokenReference != null) {
+ SecurityTokenReference secTokenRef =
+ new SecurityTokenReference((Element)securityTokenReference);
+ se = STRTransformUtil.dereferenceSTR(doc, secTokenRef, wsDocInfo);
+ }
+ }
+ }
+ }
+
+ if (se == null) {
+ se = WSSecurityUtil.getElementByWsuId(doc, uri);
+ }
if (se == null) {
se = WSSecurityUtil.getElementByGenId(doc, uri);
}
Modified: webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java?rev=945177&r1=945176&r2=945177&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java Mon May 17 14:22:02 2010
@@ -26,7 +26,6 @@ import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSDocInfoStore;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.message.token.SecurityTokenReference;
-import org.apache.ws.security.message.token.X509Security;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.Canonicalizer;
@@ -34,17 +33,13 @@ import org.apache.xml.security.c14n.Inva
import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.transforms.Transform;
import org.apache.xml.security.transforms.TransformSpi;
-import org.apache.ws.security.util.Base64;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import org.w3c.dom.Text;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
/**
@@ -187,7 +182,8 @@ public class STRTransform extends Transf
//
// Third and fourth step are performed by derefenceSTR()
//
- Element dereferencedToken = dereferenceSTR(thisDoc, secRef);
+ Element dereferencedToken = STRTransformUtil.dereferenceSTR(
+ thisDoc, secRef, wsDocInfo);
//
// C14n with specified algorithm. According to WSS Specification.
//
@@ -250,92 +246,4 @@ public class STRTransform extends Transf
throw (new CanonicalizationException("c14n.Canonicalizer.Exception", ex));
}
}
-
- private Element dereferenceSTR(Document doc, SecurityTokenReference secRef)
- throws WSSecurityException {
- //
- // Third step: locate the security token referenced by the STR element.
- // Either the Token is contained in the document as a
- // BinarySecurityToken or stored in some key storage.
- //
- // Fourth step: after security token was located, prepare it. If its
- // reference via a direct reference, i.e. a relative URI that references
- // the BST directly in the message then just return that element.
- // Otherwise wrap the located token in a newly created BST element as
- // described in WSS Specification.
- //
- //
- Element tokElement = null;
-
- //
- // First case: direct reference, according to chap 7.2 of OASIS WS
- // specification (main document). Only in this case return a true
- // reference to the BST. Copying is done by the caller.
- //
- if (secRef.containsReference()) {
- if (doDebug) {
- log.debug("STR: Reference");
- }
- tokElement = secRef.getTokenElement(doc, wsDocInfo, null);
- }
- //
- // second case: IssuerSerial, lookup in keystore, wrap in BST according
- // to specification
- //
- else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
- if (doDebug) {
- log.debug("STR: IssuerSerial");
- }
- X509Certificate cert = null;
- X509Certificate[] certs =
- secRef.getX509IssuerSerial(wsDocInfo.getCrypto());
- if (certs == null || certs.length == 0 || certs[0] == null) {
- throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
- }
- cert = certs[0];
- tokElement = createBSTX509(doc, cert, secRef.getElement());
- }
- //
- // third case: KeyIdentifier. For SKI, lookup in keystore, wrap in
- // BST according to specification. Otherwise if it's a wsse:KeyIdentifier it could
- // be a SAML assertion, so try and find the referenced element.
- //
- else if (secRef.containsKeyIdentifier()) {
- if (doDebug) {
- log.debug("STR: KeyIdentifier");
- }
- if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
- tokElement = secRef.getKeyIdentifierTokenElement(doc, wsDocInfo, null);
- } else {
- X509Certificate cert = null;
- X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo.getCrypto());
- if (certs == null || certs.length == 0 || certs[0] == null) {
- throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
- }
- cert = certs[0];
- tokElement = createBSTX509(doc, cert, secRef.getElement());
- }
- }
- return tokElement;
- }
-
- private Element createBSTX509(Document doc, X509Certificate cert, Element secRefE)
- throws WSSecurityException {
- byte data[];
- try {
- data = cert.getEncoded();
- } catch (CertificateEncodingException e) {
- throw new WSSecurityException(
- WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e
- );
- }
- String prefix =
- WSSecurityUtil.setNamespace(secRefE, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
- Element elem = doc.createElementNS(WSConstants.WSSE_NS, prefix + ":BinarySecurityToken");
- elem.setAttributeNS(null, "ValueType", X509Security.X509_V3_TYPE);
- Text certText = doc.createTextNode(Base64.encode(data)); // no line wrap
- elem.appendChild(certText);
- return elem;
- }
-
}
Added: webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java?rev=945177&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java (added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java Mon May 17 14:22:02 2010
@@ -0,0 +1,156 @@
+/**
+ * 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.ws.security.transform;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * Utility class exposing the dereferencing logic of the {@link STRTransform} implementation.
+ */
+public class STRTransformUtil {
+ private static Log log = LogFactory.getLog(STRTransformUtil.class.getName());
+
+ /**
+ * Retrieves the element representing the referenced content of a STR.
+ *
+ * @return the element representing the referenced content. The element is either
+ * extracted from {@code doc} or a new element is created in the
+ * case of a key identifier or issuer serial STR. {@code null} if
+ * {@code secRef} does not contain a direct reference, key identifier, or
+ * issuer serial.
+ * @throws WSSecurityException
+ * If an issuer serial or key identifier is used in the STR and
+ * the certificate cannot be resolved from the crypto
+ * configuration or if there is an error working with the resolved
+ * cert
+ */
+ public static Element dereferenceSTR(Document doc,
+ SecurityTokenReference secRef, WSDocInfo wsDocInfo) throws WSSecurityException
+ {
+
+ // NOTE: Here step numbers refer to the overall step in the complete processing
+ // of the STRTransform. See STRTransform for the lead up to these steps.
+ //
+ // Third step: locate the security token referenced by the STR element.
+ // Either the Token is contained in the document as a
+ // BinarySecurityToken or stored in some key storage.
+ //
+ // Fourth step: after security token was located, prepare it. If its
+ // reference via a direct reference, i.e. a relative URI that references
+ // the BST directly in the message then just return that element.
+ // Otherwise wrap the located token in a newly created BST element as
+ // described in WSS Specification.
+ //
+ //
+ Element tokElement = null;
+
+ //
+ // First case: direct reference, according to chap 7.2 of OASIS WS
+ // specification (main document). Only in this case return a true
+ // reference to the BST. Copying is done by the caller.
+ //
+ if (secRef.containsReference()) {
+ if (log.isDebugEnabled()) {
+ log.debug("STR: Reference");
+ }
+ tokElement = secRef.getTokenElement(doc, wsDocInfo, null);
+ }
+ //
+ // second case: IssuerSerial, lookup in keystore, wrap in BST according
+ // to specification
+ //
+ else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
+ if (log.isDebugEnabled()) {
+ log.debug("STR: IssuerSerial");
+ }
+ X509Certificate cert = null;
+ X509Certificate[] certs =
+ secRef.getX509IssuerSerial(wsDocInfo.getCrypto());
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+ }
+ cert = certs[0];
+ tokElement = createBSTX509(doc, cert, secRef.getElement());
+ }
+ //
+ // third case: KeyIdentifier. For SKI, lookup in keystore, wrap in
+ // BST according to specification. Otherwise if it's a wsse:KeyIdentifier it could
+ // be a SAML assertion, so try and find the referenced element.
+ //
+ else if (secRef.containsKeyIdentifier()) {
+ if (log.isDebugEnabled()) {
+ log.debug("STR: KeyIdentifier");
+ }
+ if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
+ tokElement = secRef.getKeyIdentifierTokenElement(doc, wsDocInfo, null);
+ } else {
+ X509Certificate cert = null;
+ X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo.getCrypto());
+ if (certs == null || certs.length == 0 || certs[0] == null) {
+ throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+ }
+ cert = certs[0];
+ tokElement = createBSTX509(doc, cert, secRef.getElement());
+ }
+ }
+ return tokElement;
+ }
+
+ protected static Element createBSTX509(Document doc, X509Certificate cert, Element secRefE)
+ throws WSSecurityException {
+ byte data[];
+ try {
+ data = cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e
+ );
+ }
+ String prefix = WSSecurityUtil.getPrefixNS(WSConstants.WSSE_NS, secRefE);
+ Element elem = doc.createElementNS(WSConstants.WSSE_NS, prefix + ":BinarySecurityToken");
+ WSSecurityUtil.setNamespace(elem, WSConstants.WSSE_NS, prefix);
+ // elem.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", "");
+ elem.setAttributeNS(null, "ValueType", X509Security.X509_V3_TYPE);
+ Text certText = doc.createTextNode(Base64.encode(data)); // no line wrap
+ elem.appendChild(certText);
+ return elem;
+ }
+
+ /**
+ * Hidden in utility class.
+ */
+ private STRTransformUtil() {
+ }
+
+}
\ No newline at end of file
Propchange: webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransformUtil.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: webservices/wss4j/trunk/test/log4j.properties
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/log4j.properties?rev=945177&r1=945176&r2=945177&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/log4j.properties (original)
+++ webservices/wss4j/trunk/test/log4j.properties Mon May 17 14:22:02 2010
@@ -43,6 +43,7 @@
# log4j.logger.wssec.TestWSSecurityNew9=DEBUG
# log4j.logger.wssec.TestWSSecurity10=DEBUG
# log4j.logger.wssec.TestWSSecurity11=DEBUG
+# log4j.logger.wssec.TestWSSecurityNew11=DEBUG
# log4j.logger.wssec.TestWSSecurity12=DEBUG
# log4j.logger.wssec.TestWSSecurity13=DEBUG
# log4j.logger.wssec.TestWSSecurity14=DEBUG
@@ -54,6 +55,7 @@
# log4j.logger.wssec.TestWSSecurityST3=DEBUG
# log4j.logger.wssec.TestWSSecurityNewST3=DEBUG
# log4j.logger.wssec.TestWSSecuritySOAP12=DEBUG
+# log4j.logger.wssec.TestWSSecuritySignatureParts=DEBUG
# log4j.logger.org.apache.ws.security.handler.WSS4JHandler=DEBUG
# log4j.logger.org.apache.ws.security.handler.WSHandler=DEBUG
log4j.logger.policy.WSSPolicyTesterAsymm=DEBUG
Modified: webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java?rev=945177&r1=945176&r2=945177&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java Mon May 17 14:22:02 2010
@@ -36,7 +36,11 @@ import org.apache.ws.security.components
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.saml.SAMLIssuer;
+import org.apache.ws.security.saml.SAMLIssuerFactory;
+import org.apache.ws.security.saml.WSSecSignatureSAML;
import org.apache.ws.security.util.WSSecurityUtil;
+import org.opensaml.SAMLAssertion;
import org.w3c.dom.Document;
import javax.security.auth.callback.Callback;
@@ -147,6 +151,66 @@ public class TestWSSecuritySignaturePart
}
/**
+ * Test signing of a header through a STR Dereference Transform
+ */
+ public void testSOAPHeaderSTRTransform() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
+
+ SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml4.properties");
+ // Provide info to SAML issuer that it can construct a Holder-of-key
+ // SAML token.
+ saml.setInstanceDoc(doc);
+ saml.setUserCrypto(crypto);
+ saml.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
+ SAMLAssertion assertion = saml.newAssertion();
+
+ WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+ wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+ wsSign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ List parts = new Vector();
+ WSEncryptionPart encP =
+ new WSEncryptionPart("STRTransform", "", "Element");
+ parts.add(encP);
+ wsSign.setParts(parts);
+
+ LOG.info("Before SAMLSignedKeyHolder....");
+
+ //
+ // set up for keyHolder
+ //
+ Document signedDoc = wsSign.build(doc, crypto, assertion, null, null, null, secHeader);
+ LOG.info("After SAMLSignedKeyHolder....");
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Signed SAML message (key holder):");
+ String outputString =
+ org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ List results = verify(signedDoc);
+ WSSecurityEngineResult stUnsignedActionResult =
+ WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+ SAMLAssertion receivedAssertion =
+ (SAMLAssertion) stUnsignedActionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+ assertTrue(receivedAssertion != null);
+
+ WSSecurityEngineResult signActionResult =
+ WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
+ assertTrue(signActionResult != null);
+ final java.util.List refs =
+ (java.util.List) signActionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+ assertTrue(signActionResult != null && !signActionResult.isEmpty());
+ WSDataRef wsDataRef = (WSDataRef)refs.get(0);
+ String xpath = wsDataRef.getXpath();
+ assertEquals("/soapenv:Envelope/soapenv:Header/wsse:Security/Assertion", xpath);
+ }
+
+ /**
* Test signing a custom SOAP header with a bad localname
*/
public void testBadLocalname() throws Exception {
---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org