You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by gi...@apache.org on 2011/09/18 15:51:36 UTC
svn commit: r1172285 [21/48] - in /webservices/wss4j/branches/swssf: ./
cxf-integration/ cxf-integration/src/ cxf-integration/src/main/
cxf-integration/src/main/java/ cxf-integration/src/main/java/org/
cxf-integration/src/main/java/org/swssf/ cxf-integ...
Added: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureEndingOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureEndingOutputProcessor.java?rev=1172285&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureEndingOutputProcessor.java (added)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureEndingOutputProcessor.java Sun Sep 18 13:51:23 2011
@@ -0,0 +1,242 @@
+/**
+ * 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.swssf.impl.processor.output;
+
+import org.apache.commons.codec.binary.Base64;
+import org.swssf.ext.*;
+import org.swssf.impl.SignaturePartDef;
+import org.swssf.impl.algorithms.SignatureAlgorithm;
+import org.swssf.impl.algorithms.SignatureAlgorithmFactory;
+import org.swssf.impl.util.SignerOutputStream;
+import org.swssf.securityEvent.SecurityEvent;
+import org.swssf.securityEvent.SignatureValueSecurityEvent;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.*;
+
+/**
+ * @author $Author$
+ * @version $Revision$ $Date$
+ */
+public class SignatureEndingOutputProcessor extends AbstractBufferingOutputProcessor {
+
+ private List<SignaturePartDef> signaturePartDefList;
+
+ public SignatureEndingOutputProcessor(SecurityProperties securityProperties, Constants.Action action, SignatureOutputProcessor signatureOutputProcessor) throws WSSecurityException {
+ super(securityProperties, action);
+ this.getAfterProcessors().add(SignatureOutputProcessor.class.getName());
+ this.getAfterProcessors().add(UsernameTokenOutputProcessor.class.getName());
+ signaturePartDefList = signatureOutputProcessor.getSignaturePartDefList();
+ }
+
+ @Override
+ public void doFinal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ setAppendAfterThisTokenId(outputProcessorChain.getSecurityContext().<String>get(Constants.PROP_APPEND_SIGNATURE_ON_THIS_ID));
+ super.doFinal(outputProcessorChain);
+ }
+
+ /*
+ <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-1022834285">
+ <ds:SignedInfo>
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
+ <ds:Reference URI="#id-1612925417">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+ <ds:DigestValue>cy/khx5N6UobCJ1EbX+qnrGID2U=</ds:DigestValue>
+ </ds:Reference>
+ <ds:Reference URI="#Timestamp-1106985890">
+ <ds:Transforms>
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ </ds:Transforms>
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+ <ds:DigestValue>+p5YRII6uvUdsJ7XLKkWx1CBewE=</ds:DigestValue>
+ </ds:Reference>
+ </ds:SignedInfo>
+ <ds:SignatureValue>
+ Izg1FlI9oa4gOon2vTXi7V0EpiyCUazECVGYflbXq7/3GF8ThKGDMpush/fo1I2NVjEFTfmT2WP/
+ +ZG5N2jASFptrcGbsqmuLE5JbxUP1TVKb9SigKYcOQJJ8klzmVfPXnSiRZmIU+DUT2UXopWnGNFL
+ TwY0Uxja4ZuI6U8m8Tg=
+ </ds:SignatureValue>
+ <ds:KeyInfo Id="KeyId-1043455692">
+ <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-1008354042">
+ <wsse:Reference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" URI="#CertId-3458500" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
+ </wsse:SecurityTokenReference>
+ </ds:KeyInfo>
+ </ds:Signature>
+ */
+
+ protected void processHeaderEvent(OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+
+ OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
+
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Id, "Signature-" + UUID.randomUUID().toString());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Signature, attributes);
+
+ SignatureAlgorithm signatureAlgorithm;
+
+ try {
+ signatureAlgorithm = SignatureAlgorithmFactory.getInstance().getSignatureAlgorithm(getSecurityProperties().getSignatureAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (NoSuchProviderException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noSecProvider", e);
+ }
+
+ String tokenId = outputProcessorChain.getSecurityContext().get(Constants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE);
+ if (tokenId == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE);
+ }
+ SecurityTokenProvider wrappingSecurityTokenProvider = outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
+ if (wrappingSecurityTokenProvider == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE);
+ }
+ final SecurityToken wrappingSecurityToken = wrappingSecurityTokenProvider.getSecurityToken(null);
+ if (wrappingSecurityToken == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE);
+ }
+
+ signatureAlgorithm.engineInitSign(wrappingSecurityToken.getSecretKey(getSecurityProperties().getSignatureAlgorithm(), null));
+
+ SignedInfoProcessor signedInfoProcessor = new SignedInfoProcessor(getSecurityProperties(), getAction(), signatureAlgorithm);
+ subOutputProcessorChain.addProcessor(signedInfoProcessor);
+
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_SignedInfo, null);
+
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Algorithm, getSecurityProperties().getSignatureCanonicalizationAlgorithm());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_CanonicalizationMethod, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_CanonicalizationMethod);
+
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Algorithm, getSecurityProperties().getSignatureAlgorithm());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_SignatureMethod, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_SignatureMethod);
+
+ Iterator<SignaturePartDef> signaturePartDefIterator = signaturePartDefList.iterator();
+ while (signaturePartDefIterator.hasNext()) {
+ SignaturePartDef signaturePartDef = signaturePartDefIterator.next();
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_URI, "#" + signaturePartDef.getSigRefId());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Reference, attributes);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Transforms, null);
+
+ if (signaturePartDef.getTransformAlgo() != null) {
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Algorithm, signaturePartDef.getTransformAlgo());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Transform, attributes);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_TransformationParameters, null);
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Algorithm, signaturePartDef.getC14nAlgo());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_CanonicalizationMethod, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_CanonicalizationMethod);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_TransformationParameters);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Transform);
+ } else {
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Algorithm, signaturePartDef.getC14nAlgo());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Transform, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Transform);
+ }
+
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Transforms);
+
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Algorithm, getSecurityProperties().getSignatureDigestAlgorithm());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_DigestMethod, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_DigestMethod);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_DigestValue, null);
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, signaturePartDef.getDigestValue());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_DigestValue);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Reference);
+ }
+
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_SignedInfo);
+ subOutputProcessorChain.removeProcessor(signedInfoProcessor);
+
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_SignatureValue, null);
+ final byte[] signatureValue = signedInfoProcessor.getSignatureValue();
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(signatureValue));
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_SignatureValue);
+
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Id, "KeyId-" + UUID.randomUUID().toString());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_KeyInfo, attributes);
+ createSecurityTokenReferenceStructureForSignature(subOutputProcessorChain, wrappingSecurityToken, getSecurityProperties().getSignatureKeyIdentifierType(), getSecurityProperties().isUseSingleCert());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_KeyInfo);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_Signature);
+
+ SignatureValueSecurityEvent signatureValueSecurityEvent = new SignatureValueSecurityEvent(SecurityEvent.Event.SignatureValue);
+ signatureValueSecurityEvent.setSignatureValue(signatureValue);
+ outputProcessorChain.getSecurityContext().registerSecurityEvent(signatureValueSecurityEvent);
+ }
+
+ class SignedInfoProcessor extends AbstractOutputProcessor {
+
+ private SignerOutputStream signerOutputStream;
+ private OutputStream bufferedSignerOutputStream;
+ private Transformer transformer;
+
+ SignedInfoProcessor(SecurityProperties securityProperties, Constants.Action action, SignatureAlgorithm signatureAlgorithm) throws WSSecurityException {
+ super(securityProperties, action);
+ this.getAfterProcessors().add(SignatureEndingOutputProcessor.class.getName());
+
+ signerOutputStream = new SignerOutputStream(signatureAlgorithm);
+ bufferedSignerOutputStream = new BufferedOutputStream(signerOutputStream);
+
+ try {
+ transformer = Utils.getTransformer(null, this.bufferedSignerOutputStream, getSecurityProperties().getSignatureCanonicalizationAlgorithm());
+ } catch (NoSuchMethodException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (InstantiationException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (IllegalAccessException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (InvocationTargetException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ }
+
+ public byte[] getSignatureValue() throws WSSecurityException {
+ try {
+ bufferedSignerOutputStream.close();
+ return signerOutputStream.sign();
+ } catch (IOException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ }
+
+ @Override
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ transformer.transform(xmlEvent);
+ outputProcessorChain.processEvent(xmlEvent);
+ }
+ }
+}
Propchange: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureEndingOutputProcessor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureOutputProcessor.java?rev=1172285&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureOutputProcessor.java (added)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureOutputProcessor.java Sun Sep 18 13:51:23 2011
@@ -0,0 +1,240 @@
+/**
+ * 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.swssf.impl.processor.output;
+
+import org.apache.commons.codec.binary.Base64;
+import org.swssf.config.JCEAlgorithmMapper;
+import org.swssf.ext.*;
+import org.swssf.impl.SignaturePartDef;
+import org.xmlsecurity.ns.configuration.AlgorithmType;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.*;
+
+/**
+ * @author $Author$
+ * @version $Revision$ $Date$
+ */
+public class SignatureOutputProcessor extends AbstractOutputProcessor {
+
+ private List<SecurePart> secureParts;
+ private List<SignaturePartDef> signaturePartDefList = new LinkedList<SignaturePartDef>();
+
+ private InternalSignatureOutputProcessor activeInternalSignatureOutputProcessor = null;
+
+ public SignatureOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ super(securityProperties, action);
+ secureParts = securityProperties.getSignatureSecureParts();
+ }
+
+ public List<SignaturePartDef> getSignaturePartDefList() {
+ return signaturePartDefList;
+ }
+
+ @Override
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ if (xmlEvent.isStartElement()) {
+ StartElement startElement = xmlEvent.asStartElement();
+
+ //avoid double signature when child elements matches too
+ if (activeInternalSignatureOutputProcessor == null) {
+ SecurePart securePart = securePartMatches(startElement, outputProcessorChain);
+ if (securePart != null) {
+
+ logger.debug("Matched securePart for signature");
+ InternalSignatureOutputProcessor internalSignatureOutputProcessor = null;
+ try {
+ SignaturePartDef signaturePartDef = new SignaturePartDef();
+ if (securePart.getIdToSign() == null) {
+ signaturePartDef.setSigRefId("id-" + UUID.randomUUID().toString());
+ signaturePartDef.setC14nAlgo(getSecurityProperties().getSignatureCanonicalizationAlgorithm());
+
+ boolean found = false;
+ List<Attribute> attributeList = new ArrayList<Attribute>();
+ @SuppressWarnings("unchecked")
+ Iterator<Attribute> attributeIterator = startElement.getAttributes();
+ while (attributeIterator.hasNext()) {
+ Attribute attribute = attributeIterator.next();
+ if (attribute.getName().equals(Constants.ATT_wsu_Id)) {
+ signaturePartDef.setSigRefId(attribute.getValue());
+ found = true;
+ }
+ }
+ if (!found) {
+ attributeList.add(createAttribute(Constants.ATT_wsu_Id, signaturePartDef.getSigRefId()));
+ xmlEvent = cloneStartElementEvent(xmlEvent, attributeList);
+ }
+ } else {
+ if (Constants.SOAPMESSAGE_NS10_STRTransform.equals(securePart.getName())) {
+ signaturePartDef.setSigRefId(securePart.getIdToReference());
+ signaturePartDef.setTransformAlgo(Constants.SOAPMESSAGE_NS10_STRTransform);
+ signaturePartDef.setC14nAlgo(Constants.NS_C14N_EXCL);
+ } else {
+ signaturePartDef.setSigRefId(securePart.getIdToSign());
+ signaturePartDef.setC14nAlgo(getSecurityProperties().getSignatureCanonicalizationAlgorithm());
+ }
+ }
+
+ signaturePartDefList.add(signaturePartDef);
+ internalSignatureOutputProcessor = new InternalSignatureOutputProcessor(getSecurityProperties(), getAction(), signaturePartDef, startElement.getName());
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, "unsupportedKeyTransp",
+ e, "No such algorithm: " + getSecurityProperties().getSignatureAlgorithm()
+ );
+ } catch (NoSuchProviderException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noSecProvider", e);
+ }
+
+ activeInternalSignatureOutputProcessor = internalSignatureOutputProcessor;
+ outputProcessorChain.addProcessor(internalSignatureOutputProcessor);
+ }
+ }
+ }
+ outputProcessorChain.processEvent(xmlEvent);
+ }
+
+ private SecurePart securePartMatches(StartElement startElement, OutputProcessorChain outputProcessorChain) {
+ SecurePart securePart = securePartMatches(startElement, this.secureParts);
+ if (securePart != null) {
+ return securePart;
+ }
+ List<SecurePart> secureParts = outputProcessorChain.getSecurityContext().getAsList(SecurePart.class);
+ if (secureParts == null) {
+ return null;
+ }
+ return securePartMatches(startElement, secureParts);
+ }
+
+ private SecurePart securePartMatches(StartElement startElement, List<SecurePart> secureParts) {
+ Iterator<SecurePart> securePartIterator = secureParts.iterator();
+ while (securePartIterator.hasNext()) {
+ SecurePart securePart = securePartIterator.next();
+ if (securePart.getIdToSign() == null) {
+ if (startElement.getName().getLocalPart().equals(securePart.getName())
+ && startElement.getName().getNamespaceURI().equals(securePart.getNamespace())) {
+ return securePart;
+ }
+ } else {
+ @SuppressWarnings("unchecked")
+ Iterator<Attribute> attributeIterator = startElement.getAttributes();
+ while (attributeIterator.hasNext()) {
+ Attribute attribute = attributeIterator.next();
+ if (attribute != null) {
+ QName attributeName = attribute.getName();
+ if ((attributeName.equals(Constants.ATT_wsu_Id)
+ || attributeName.equals(Constants.ATT_NULL_Id)
+ || attributeName.equals(Constants.ATT_NULL_ID)
+ || attributeName.equals(Constants.ATT_NULL_AssertionID))
+ && attribute.getValue().equals(securePart.getIdToSign())) {
+ return securePart;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ class InternalSignatureOutputProcessor extends AbstractOutputProcessor {
+
+ private SignaturePartDef signaturePartDef;
+ private QName startElement;
+ private int elementCounter = 0;
+
+ private OutputStream bufferedDigestOutputStream;
+ private org.swssf.impl.util.DigestOutputStream digestOutputStream;
+ private Transformer transformer;
+
+ InternalSignatureOutputProcessor(SecurityProperties securityProperties, Constants.Action action, SignaturePartDef signaturePartDef, QName startElement) throws WSSecurityException, NoSuchProviderException, NoSuchAlgorithmException {
+ super(securityProperties, action);
+ this.getAfterProcessors().add(SignatureOutputProcessor.class.getName());
+ this.getBeforeProcessors().add(SignatureEndingOutputProcessor.class.getName());
+ this.getBeforeProcessors().add(InternalSignatureOutputProcessor.class.getName());
+ this.signaturePartDef = signaturePartDef;
+ this.startElement = startElement;
+
+ AlgorithmType algorithmID = JCEAlgorithmMapper.getAlgorithmMapping(getSecurityProperties().getSignatureDigestAlgorithm());
+ MessageDigest messageDigest = MessageDigest.getInstance(algorithmID.getJCEName(), algorithmID.getJCEProvider());
+ this.digestOutputStream = new org.swssf.impl.util.DigestOutputStream(messageDigest);
+ this.bufferedDigestOutputStream = new BufferedOutputStream(digestOutputStream);
+
+ try {
+ if (signaturePartDef.getTransformAlgo() != null) {
+ Transformer transformer = Utils.getTransformer("#default", this.bufferedDigestOutputStream, signaturePartDef.getC14nAlgo());
+ this.transformer = Utils.getTransformer(transformer, null, signaturePartDef.getTransformAlgo());
+ } else {
+ transformer = Utils.getTransformer(null, this.bufferedDigestOutputStream, signaturePartDef.getC14nAlgo());
+ }
+ } catch (NoSuchMethodException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (InstantiationException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (IllegalAccessException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (InvocationTargetException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ }
+
+ @Override
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+
+ transformer.transform(xmlEvent);
+
+ if (xmlEvent.isStartElement()) {
+ elementCounter++;
+ } else if (xmlEvent.isEndElement()) {
+ elementCounter--;
+
+ EndElement endElement = xmlEvent.asEndElement();
+
+ if (endElement.getName().equals(this.startElement) && elementCounter == 0) {
+ try {
+ bufferedDigestOutputStream.close();
+ } catch (IOException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ String calculatedDigest = new String(Base64.encodeBase64(this.digestOutputStream.getDigestValue()));
+ logger.debug("Calculated Digest: " + calculatedDigest);
+ signaturePartDef.setDigestValue(calculatedDigest);
+
+ outputProcessorChain.removeProcessor(this);
+ //from now on signature is possible again
+ activeInternalSignatureOutputProcessor = null;
+ xmlEvent = createEndElement(startElement);
+ }
+ }
+ outputProcessorChain.processEvent(xmlEvent);
+ }
+ }
+}
Propchange: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/SignatureOutputProcessor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/TimestampOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/TimestampOutputProcessor.java?rev=1172285&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/TimestampOutputProcessor.java (added)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/TimestampOutputProcessor.java Sun Sep 18 13:51:23 2011
@@ -0,0 +1,86 @@
+/**
+ * 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.swssf.impl.processor.output;
+
+import org.swssf.ext.*;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**
+ * @author $Author$
+ * @version $Revision$ $Date$
+ */
+public class TimestampOutputProcessor extends AbstractOutputProcessor {
+
+ public TimestampOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ super(securityProperties, action);
+ }
+
+ /*
+ <wsu:Timestamp wsu:Id="Timestamp-1247751600"
+ xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+ <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+ 2009-08-31T05:37:57.391Z
+ </wsu:Created>
+ <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+ 2009-08-31T05:52:57.391Z
+ </wsu:Expires>
+ </wsu:Timestamp>
+ */
+
+ @Override
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ outputProcessorChain.processEvent(xmlEvent);
+ if (xmlEvent.isStartElement()) {
+ StartElement startElement = xmlEvent.asStartElement();
+ if (outputProcessorChain.getDocumentContext().isInSecurityHeader() && startElement.getName().equals(Constants.TAG_wsse_Security)) {
+ try {
+ DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
+ XMLGregorianCalendar created = datatypeFactory.newXMLGregorianCalendar(new GregorianCalendar());
+
+ GregorianCalendar expiresCalendar = new GregorianCalendar();
+ expiresCalendar.add(Calendar.SECOND, getSecurityProperties().getTimestampTTL());
+ XMLGregorianCalendar expires = datatypeFactory.newXMLGregorianCalendar(expiresCalendar);
+
+ OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
+ //wsu:id is optional and will be added when signing...
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Timestamp, null);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Created, null);
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, created.toXMLFormat());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Created);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Expires, null);
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, expires.toXMLFormat());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Expires);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Timestamp);
+ } catch (DatatypeConfigurationException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
+ }
+
+ outputProcessorChain.removeProcessor(this);
+ }
+ }
+ }
+}
Propchange: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/TimestampOutputProcessor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/UsernameTokenOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/UsernameTokenOutputProcessor.java?rev=1172285&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/UsernameTokenOutputProcessor.java (added)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/UsernameTokenOutputProcessor.java Sun Sep 18 13:51:23 2011
@@ -0,0 +1,173 @@
+/**
+ * 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.swssf.impl.processor.output;
+
+import org.apache.commons.codec.binary.Base64;
+import org.swssf.crypto.Crypto;
+import org.swssf.ext.*;
+import org.swssf.impl.securityToken.UsernameSecurityToken;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.util.*;
+
+/**
+ * @author $Author$
+ * @version $Revision$ $Date$
+ */
+public class UsernameTokenOutputProcessor extends AbstractOutputProcessor {
+
+ public UsernameTokenOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ super(securityProperties, action);
+ }
+
+ @Override
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+
+ try {
+ WSPasswordCallback pwCb = new WSPasswordCallback(getSecurityProperties().getTokenUser(), WSPasswordCallback.Usage.USERNAME_TOKEN);
+ Utils.doPasswordCallback(getSecurityProperties().getCallbackHandler(), pwCb);
+ String password = pwCb.getPassword();
+ Constants.UsernameTokenPasswordType usernameTokenPasswordType = getSecurityProperties().getUsernameTokenPasswordType();
+
+ if (password == null && usernameTokenPasswordType != null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
+ }
+
+ byte[] nonceValue = new byte[16];
+ Constants.secureRandom.nextBytes(nonceValue);
+
+ DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
+ XMLGregorianCalendar created = datatypeFactory.newXMLGregorianCalendar(new GregorianCalendar());
+
+ final String wsuId = "UsernameToken-" + UUID.randomUUID().toString();
+
+ final OutputProcessor outputProcessor = this;
+
+ final UsernameSecurityToken usernameSecurityToken =
+ new UsernameSecurityToken(
+ getSecurityProperties().getTokenUser(),
+ password,
+ created != null ? created.toXMLFormat() : null,
+ nonceValue,
+ null,
+ null,
+ outputProcessorChain.getSecurityContext(),
+ wsuId,
+ outputProcessor
+ );
+
+ SecurityTokenProvider securityTokenProvider = new SecurityTokenProvider() {
+ public SecurityToken getSecurityToken(Crypto crypto) throws WSSecurityException {
+ return usernameSecurityToken;
+ }
+
+ public String getId() {
+ return wsuId;
+ }
+ };
+ if (getAction() == Constants.Action.USERNAMETOKEN_SIGNED) {
+ outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(wsuId, securityTokenProvider);
+ outputProcessorChain.getSecurityContext().put(Constants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE, wsuId);
+ outputProcessorChain.getSecurityContext().put(Constants.PROP_APPEND_SIGNATURE_ON_THIS_ID, wsuId);
+ }
+ outputProcessorChain.addProcessor(new FinalUsernameTokenOutputProcessor(getSecurityProperties(), getAction(), wsuId, nonceValue, password, created));
+
+ } catch (DatatypeConfigurationException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
+ } finally {
+ outputProcessorChain.removeProcessor(this);
+ }
+ outputProcessorChain.processEvent(xmlEvent);
+ }
+
+ class FinalUsernameTokenOutputProcessor extends AbstractOutputProcessor {
+
+ private String wsuId = null;
+ private byte[] nonceValue = null;
+ private String password = null;
+ private XMLGregorianCalendar created = null;
+
+ FinalUsernameTokenOutputProcessor(SecurityProperties securityProperties, Constants.Action action, String wsuId,
+ byte[] nonceValue, String password, XMLGregorianCalendar created)
+ throws WSSecurityException {
+ super(securityProperties, action);
+ this.getAfterProcessors().add(UsernameTokenOutputProcessor.class.getName());
+ this.getAfterProcessors().add(UsernameTokenOutputProcessor.class.getName());
+ this.wsuId = wsuId;
+ this.nonceValue = nonceValue;
+ this.password = password;
+ this.created = created;
+ }
+
+ @Override
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ outputProcessorChain.processEvent(xmlEvent);
+ if (xmlEvent.isStartElement()) {
+ StartElement startElement = xmlEvent.asStartElement();
+ if (outputProcessorChain.getDocumentContext().isInSecurityHeader() && startElement.getName().equals(Constants.TAG_wsse_Security)) {
+ OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
+
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_wsu_Id, this.wsuId);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_UsernameToken, attributes);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_Username, null);
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, getSecurityProperties().getTokenUser());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_Username);
+ if (getSecurityProperties().getUsernameTokenPasswordType() != Constants.UsernameTokenPasswordType.PASSWORD_NONE) {
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_Type,
+ getSecurityProperties().getUsernameTokenPasswordType() == Constants.UsernameTokenPasswordType.PASSWORD_DIGEST
+ ? Constants.UsernameTokenPasswordType.PASSWORD_DIGEST.getNamespace()
+ : Constants.UsernameTokenPasswordType.PASSWORD_TEXT.getNamespace());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_Password, attributes);
+ createCharactersAndOutputAsEvent(subOutputProcessorChain,
+ getSecurityProperties().getUsernameTokenPasswordType() == Constants.UsernameTokenPasswordType.PASSWORD_DIGEST
+ ? Utils.doPasswordDigest(this.nonceValue, this.created.toXMLFormat(), this.password)
+ : this.password);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_Password);
+ }
+
+ if (getSecurityProperties().getUsernameTokenPasswordType() == Constants.UsernameTokenPasswordType.PASSWORD_DIGEST
+ || Arrays.binarySearch(getSecurityProperties().getOutAction(), Constants.Action.USERNAMETOKEN_SIGNED) >= 0) {
+ attributes = new HashMap<QName, String>();
+ attributes.put(Constants.ATT_NULL_EncodingType, Constants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_Nonce, attributes);
+
+
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(this.nonceValue));
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_Nonce);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Created, null);
+
+ createCharactersAndOutputAsEvent(subOutputProcessorChain, this.created.toXMLFormat());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsu_Created);
+ }
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsse_UsernameToken);
+
+ outputProcessorChain.removeProcessor(this);
+ }
+ }
+ }
+ }
+}
Propchange: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/processor/output/UsernameTokenOutputProcessor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLBootstrap.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLBootstrap.java?rev=1172285&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLBootstrap.java (added)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLBootstrap.java Sun Sep 18 13:51:23 2011
@@ -0,0 +1,86 @@
+/**
+ * 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.swssf.impl.saml;
+
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.xml.ConfigurationException;
+
+/**
+ * This class intializes the Opensaml library. It is necessary to override DefaultBootstrap
+ * to avoid instantiating Velocity, which we do not need in WSS4J.
+ */
+public class OpenSAMLBootstrap extends DefaultBootstrap {
+
+ /**
+ * List of default XMLTooling configuration files.
+ */
+ private static String[] xmlToolingConfigs = {
+ "/default-config.xml",
+ "/schema-config.xml",
+ "/signature-config.xml",
+ "/signature-validation-config.xml",
+ "/encryption-config.xml",
+ "/encryption-validation-config.xml",
+ "/soap11-config.xml",
+ "/wsfed11-protocol-config.xml",
+ "/saml1-assertion-config.xml",
+ "/saml1-protocol-config.xml",
+ "/saml1-core-validation-config.xml",
+ "/saml2-assertion-config.xml",
+ "/saml2-protocol-config.xml",
+ "/saml2-core-validation-config.xml",
+ "/saml1-metadata-config.xml",
+ "/saml2-metadata-config.xml",
+ "/saml2-metadata-validation-config.xml",
+ "/saml2-metadata-idp-discovery-config.xml",
+ "/saml2-protocol-thirdparty-config.xml",
+ "/saml2-metadata-query-config.xml",
+ "/saml2-assertion-delegation-restriction-config.xml",
+ "/saml2-ecp-config.xml",
+ "/xacml10-saml2-profile-config.xml",
+ "/xacml11-saml2-profile-config.xml",
+ "/xacml20-context-config.xml",
+ "/xacml20-policy-config.xml",
+ "/xacml2-saml2-profile-config.xml",
+ "/xacml3-saml2-profile-config.xml",
+ "/wsaddressing-config.xml",
+ "/wssecurity-config.xml",
+ };
+
+ /**
+ * Initializes the OpenSAML library, loading default configurations.
+ *
+ * @throws org.opensaml.xml.ConfigurationException
+ * thrown if there is a problem initializing the OpenSAML library
+ */
+ public static synchronized void bootstrap() throws ConfigurationException {
+
+ initializeXMLSecurity();
+
+ initializeXMLTooling(xmlToolingConfigs);
+
+ initializeArtifactBuilderFactories();
+
+ initializeGlobalSecurityConfiguration();
+
+ initializeParserPool();
+ }
+
+}
Propchange: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLBootstrap.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLUtil.java?rev=1172285&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLUtil.java (added)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLUtil.java Sun Sep 18 13:51:23 2011
@@ -0,0 +1,204 @@
+/**
+ * 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.swssf.impl.saml;
+
+import org.opensaml.xml.*;
+import org.opensaml.xml.io.*;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureException;
+import org.opensaml.xml.signature.Signer;
+import org.swssf.ext.WSSecurityException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Class OpenSAMLUtil provides static helper methods for the OpenSaml library
+ * <p/>
+ * Created on May 18, 2009
+ */
+public class OpenSAMLUtil {
+
+ private static final org.apache.commons.logging.Log log =
+ org.apache.commons.logging.LogFactory.getLog(OpenSAMLUtil.class);
+
+ private static XMLObjectBuilderFactory builderFactory;
+ private static MarshallerFactory marshallerFactory;
+ private static UnmarshallerFactory unmarshallerFactory;
+ private static boolean samlEngineInitialized = false;
+
+ /**
+ * Initialise the SAML library
+ */
+ public synchronized static void initSamlEngine() {
+ if (!samlEngineInitialized) {
+ if (log.isDebugEnabled()) {
+ log.debug("Initilizing the opensaml2 library...");
+ }
+ try {
+ OpenSAMLBootstrap.bootstrap();
+ builderFactory = Configuration.getBuilderFactory();
+ marshallerFactory = Configuration.getMarshallerFactory();
+ unmarshallerFactory = Configuration.getUnmarshallerFactory();
+ samlEngineInitialized = true;
+ if (log.isDebugEnabled()) {
+ log.debug("opensaml2 library bootstrap complete");
+ }
+ } catch (ConfigurationException e) {
+ log.error(
+ "Unable to bootstrap the opensaml2 library - all SAML operations will fail",
+ e
+ );
+ }
+ }
+ }
+
+ /**
+ * Convert a SAML Assertion from a DOM Element to an XMLObject
+ *
+ * @param root of type Element
+ * @return XMLObject
+ * @throws org.opensaml.xml.io.UnmarshallingException
+ *
+ */
+ public static XMLObject fromDom(Element root) throws WSSecurityException {
+ Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(root);
+ try {
+ return unmarshaller.unmarshall(root);
+ } catch (UnmarshallingException ex) {
+ throw new WSSecurityException("Error unmarshalling a SAML assertion", ex);
+ }
+ }
+
+ /**
+ * Convert a SAML Assertion from a XMLObject to a DOM Element
+ *
+ * @param xmlObject of type XMLObject
+ * @param doc of type Document
+ * @return Element
+ * @throws org.opensaml.xml.io.MarshallingException
+ *
+ * @throws SignatureException
+ */
+ public static Element toDom(
+ XMLObject xmlObject,
+ Document doc
+ ) throws WSSecurityException {
+ Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject);
+ Element element = null;
+ try {
+ element = marshaller.marshall(xmlObject);
+ } catch (MarshallingException ex) {
+ throw new WSSecurityException("Error marshalling a SAML assertion", ex);
+ }
+
+ // Sign the assertion if the signature element is present.
+ if (xmlObject instanceof org.opensaml.saml2.core.Assertion) {
+ org.opensaml.saml2.core.Assertion saml2 =
+ (org.opensaml.saml2.core.Assertion) xmlObject;
+ // if there is a signature, but it hasn't already been signed
+ if (saml2.getSignature() != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Signing SAML v2.0 assertion...");
+ }
+ try {
+ Signer.signObject(saml2.getSignature());
+ } catch (SignatureException ex) {
+ throw new WSSecurityException("Error signing a SAML assertion", ex);
+ }
+ }
+ } else if (xmlObject instanceof org.opensaml.saml1.core.Assertion) {
+ org.opensaml.saml1.core.Assertion saml1 =
+ (org.opensaml.saml1.core.Assertion) xmlObject;
+ // if there is a signature, but it hasn't already been signed
+ if (saml1.getSignature() != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Signing SAML v1.1 assertion...");
+ }
+ try {
+ Signer.signObject(saml1.getSignature());
+ } catch (SignatureException ex) {
+ throw new WSSecurityException("Error signing a SAML assertion", ex);
+ }
+ }
+ }
+
+ // Reparent the document. This makes sure that the resulting element will be compatible
+ // with the user-supplied document in the future (for example, when we want to add this
+ // element that dom).
+ if (doc != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Reparenting the SAML token dom to type: " + doc.getClass().getName());
+ }
+ Node importedNode = doc.importNode(element, true);
+ element = (Element) importedNode;
+ }
+
+ return element;
+ }
+
+ /**
+ * Method buildSignature ...
+ *
+ * @return Signature
+ */
+ @SuppressWarnings("unchecked")
+ public static Signature buildSignature() {
+ QName qName = Signature.DEFAULT_ELEMENT_NAME;
+ XMLObjectBuilder<Signature> builder = builderFactory.getBuilder(qName);
+ if (builder == null) {
+ log.error(
+ "Unable to retrieve builder for object QName "
+ + qName
+ );
+ return null;
+ }
+ return
+ builder.buildObject(
+ qName.getNamespaceURI(), qName.getLocalPart(), qName.getPrefix()
+ );
+ }
+
+ /**
+ * Method isMethodSenderVouches ...
+ *
+ * @param confirmMethod of type String
+ * @return boolean
+ */
+ public static boolean isMethodSenderVouches(String confirmMethod) {
+ return
+ confirmMethod != null && confirmMethod.startsWith("urn:oasis:names:tc:SAML:")
+ && confirmMethod.endsWith(":cm:sender-vouches");
+ }
+
+ /**
+ * Method isMethodHolderOfKey ...
+ *
+ * @param confirmMethod of type String
+ * @return boolean
+ */
+ public static boolean isMethodHolderOfKey(String confirmMethod) {
+ return
+ confirmMethod != null && confirmMethod.startsWith("urn:oasis:names:tc:SAML:")
+ && confirmMethod.endsWith(":cm:holder-of-key");
+ }
+}
Propchange: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/impl/saml/OpenSAMLUtil.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision