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/10/11 20:03:15 UTC
svn commit: r1181995 [8/26] - in /webservices/wss4j/branches/swssf: ./
cxf-integration/ cxf-integration/src/main/java/org/swssf/cxfIntegration/
cxf-integration/src/main/java/org/swssf/cxfIntegration/interceptor/
cxf-integration/src/main/java/org/swssf/...
Modified: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/DerivedKeyTokenOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/DerivedKeyTokenOutputProcessor.java?rev=1181995&r1=1179730&r2=1181995&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/DerivedKeyTokenOutputProcessor.java (original)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/DerivedKeyTokenOutputProcessor.java Tue Oct 11 18:03:00 2011
@@ -16,16 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.swssf.impl.processor.output;
+package org.swssf.wss.impl.processor.output;
import org.apache.commons.codec.binary.Base64;
-import org.swssf.config.JCEAlgorithmMapper;
-import org.swssf.crypto.Crypto;
-import org.swssf.ext.*;
-import org.swssf.impl.derivedKey.AlgoFactory;
-import org.swssf.impl.derivedKey.ConversationException;
-import org.swssf.impl.derivedKey.DerivationAlgorithm;
-import org.swssf.impl.securityToken.ProcessorInfoSecurityToken;
+import org.swssf.wss.ext.*;
+import org.swssf.wss.impl.derivedKey.AlgoFactory;
+import org.swssf.wss.impl.derivedKey.ConversationException;
+import org.swssf.wss.impl.derivedKey.DerivationAlgorithm;
+import org.swssf.wss.impl.securityToken.ProcessorInfoSecurityToken;
+import org.swssf.xmlsec.config.JCEAlgorithmMapper;
+import org.swssf.xmlsec.crypto.Crypto;
+import org.swssf.xmlsec.crypto.Merlin;
+import org.swssf.xmlsec.ext.*;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.namespace.QName;
@@ -33,13 +35,12 @@ import javax.xml.stream.XMLStreamExcepti
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import java.io.UnsupportedEncodingException;
-import java.security.Key;
-import java.security.PublicKey;
+import java.security.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
/**
* @author $Author$
@@ -47,15 +48,15 @@ import java.util.UUID;
*/
public class DerivedKeyTokenOutputProcessor extends AbstractOutputProcessor {
- public DerivedKeyTokenOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ public DerivedKeyTokenOutputProcessor(WSSSecurityProperties securityProperties, XMLSecurityConstants.Action action) throws XMLSecurityException {
super(securityProperties, action);
}
@Override
- public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
try {
- String tokenId = outputProcessorChain.getSecurityContext().get(Constants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY);
+ String tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY);
if (tokenId == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION);
}
@@ -72,24 +73,23 @@ public class DerivedKeyTokenOutputProces
int offset = 0;
int length = 0;
- switch (getAction()) {
- case SIGNATURE_WITH_DERIVED_KEY:
- length = JCEAlgorithmMapper.getAlgorithmMapping(getSecurityProperties().getSignatureAlgorithm()).getKeyLength() / 8;
- break;
- case ENCRYPT_WITH_DERIVED_KEY:
- length = JCEAlgorithmMapper.getAlgorithmMapping(getSecurityProperties().getEncryptionSymAlgorithm()).getKeyLength() / 8;
- break;
+
+ XMLSecurityConstants.Action action = getAction();
+ if (action.equals(WSSConstants.SIGNATURE_WITH_DERIVED_KEY)) {
+ length = JCEAlgorithmMapper.getAlgorithmMapping(getSecurityProperties().getSignatureAlgorithm()).getKeyLength() / 8;
+ } else if (action.equals(WSSConstants.ENCRYPT_WITH_DERIVED_KEY)) {
+ length = JCEAlgorithmMapper.getAlgorithmMapping(getSecurityProperties().getEncryptionSymAlgorithm()).getKeyLength() / 8;
}
byte[] label;
try {
- label = (Constants.WS_SecureConversation_DEFAULT_LABEL + Constants.WS_SecureConversation_DEFAULT_LABEL).getBytes("UTF-8");
+ label = (WSSConstants.WS_SecureConversation_DEFAULT_LABEL + WSSConstants.WS_SecureConversation_DEFAULT_LABEL).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new WSSecurityException("UTF-8 encoding is not supported", e);
}
byte[] nonce = new byte[16];
- Constants.secureRandom.nextBytes(nonce);
+ WSSConstants.secureRandom.nextBytes(nonce);
byte[] seed = new byte[label.length + nonce.length];
System.arraycopy(label, 0, seed, 0, label.length);
@@ -97,7 +97,7 @@ public class DerivedKeyTokenOutputProces
DerivationAlgorithm derivationAlgorithm;
try {
- derivationAlgorithm = AlgoFactory.getInstance(Constants.P_SHA_1);
+ derivationAlgorithm = AlgoFactory.getInstance(WSSConstants.P_SHA_1);
} catch (ConversationException e) {
throw new WSSecurityException(e.getMessage(), e);
}
@@ -105,9 +105,9 @@ public class DerivedKeyTokenOutputProces
final byte[] derivedKeyBytes;
try {
byte[] secret;
- if (wrappingSecurityToken.getTokenType() == Constants.TokenType.SecurityContextToken) {
+ if (wrappingSecurityToken.getTokenType() == WSSConstants.SecurityContextToken) {
WSPasswordCallback passwordCallback = new WSPasswordCallback(wsuIdDKT, WSPasswordCallback.Usage.SECRET_KEY);
- Utils.doSecretKeyCallback(securityProperties.getCallbackHandler(), passwordCallback, wsuIdDKT);
+ WSSUtils.doSecretKeyCallback(securityProperties.getCallbackHandler(), passwordCallback, wsuIdDKT);
if (passwordCallback.getKey() == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noKey", wsuIdDKT);
}
@@ -142,7 +142,7 @@ public class DerivedKeyTokenOutputProces
return false;
}
- public Key getSecretKey(String algorithmURI, Constants.KeyUsage keyUsage) throws WSSecurityException {
+ public Key getSecretKey(String algorithmURI, XMLSecurityConstants.KeyUsage keyUsage) throws WSSecurityException {
if (keyTable.containsKey(algorithmURI)) {
return keyTable.get(algorithmURI);
} else {
@@ -153,7 +153,7 @@ public class DerivedKeyTokenOutputProces
}
}
- public PublicKey getPublicKey(Constants.KeyUsage keyUsage) throws WSSecurityException {
+ public PublicKey getPublicKey(XMLSecurityConstants.KeyUsage keyUsage) throws WSSecurityException {
return null;
}
@@ -172,7 +172,7 @@ public class DerivedKeyTokenOutputProces
return null;
}
- public Constants.TokenType getTokenType() {
+ public WSSConstants.TokenType getTokenType() {
return null;
}
};
@@ -187,17 +187,17 @@ public class DerivedKeyTokenOutputProces
}
};
- switch (getAction()) {
- case SIGNATURE_WITH_DERIVED_KEY:
- outputProcessorChain.getSecurityContext().put(Constants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE, wsuIdDKT);
- outputProcessorChain.getSecurityContext().put(Constants.PROP_APPEND_SIGNATURE_ON_THIS_ID, wsuIdDKT);
- break;
- case ENCRYPT_WITH_DERIVED_KEY:
- outputProcessorChain.getSecurityContext().put(Constants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, wsuIdDKT);
- break;
+ if (action.equals(WSSConstants.SIGNATURE_WITH_DERIVED_KEY)) {
+ outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE, wsuIdDKT);
+ outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_APPEND_SIGNATURE_ON_THIS_ID, wsuIdDKT);
+ } else if (action.equals(WSSConstants.ENCRYPT_WITH_DERIVED_KEY)) {
+ outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, wsuIdDKT);
}
outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(wsuIdDKT, derivedKeysecurityTokenProvider);
- FinalDerivedKeyTokenOutputProcessor finalDerivedKeyTokenOutputProcessor = new FinalDerivedKeyTokenOutputProcessor(getSecurityProperties(), getAction(), derivedKeySecurityToken, offset, length, new String(Base64.encodeBase64(nonce)));
+ FinalDerivedKeyTokenOutputProcessor finalDerivedKeyTokenOutputProcessor =
+ new FinalDerivedKeyTokenOutputProcessor(
+ getSecurityProperties(), getAction(), derivedKeySecurityToken,
+ offset, length, new String(Base64.encodeBase64(nonce)));
finalDerivedKeyTokenOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
derivedKeySecurityToken.setProcessor(finalDerivedKeyTokenOutputProcessor);
outputProcessorChain.addProcessor(finalDerivedKeyTokenOutputProcessor);
@@ -214,7 +214,10 @@ public class DerivedKeyTokenOutputProces
private int length;
private String nonce;
- FinalDerivedKeyTokenOutputProcessor(SecurityProperties securityProperties, Constants.Action action, SecurityToken securityToken, int offset, int length, String nonce) throws WSSecurityException {
+ FinalDerivedKeyTokenOutputProcessor(XMLSecurityProperties securityProperties, XMLSecurityConstants.Action action,
+ SecurityToken securityToken, int offset, int length, String nonce)
+ throws XMLSecurityException {
+
super(securityProperties, action);
this.securityToken = securityToken;
this.offset = offset;
@@ -223,32 +226,187 @@ public class DerivedKeyTokenOutputProces
}
@Override
- public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
outputProcessorChain.processEvent(xmlEvent);
if (xmlEvent.isStartElement()) {
StartElement startElement = xmlEvent.asStartElement();
- if (outputProcessorChain.getDocumentContext().isInSecurityHeader() && startElement.getName().equals(Constants.TAG_wsse_Security)) {
+ if (((WSSDocumentContext) outputProcessorChain.getDocumentContext()).isInSecurityHeader() && startElement.getName().equals(WSSConstants.TAG_wsse_Security)) {
OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
Map<QName, String> attributes = new HashMap<QName, String>();
- attributes.put(Constants.ATT_wsu_Id, securityToken.getId());
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_DerivedKeyToken, attributes);
+ attributes.put(WSSConstants.ATT_wsu_Id, securityToken.getId());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_DerivedKeyToken, attributes);
- createSecurityTokenReferenceStructureForDerivedKey(subOutputProcessorChain, securityToken, getSecurityProperties().getDerivedKeyKeyIdentifierType(), getSecurityProperties().getDerivedKeyTokenReference(), getSecurityProperties().isUseSingleCert());
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_Offset, null);
+ createSecurityTokenReferenceStructureForDerivedKey(subOutputProcessorChain, securityToken,
+ ((WSSSecurityProperties) getSecurityProperties()).getDerivedKeyKeyIdentifierType(),
+ ((WSSSecurityProperties) getSecurityProperties()).getDerivedKeyTokenReference(), getSecurityProperties().isUseSingleCert());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_Offset, null);
createCharactersAndOutputAsEvent(subOutputProcessorChain, "" + offset);
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_Offset);
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_Length, null);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_Offset);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_Length, null);
createCharactersAndOutputAsEvent(subOutputProcessorChain, "" + length);
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_Length);
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_Nonce, null);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_Length);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_Nonce, null);
createCharactersAndOutputAsEvent(subOutputProcessorChain, nonce);
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_Nonce);
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_wsc0502_DerivedKeyToken);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_Nonce);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsc0502_DerivedKeyToken);
outputProcessorChain.removeProcessor(this);
}
}
}
+
+ protected void createSecurityTokenReferenceStructureForDerivedKey(
+ OutputProcessorChain outputProcessorChain,
+ SecurityToken securityToken,
+ WSSConstants.KeyIdentifierType keyIdentifierType,
+ WSSConstants.DerivedKeyTokenReference derivedKeyTokenReference,
+ boolean useSingleCertificate)
+ throws XMLStreamException, XMLSecurityException {
+
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_wsu_Id, "STRId-" + UUID.randomUUID().toString());
+ if ((keyIdentifierType == WSSConstants.KeyIdentifierType.BST_DIRECT_REFERENCE
+ || keyIdentifierType == WSSConstants.KeyIdentifierType.BST_EMBEDDED)
+ && !useSingleCertificate) {
+ attributes.put(WSSConstants.ATT_wsse11_TokenType, WSSConstants.NS_X509PKIPathv1);
+ } else if (derivedKeyTokenReference == WSSConstants.DerivedKeyTokenReference.EncryptedKey) {
+ attributes.put(WSSConstants.ATT_wsse11_TokenType, WSSConstants.NS_WSS_ENC_KEY_VALUE_TYPE);
+ }
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_SecurityTokenReference, attributes);
+
+ X509Certificate[] x509Certificates = securityToken.getKeyWrappingToken().getX509Certificates();
+ String tokenId = securityToken.getKeyWrappingToken().getId();
+
+ if (keyIdentifierType == WSSConstants.KeyIdentifierType.ISSUER_SERIAL) {
+ createX509IssuerSerialStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType == WSSConstants.KeyIdentifierType.SKI_KEY_IDENTIFIER) {
+ createX509SubjectKeyIdentifierStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType == WSSConstants.KeyIdentifierType.X509_KEY_IDENTIFIER) {
+ createX509KeyIdentifierStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType == WSSConstants.KeyIdentifierType.THUMBPRINT_IDENTIFIER) {
+ createThumbprintKeyIdentifierStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType == WSSConstants.KeyIdentifierType.BST_EMBEDDED) {
+ createBSTReferenceStructure(outputProcessorChain, tokenId, x509Certificates, useSingleCertificate, true);
+ } else if (keyIdentifierType == WSSConstants.KeyIdentifierType.BST_DIRECT_REFERENCE) {
+ createBSTReferenceStructure(outputProcessorChain, tokenId, x509Certificates, useSingleCertificate, false);
+ } else if (keyIdentifierType == WSSConstants.KeyIdentifierType.EMBEDDED_SECURITY_TOKEN_REF) {
+ createEmbeddedSecurityTokenReferenceStructure(outputProcessorChain, tokenId);
+ } else {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, "unsupportedSecurityToken", keyIdentifierType.name());
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_SecurityTokenReference);
+ }
+
+ //todo common method
+ protected void createX509SubjectKeyIdentifierStructure(OutputProcessorChain outputProcessorChain, X509Certificate[] x509Certificates) throws XMLSecurityException, XMLStreamException {
+ // As per the 1.1 specification, SKI can only be used for a V3 certificate
+ if (x509Certificates[0].getVersion() != 3) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, "invalidCertForSKI");
+ }
+
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, WSSConstants.NS_X509SubjectKeyIdentifier);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier, attributes);
+ byte data[] = new Merlin().getSKIBytesFromCert(x509Certificates[0]);
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(data));
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier);
+ }
+
+ //todo common method
+ protected void createX509KeyIdentifierStructure(OutputProcessorChain outputProcessorChain, X509Certificate[] x509Certificates) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, WSSConstants.NS_X509_V3_TYPE);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier, attributes);
+ try {
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(x509Certificates[0].getEncoded()));
+ } catch (CertificateEncodingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier);
+ }
+
+ //todo common methdod
+ protected void createThumbprintKeyIdentifierStructure(OutputProcessorChain outputProcessorChain, X509Certificate[] x509Certificates) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, WSSConstants.NS_THUMBPRINT);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier, attributes);
+ try {
+ MessageDigest sha;
+ sha = MessageDigest.getInstance("SHA-1");
+ sha.reset();
+ sha.update(x509Certificates[0].getEncoded());
+ byte[] data = sha.digest();
+
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(data));
+ } catch (CertificateEncodingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier);
+ }
+
+ //todo common method
+ protected void createBSTReferenceStructure(OutputProcessorChain outputProcessorChain, String referenceId, X509Certificate[] x509Certificates, boolean useSingleCertificate, boolean embed) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ String valueType;
+ if (useSingleCertificate) {
+ valueType = WSSConstants.NS_X509_V3_TYPE;
+ } else {
+ valueType = WSSConstants.NS_X509PKIPathv1;
+ }
+ attributes.put(WSSConstants.ATT_NULL_URI, "#" + referenceId);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, valueType);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference, attributes);
+ if (embed) {
+ createBinarySecurityTokenStructure(outputProcessorChain, referenceId, x509Certificates, useSingleCertificate);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference);
+ }
+
+ //todo common method
+ protected void createEmbeddedSecurityTokenReferenceStructure(OutputProcessorChain outputProcessorChain, String referenceId) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_URI, "#" + referenceId);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference, attributes);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference);
+ }
+
+ //todo common method
+ protected void createBinarySecurityTokenStructure(OutputProcessorChain outputProcessorChain, String referenceId, X509Certificate[] x509Certificates, boolean useSingleCertificate) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ String valueType;
+ if (useSingleCertificate) {
+ valueType = WSSConstants.NS_X509_V3_TYPE;
+ } else {
+ valueType = WSSConstants.NS_X509PKIPathv1;
+ }
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, valueType);
+ attributes.put(WSSConstants.ATT_wsu_Id, referenceId);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_BinarySecurityToken, attributes);
+ try {
+ if (useSingleCertificate) {
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(x509Certificates[0].getEncoded()));
+ } else {
+ try {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
+ List<X509Certificate> certificates = Arrays.asList(x509Certificates);
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(certificateFactory.generateCertPath(certificates).getEncoded()));
+ } catch (CertificateException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
+ } catch (NoSuchProviderException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
+ }
+ }
+ } catch (CertificateEncodingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_BinarySecurityToken);
+ }
}
}
Modified: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptEndingOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptEndingOutputProcessor.java?rev=1181995&r1=1179730&r2=1181995&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptEndingOutputProcessor.java (original)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptEndingOutputProcessor.java Tue Oct 11 18:03:00 2011
@@ -16,11 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.swssf.impl.processor.output;
+package org.swssf.wss.impl.processor.output;
-import org.swssf.ext.*;
+import org.swssf.wss.ext.WSSConstants;
+import org.swssf.wss.ext.WSSDocumentContext;
+import org.swssf.wss.ext.WSSSecurityProperties;
+import org.swssf.wss.ext.WSSUtils;
+import org.swssf.xmlsec.ext.OutputProcessorChain;
+import org.swssf.xmlsec.ext.XMLSecurityConstants;
+import org.swssf.xmlsec.ext.XMLSecurityException;
+import org.swssf.xmlsec.impl.processor.output.AbstractEncryptEndingOutputProcessor;
+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.util.Iterator;
/**
* Processor buffers encrypted XMLEvents and forwards them when final is called
@@ -28,19 +41,128 @@ import javax.xml.stream.XMLStreamExcepti
* @author $Author$
* @version $Revision$ $Date$
*/
-public class EncryptEndingOutputProcessor extends AbstractBufferingOutputProcessor {
+public class EncryptEndingOutputProcessor extends AbstractEncryptEndingOutputProcessor {
- public EncryptEndingOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ public EncryptEndingOutputProcessor(WSSSecurityProperties securityProperties, XMLSecurityConstants.Action action) throws XMLSecurityException {
super(securityProperties, action);
this.getAfterProcessors().add(EncryptOutputProcessor.class.getName());
this.getAfterProcessors().add(UsernameTokenOutputProcessor.class.getName());
}
@Override
- protected void processHeaderEvent(OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ protected void processHeaderEvent(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
- if (getAction() == Constants.Action.ENCRYPT_WITH_DERIVED_KEY) {
+ if (getAction() == WSSConstants.ENCRYPT_WITH_DERIVED_KEY) {
createReferenceListStructure(subOutputProcessorChain);
}
}
+
+ @Override
+ public void doFinal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
+
+ //todo replace this and in EncryptEndingOutputProcessor with a common method somewhere
+ OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
+
+ //loop until we reach our security header and set flag
+ Iterator<XMLEvent> xmlEventIterator = getXmlEventBuffer().descendingIterator();
+ while (xmlEventIterator.hasNext()) {
+ XMLEvent xmlEvent = xmlEventIterator.next();
+ if (xmlEvent.isStartElement()) {
+ StartElement startElement = xmlEvent.asStartElement();
+ if (startElement.getName().equals(WSSConstants.TAG_wsse_Security)
+ && WSSUtils.isResponsibleActorOrRole(
+ startElement,
+ ((WSSDocumentContext) subOutputProcessorChain.getDocumentContext()).getSOAPMessageVersionNamespace(),
+ ((WSSSecurityProperties) getSecurityProperties()).getActor())) {
+ ((WSSDocumentContext) subOutputProcessorChain.getDocumentContext()).setInSecurityHeader(true);
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+ break;
+ }
+ }
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+ }
+
+ //append current header
+ if (getAppendAfterThisTokenId() == null) {
+ processHeaderEvent(subOutputProcessorChain);
+ } else {
+ //we have a dependent token. so we have to append the current header after the token
+ boolean found = false;
+ while (xmlEventIterator.hasNext() && !found) {
+ XMLEvent xmlEvent = xmlEventIterator.next();
+
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+
+ //search for an element with a matching wsu:Id. this is our token
+ if (xmlEvent.isStartElement()) {
+ StartElement startElement = xmlEvent.asStartElement();
+ QName matchingElementName;
+
+ @SuppressWarnings("unchecked")
+ Iterator<Attribute> attributeIterator = startElement.getAttributes();
+ while (attributeIterator.hasNext() && !found) {
+ Attribute attribute = attributeIterator.next();
+ final QName attributeName = attribute.getName();
+ final String attributeValue = attribute.getValue();
+ if ((WSSConstants.ATT_wsu_Id.equals(attributeName) && getAppendAfterThisTokenId().equals(attributeValue))
+ || (WSSConstants.ATT_NULL_Id.equals(attributeName) && getAppendAfterThisTokenId().equals(attributeValue))
+ || (WSSConstants.ATT_NULL_AssertionID.equals(attributeName) && getAppendAfterThisTokenId().equals(attributeValue))
+ || (WSSConstants.ATT_NULL_ID.equals(attributeName) && getAppendAfterThisTokenId().endsWith(attributeValue))) {
+ matchingElementName = startElement.getName();
+ //we found the token and...
+ int level = 0;
+ while (xmlEventIterator.hasNext() && !found) {
+ xmlEvent = xmlEventIterator.next();
+
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+
+ //loop until we reach the token end element
+ if (xmlEvent.isEndElement()) {
+ EndElement endElement = xmlEvent.asEndElement();
+ if (level == 0 && endElement.getName().equals(matchingElementName)) {
+ found = true;
+ //output now the current header
+ processHeaderEvent(subOutputProcessorChain);
+ }
+ level--;
+ } else if (xmlEvent.isStartElement()) {
+ level++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ //loop until our security header end element and unset the flag
+ while (xmlEventIterator.hasNext()) {
+ XMLEvent xmlEvent = xmlEventIterator.next();
+ if (xmlEvent.isEndElement()) {
+ EndElement endElement = xmlEvent.asEndElement();
+ if (endElement.getName().equals(WSSConstants.TAG_wsse_Security)) {
+ ((WSSDocumentContext) subOutputProcessorChain.getDocumentContext()).setInSecurityHeader(false);
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+ break;
+ }
+ }
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+ }
+ //loop throug the rest of the document
+ while (xmlEventIterator.hasNext()) {
+ XMLEvent xmlEvent = xmlEventIterator.next();
+ subOutputProcessorChain.reset();
+ subOutputProcessorChain.processEvent(xmlEvent);
+ }
+ subOutputProcessorChain.reset();
+ //call final on the rest of the chain
+ subOutputProcessorChain.doFinal();
+ //this processor is now finished and we can remove it now
+ subOutputProcessorChain.removeProcessor(this);
+ }
}
Modified: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptOutputProcessor.java?rev=1181995&r1=1179730&r2=1181995&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptOutputProcessor.java (original)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptOutputProcessor.java Tue Oct 11 18:03:00 2011
@@ -16,29 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.swssf.impl.processor.output;
+package org.swssf.wss.impl.processor.output;
-import org.apache.commons.codec.binary.Base64OutputStream;
-import org.swssf.config.JCEAlgorithmMapper;
-import org.swssf.ext.*;
-import org.swssf.impl.EncryptionPartDef;
-import org.swssf.impl.util.TrimmerOutputStream;
+import org.swssf.wss.ext.WSSConstants;
+import org.swssf.wss.ext.WSSDocumentContext;
+import org.swssf.wss.ext.WSSSecurityProperties;
+import org.swssf.xmlsec.ext.*;
+import org.swssf.xmlsec.impl.EncryptionPartDef;
+import org.swssf.xmlsec.impl.processor.output.AbstractEncryptOutputProcessor;
-import javax.crypto.Cipher;
-import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.xml.namespace.QName;
-import javax.xml.stream.XMLEventFactory;
-import javax.xml.stream.XMLEventWriter;
-import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.*;
-import java.io.BufferedOutputStream;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
import java.io.IOException;
-import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
/**
* Processor to encrypt XML structures
@@ -46,66 +45,53 @@ import java.util.*;
* @author $Author$
* @version $Revision$ $Date$
*/
-public class EncryptOutputProcessor extends AbstractOutputProcessor {
+public class EncryptOutputProcessor extends AbstractEncryptOutputProcessor {
- private List<SecurePart> secureParts;
- private InternalEncryptionOutputProcessor activeInternalEncryptionOutputProcessor = null;
-
- public EncryptOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ public EncryptOutputProcessor(WSSSecurityProperties securityProperties, XMLSecurityConstants.Action action) throws XMLSecurityException {
super(securityProperties, action);
- secureParts = securityProperties.getEncryptionSecureParts();
}
@Override
- public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
if (xmlEvent.isStartElement()) {
StartElement startElement = xmlEvent.asStartElement();
//avoid double encryption when child elements matches too
- if (activeInternalEncryptionOutputProcessor == null) {
- //find an element which matches a user configured securePart
- 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())) {
-
- logger.debug("Matched securePart for encryption");
- InternalEncryptionOutputProcessor internalEncryptionOutputProcessor = null;
- try {
- String tokenId = outputProcessorChain.getSecurityContext().get(Constants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
- SecurityTokenProvider securityTokenProvider = outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
- EncryptionPartDef encryptionPartDef = new EncryptionPartDef();
- encryptionPartDef.setModifier(securePart.getModifier());
- encryptionPartDef.setEncRefId("ED-" + UUID.randomUUID().toString());
- encryptionPartDef.setKeyId(securityTokenProvider.getId());
- encryptionPartDef.setSymmetricKey(securityTokenProvider.getSecurityToken(null).getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm(), null));
- outputProcessorChain.getSecurityContext().putAsList(EncryptionPartDef.class, encryptionPartDef);
- internalEncryptionOutputProcessor =
- new InternalEncryptionOutputProcessor(
- getSecurityProperties(),
- getAction(),
- encryptionPartDef,
- startElement,
- outputProcessorChain.getDocumentContext().getEncoding()
- );
- } catch (NoSuchAlgorithmException e) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
- } catch (NoSuchPaddingException e) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
- } catch (InvalidKeyException e) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
- } catch (IOException e) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
- }
-
- activeInternalEncryptionOutputProcessor = internalEncryptionOutputProcessor;
- outputProcessorChain.addProcessor(internalEncryptionOutputProcessor);
- break;
- }
+ if (getActiveInternalEncryptionOutputProcessor() == null) {
+ SecurePart securePart = securePartMatches(startElement, outputProcessorChain);
+ if (securePart != null) {
+ logger.debug("Matched securePart for encryption");
+ InternalEncryptionOutputProcessor internalEncryptionOutputProcessor = null;
+ try {
+ String tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
+ SecurityTokenProvider securityTokenProvider = outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
+ EncryptionPartDef encryptionPartDef = new EncryptionPartDef();
+ encryptionPartDef.setModifier(securePart.getModifier());
+ encryptionPartDef.setEncRefId("ED-" + UUID.randomUUID().toString());
+ encryptionPartDef.setKeyId(securityTokenProvider.getId());
+ encryptionPartDef.setSymmetricKey(securityTokenProvider.getSecurityToken(null).getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm(), null));
+ outputProcessorChain.getSecurityContext().putAsList(EncryptionPartDef.class, encryptionPartDef);
+ internalEncryptionOutputProcessor =
+ new InternalEncryptionOutputProcessor(
+ ((WSSSecurityProperties) getSecurityProperties()),
+ getAction(),
+ encryptionPartDef,
+ startElement,
+ outputProcessorChain.getDocumentContext().getEncoding()
+ );
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+ } catch (NoSuchPaddingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+ } catch (InvalidKeyException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
+ } catch (IOException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
}
+
+ setActiveInternalEncryptionOutputProcessor(internalEncryptionOutputProcessor);
+ outputProcessorChain.addProcessor(internalEncryptionOutputProcessor);
}
}
}
@@ -116,168 +102,61 @@ public class EncryptOutputProcessor exte
/**
* Processor which handles the effective enryption of the data
*/
- class InternalEncryptionOutputProcessor extends AbstractOutputProcessor {
-
- private EncryptionPartDef encryptionPartDef;
- private CharacterEventGeneratorOutputStream characterEventGeneratorOutputStream;
- private XMLEventWriter xmlEventWriter;
- private OutputStream cipherOutputStream;
+ class InternalEncryptionOutputProcessor extends AbstractInternalEncryptionOutputProcessor {
- private StartElement startElement;
- private int elementCounter = 0;
private boolean doEncryptedHeader = false;
- private OutputProcessorChain subOutputProcessorChain;
- InternalEncryptionOutputProcessor(SecurityProperties securityProperties, Constants.Action action, EncryptionPartDef encryptionPartDef,
+ InternalEncryptionOutputProcessor(WSSSecurityProperties securityProperties, XMLSecurityConstants.Action action, EncryptionPartDef encryptionPartDef,
StartElement startElement, String encoding)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, XMLStreamException {
- super(securityProperties, action);
- this.getBeforeProcessors().add(EncryptEndingOutputProcessor.class.getName());
+ super(securityProperties, action, encryptionPartDef, startElement, encoding);
+ this.getBeforeProcessors().add(org.swssf.wss.impl.processor.output.EncryptEndingOutputProcessor.class.getName());
this.getBeforeProcessors().add(InternalEncryptionOutputProcessor.class.getName());
this.getAfterProcessors().add(EncryptOutputProcessor.class.getName());
- this.encryptionPartDef = encryptionPartDef;
- this.startElement = startElement;
-
- //initialize the cipher
- String jceAlgorithm = JCEAlgorithmMapper.translateURItoJCEID(securityProperties.getEncryptionSymAlgorithm());
- Cipher symmetricCipher = Cipher.getInstance(jceAlgorithm);
-
- //Should internally generate an IV
- symmetricCipher.init(Cipher.ENCRYPT_MODE, encryptionPartDef.getSymmetricKey());
- byte[] iv = symmetricCipher.getIV();
-
- characterEventGeneratorOutputStream = new CharacterEventGeneratorOutputStream(encoding);
- //Base64EncoderStream calls write every 78byte (line breaks). So we have to buffer again to get optimal performance
- Base64OutputStream base64EncoderStream = new Base64OutputStream(new BufferedOutputStream(characterEventGeneratorOutputStream), true, 76, new byte[]{'\n'});
- base64EncoderStream.write(iv);
-
- //the trimmer output stream is needed to strip away the dummy wrapping element which must be added
- cipherOutputStream = new TrimmerOutputStream(new CipherOutputStream(base64EncoderStream, symmetricCipher), 8192, 3, 4);
-
- //we create a new StAX writer for optimized namespace writing.
- XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
- xmlOutputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
- //spec says (4.2): "The cleartext octet sequence obtained in step 3 is interpreted as UTF-8 encoded character data."
- xmlEventWriter = xmlOutputFactory.createXMLEventWriter(cipherOutputStream, "UTF-8");
- //we have to output a fake element to workaround text-only encryption:
- xmlEventWriter.add(XMLEventFactory.newFactory().createStartElement(new QName("a"), null, null));
- }
-
- @Override
- public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
-
- if (xmlEvent.isStartElement()) {
-
- StartElement startElement = xmlEvent.asStartElement();
-
- if (startElement.getName().equals(this.startElement.getName()) && elementCounter == 0) {
- //if the user selected element encryption we have to encrypt the current element-event...
- if (encryptionPartDef.getModifier() == SecurePart.Modifier.Element) {
- subOutputProcessorChain = outputProcessorChain.createSubChain(this);
- processEventInternal(subOutputProcessorChain);
- //encrypt the current element event
- encryptEvent(xmlEvent);
-
- } //...the user selected content encryption, so we let pass this event as usual
- else if (encryptionPartDef.getModifier() == SecurePart.Modifier.Content) {
- outputProcessorChain.processEvent(xmlEvent);
- subOutputProcessorChain = outputProcessorChain.createSubChain(this);
- processEventInternal(subOutputProcessorChain);
- }
- } else {
- encryptEvent(xmlEvent);
- }
-
- elementCounter++;
-
- } else if (xmlEvent.isEndElement()) {
- elementCounter--;
-
- EndElement endElement = xmlEvent.asEndElement();
-
- if (endElement.getName().equals(this.startElement.getName()) && elementCounter == 0) {
- if (encryptionPartDef.getModifier() == SecurePart.Modifier.Element) {
- encryptEvent(xmlEvent);
- doFinalInternal(subOutputProcessorChain);
- } else {
- doFinalInternal(subOutputProcessorChain);
- outputAsEvent(subOutputProcessorChain, xmlEvent);
- }
- subOutputProcessorChain.removeProcessor(this);
- subOutputProcessorChain = null;
- //from now on encryption is possible again
- activeInternalEncryptionOutputProcessor = null;
-
- } else {
- encryptEvent(xmlEvent);
- }
- } else {
- //not an interesting start nor an interesting end element
- //so encrypt this
- encryptEvent(xmlEvent);
-
- //push all buffered encrypted character events through the chain
- Iterator<Characters> charactersIterator = characterEventGeneratorOutputStream.getCharactersBuffer().iterator();
- while (charactersIterator.hasNext()) {
- Characters characters = charactersIterator.next();
- outputAsEvent(subOutputProcessorChain, characters);
- charactersIterator.remove();
- }
- }
- }
-
- private void encryptEvent(XMLEvent xmlEvent) throws XMLStreamException {
- xmlEventWriter.add(xmlEvent);
}
/**
* Creates the Data structure around the cipher data
*/
- private void processEventInternal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ protected void processEventInternal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
Map<QName, String> attributes = null;
//WSS 1.1 EncryptedHeader Element:
if (outputProcessorChain.getDocumentContext().getDocumentLevel() == 3
- && outputProcessorChain.getDocumentContext().isInSOAPHeader()) {
+ && ((WSSDocumentContext) outputProcessorChain.getDocumentContext()).isInSOAPHeader()) {
doEncryptedHeader = true;
attributes = new HashMap<QName, String>();
@SuppressWarnings("unchecked")
- Iterator<Attribute> attributeIterator = this.startElement.getAttributes();
+ Iterator<Attribute> attributeIterator = getStartElement().getAttributes();
while (attributeIterator.hasNext()) {
Attribute attribute = attributeIterator.next();
if (!attribute.isNamespace() &&
- (Constants.NS_SOAP11.equals(attribute.getName().getNamespaceURI()) ||
- Constants.NS_SOAP12.equals(attribute.getName().getNamespaceURI()))) {
+ (WSSConstants.NS_SOAP11.equals(attribute.getName().getNamespaceURI()) ||
+ WSSConstants.NS_SOAP12.equals(attribute.getName().getNamespaceURI()))) {
attributes.put(attribute.getName(), attribute.getValue());
}
}
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_wsse11_EncryptedHeader, attributes);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse11_EncryptedHeader, attributes);
}
attributes = new HashMap<QName, String>();
- attributes.put(Constants.ATT_NULL_Id, encryptionPartDef.getEncRefId());
- attributes.put(Constants.ATT_NULL_Type, encryptionPartDef.getModifier().getModifier());
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_EncryptedData, attributes);
+ attributes.put(WSSConstants.ATT_NULL_Id, getEncryptionPartDef().getEncRefId());
+ attributes.put(WSSConstants.ATT_NULL_Type, getEncryptionPartDef().getModifier().getModifier());
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_xenc_EncryptedData, attributes);
attributes = new HashMap<QName, String>();
- attributes.put(Constants.ATT_NULL_Algorithm, securityProperties.getEncryptionSymAlgorithm());
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_EncryptionMethod, attributes);
-
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_EncryptionMethod);
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_dsig_KeyInfo, null);
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_wsse_SecurityTokenReference, null);
+ attributes.put(WSSConstants.ATT_NULL_Algorithm, securityProperties.getEncryptionSymAlgorithm());
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_xenc_EncryptionMethod, attributes);
- attributes = new HashMap<QName, String>();
- attributes.put(Constants.ATT_NULL_URI, "#" + encryptionPartDef.getKeyId());
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_wsse_Reference, attributes);
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_wsse_Reference);
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_wsse_SecurityTokenReference);
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_dsig_KeyInfo);
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_CipherData, null);
- createStartElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_CipherValue, null);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_xenc_EncryptionMethod);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_dsig_KeyInfo, null);
+ createKeyInfoStructure(outputProcessorChain);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_dsig_KeyInfo);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_xenc_CipherData, null);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_xenc_CipherValue, null);
/*
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EncDataId-1612925417"
@@ -299,65 +178,25 @@ public class EncryptOutputProcessor exte
*/
}
- private void doFinalInternal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ @Override
+ protected void createKeyInfoStructure(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes;
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_SecurityTokenReference, null);
- try {
- xmlEventWriter.add(XMLEventFactory.newFactory().createEndElement(new QName("a"), null));
- //close the event writer to flush all outstanding events to the encrypt stream
- xmlEventWriter.close();
- //call close to force a cipher.doFinal()
- cipherOutputStream.close();
- } catch (IOException e) {
- throw new XMLStreamException(e);
- }
+ attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_URI, "#" + getEncryptionPartDef().getKeyId());
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference, attributes);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_SecurityTokenReference);
+ }
- //push all buffered encrypted character events through the chain
- Iterator<Characters> charactersIterator = characterEventGeneratorOutputStream.getCharactersBuffer().iterator();
- while (charactersIterator.hasNext()) {
- Characters characters = charactersIterator.next();
- outputAsEvent(outputProcessorChain, characters);
- charactersIterator.remove();
- }
+ protected void doFinalInternal(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_CipherValue);
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_CipherData);
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_xenc_EncryptedData);
+ super.doFinalInternal(outputProcessorChain);
if (doEncryptedHeader) {
- createEndElementAndOutputAsEvent(outputProcessorChain, Constants.TAG_wsse11_EncryptedHeader);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse11_EncryptedHeader);
}
}
}
-
- /**
- * Creates Character-XMLEvents from the byte stream
- */
- class CharacterEventGeneratorOutputStream extends OutputStream {
-
- private List<Characters> charactersBuffer = new Vector<Characters>();
- private String encoding;
-
- CharacterEventGeneratorOutputStream(String encoding) {
- this.encoding = encoding;
- }
-
- public List<Characters> getCharactersBuffer() {
- return charactersBuffer;
- }
-
- @Override
- public void write(int b) throws IOException {
- charactersBuffer.add(createCharacters(new String(new byte[]{((byte) b)}, encoding)).asCharacters());
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- charactersBuffer.add(createCharacters(new String(b, encoding)).asCharacters());
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- charactersBuffer.add(createCharacters(new String(b, off, len, encoding)).asCharacters());
- }
- }
}
Modified: webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptedKeyOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptedKeyOutputProcessor.java?rev=1181995&r1=1179730&r2=1181995&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptedKeyOutputProcessor.java (original)
+++ webservices/wss4j/branches/swssf/streaming-ws-security/src/main/java/org/swssf/wss/impl/processor/output/EncryptedKeyOutputProcessor.java Tue Oct 11 18:03:00 2011
@@ -16,27 +16,30 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.swssf.impl.processor.output;
+package org.swssf.wss.impl.processor.output;
import org.apache.commons.codec.binary.Base64;
-import org.swssf.config.JCEAlgorithmMapper;
-import org.swssf.crypto.Crypto;
-import org.swssf.ext.*;
-import org.swssf.impl.securityToken.ProcessorInfoSecurityToken;
+import org.swssf.wss.ext.WSSConstants;
+import org.swssf.wss.ext.WSSDocumentContext;
+import org.swssf.wss.ext.WSSSecurityProperties;
+import org.swssf.wss.ext.WSSecurityException;
+import org.swssf.wss.impl.securityToken.ProcessorInfoSecurityToken;
+import org.swssf.xmlsec.config.JCEAlgorithmMapper;
+import org.swssf.xmlsec.crypto.Crypto;
+import org.swssf.xmlsec.crypto.Merlin;
+import org.swssf.xmlsec.ext.*;
import javax.crypto.*;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
+import java.security.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
/**
* @author $Author$
@@ -44,15 +47,15 @@ import java.util.UUID;
*/
public class EncryptedKeyOutputProcessor extends AbstractOutputProcessor {
- public EncryptedKeyOutputProcessor(SecurityProperties securityProperties, Constants.Action action) throws WSSecurityException {
+ public EncryptedKeyOutputProcessor(XMLSecurityProperties securityProperties, XMLSecurityConstants.Action action) throws XMLSecurityException {
super(securityProperties, action);
}
@Override
- public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
try {
- String tokenId = outputProcessorChain.getSecurityContext().get(Constants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY);
+ String tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY);
if (tokenId == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION);
}
@@ -100,19 +103,19 @@ public class EncryptedKeyOutputProcessor
return false;
}
- public Key getSecretKey(String algorithmURI, Constants.KeyUsage keyUsage) throws WSSecurityException {
+ public Key getSecretKey(String algorithmURI, XMLSecurityConstants.KeyUsage keyUsage) throws XMLSecurityException {
return symmetricKey;
}
- public PublicKey getPublicKey(Constants.KeyUsage keyUsage) throws WSSecurityException {
+ public PublicKey getPublicKey(XMLSecurityConstants.KeyUsage keyUsage) throws XMLSecurityException {
return null;
}
- public X509Certificate[] getX509Certificates() throws WSSecurityException {
+ public X509Certificate[] getX509Certificates() throws XMLSecurityException {
return null;
}
- public void verify() throws WSSecurityException {
+ public void verify() throws XMLSecurityException {
}
public SecurityToken getKeyWrappingToken() {
@@ -123,13 +126,13 @@ public class EncryptedKeyOutputProcessor
return null;
}
- public Constants.TokenType getTokenType() {
+ public WSSConstants.TokenType getTokenType() {
return null;
}
};
final SecurityTokenProvider encryptedKeySecurityTokenProvider = new SecurityTokenProvider() {
- public SecurityToken getSecurityToken(Crypto crypto) throws WSSecurityException {
+ public SecurityToken getSecurityToken(Crypto crypto) throws XMLSecurityException {
return encryptedKeySecurityToken;
}
@@ -139,31 +142,28 @@ public class EncryptedKeyOutputProcessor
};
FinalEncryptedKeyOutputProcessor finalEncryptedKeyOutputProcessor = new FinalEncryptedKeyOutputProcessor(getSecurityProperties(), getAction(), encryptedKeySecurityToken);
- switch (getAction()) {
- case ENCRYPT:
- outputProcessorChain.getSecurityContext().put(Constants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, ekId);
- if (wrappingSecurityToken.getProcessor() != null) {
- finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
- } else {
- finalEncryptedKeyOutputProcessor.getAfterProcessors().add(EncryptEndingOutputProcessor.class.getName());
- }
- break;
- case SIGNATURE_WITH_DERIVED_KEY:
- outputProcessorChain.getSecurityContext().put(Constants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY, ekId);
- if (wrappingSecurityToken.getProcessor() != null) {
- finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
- } else {
- finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(SignatureOutputProcessor.class.getName());
- }
- break;
- case ENCRYPT_WITH_DERIVED_KEY:
- outputProcessorChain.getSecurityContext().put(Constants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY, ekId);
- if (wrappingSecurityToken.getProcessor() != null) {
- finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
- } else {
- finalEncryptedKeyOutputProcessor.getAfterProcessors().add(EncryptEndingOutputProcessor.class.getName());
- }
- break;
+ XMLSecurityConstants.Action action = getAction();
+ if (action.equals(WSSConstants.ENCRYPT)) {
+ outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, ekId);
+ if (wrappingSecurityToken.getProcessor() != null) {
+ finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
+ } else {
+ finalEncryptedKeyOutputProcessor.getAfterProcessors().add(org.swssf.wss.impl.processor.output.EncryptEndingOutputProcessor.class.getName());
+ }
+ } else if (action.equals(WSSConstants.SIGNATURE_WITH_DERIVED_KEY)) {
+ outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY, ekId);
+ if (wrappingSecurityToken.getProcessor() != null) {
+ finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
+ } else {
+ finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(org.swssf.wss.impl.processor.output.SignatureOutputProcessor.class.getName());
+ }
+ } else if (action.equals(WSSConstants.ENCRYPT_WITH_DERIVED_KEY)) {
+ outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_DERIVED_KEY, ekId);
+ if (wrappingSecurityToken.getProcessor() != null) {
+ finalEncryptedKeyOutputProcessor.getBeforeProcessors().add(wrappingSecurityToken.getProcessor());
+ } else {
+ finalEncryptedKeyOutputProcessor.getAfterProcessors().add(org.swssf.wss.impl.processor.output.EncryptEndingOutputProcessor.class.getName());
+ }
}
outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(ekId, encryptedKeySecurityTokenProvider);
encryptedKeySecurityToken.setProcessor(finalEncryptedKeyOutputProcessor);
@@ -178,7 +178,7 @@ public class EncryptedKeyOutputProcessor
private SecurityToken securityToken;
- FinalEncryptedKeyOutputProcessor(SecurityProperties securityProperties, Constants.Action action, SecurityToken securityToken) throws WSSecurityException {
+ FinalEncryptedKeyOutputProcessor(XMLSecurityProperties securityProperties, XMLSecurityConstants.Action action, SecurityToken securityToken) throws XMLSecurityException {
super(securityProperties, action);
this.getAfterProcessors().add(FinalEncryptedKeyOutputProcessor.class.getName());
this.securityToken = securityToken;
@@ -206,28 +206,28 @@ public class EncryptedKeyOutputProcessor
*/
@Override
- public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, WSSecurityException {
+ public void processEvent(XMLEvent xmlEvent, OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
outputProcessorChain.processEvent(xmlEvent);
if (xmlEvent.isStartElement()) {
StartElement startElement = xmlEvent.asStartElement();
- if (outputProcessorChain.getDocumentContext().isInSecurityHeader() && startElement.getName().equals(Constants.TAG_wsse_Security)) {
+ if (((WSSDocumentContext) outputProcessorChain.getDocumentContext()).isInSecurityHeader() && startElement.getName().equals(WSSConstants.TAG_wsse_Security)) {
OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
X509Certificate x509Certificate = securityToken.getKeyWrappingToken().getX509Certificates()[0];
Map<QName, String> attributes = new HashMap<QName, String>();
- attributes.put(Constants.ATT_NULL_Id, securityToken.getId());
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_EncryptedKey, attributes);
+ attributes.put(WSSConstants.ATT_NULL_Id, securityToken.getId());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_EncryptedKey, attributes);
attributes = new HashMap<QName, String>();
- attributes.put(Constants.ATT_NULL_Algorithm, getSecurityProperties().getEncryptionKeyTransportAlgorithm());
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_EncryptionMethod, attributes);
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_EncryptionMethod);
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_KeyInfo, null);
- createSecurityTokenReferenceStructureForEncryptedKey(subOutputProcessorChain, securityToken, getSecurityProperties().getEncryptionKeyIdentifierType(), getSecurityProperties().isUseSingleCert());
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_dsig_KeyInfo);
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_CipherData, null);
- createStartElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_CipherValue, null);
+ attributes.put(WSSConstants.ATT_NULL_Algorithm, getSecurityProperties().getEncryptionKeyTransportAlgorithm());
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_EncryptionMethod, attributes);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_EncryptionMethod);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_dsig_KeyInfo, null);
+ createSecurityTokenReferenceStructureForEncryptedKey(subOutputProcessorChain, securityToken, ((WSSSecurityProperties) getSecurityProperties()).getEncryptionKeyIdentifierType(), getSecurityProperties().isUseSingleCert());
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_dsig_KeyInfo);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherData, null);
+ createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherValue, null);
try {
//encrypt the symmetric session key with the public key from the receiver:
@@ -258,16 +258,166 @@ public class EncryptedKeyOutputProcessor
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
}
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_CipherValue);
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_CipherData);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherValue);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherData);
- if (getAction() == Constants.Action.ENCRYPT) {
+ if (getAction() == WSSConstants.ENCRYPT) {
createReferenceListStructure(subOutputProcessorChain);
}
- createEndElementAndOutputAsEvent(subOutputProcessorChain, Constants.TAG_xenc_EncryptedKey);
+ createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_EncryptedKey);
outputProcessorChain.removeProcessor(this);
}
}
}
+
+ protected void createSecurityTokenReferenceStructureForEncryptedKey(
+ OutputProcessorChain outputProcessorChain,
+ SecurityToken securityToken,
+ WSSConstants.KeyIdentifierType keyIdentifierType,
+ boolean useSingleCertificate)
+ throws XMLStreamException, XMLSecurityException {
+
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_wsu_Id, "STRId-" + UUID.randomUUID().toString());
+ if ((keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.BST_DIRECT_REFERENCE.name())
+ || keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.BST_EMBEDDED.name()))
+ && !useSingleCertificate) {
+ attributes.put(WSSConstants.ATT_wsse11_TokenType, WSSConstants.NS_X509PKIPathv1);
+ }
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_SecurityTokenReference, attributes);
+
+ X509Certificate[] x509Certificates = securityToken.getKeyWrappingToken().getX509Certificates();
+ String tokenId = securityToken.getKeyWrappingToken().getId();
+
+ if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.ISSUER_SERIAL.name())) {
+ createX509IssuerSerialStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.SKI_KEY_IDENTIFIER.name())) {
+ createX509SubjectKeyIdentifierStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.X509_KEY_IDENTIFIER.name())) {
+ createX509KeyIdentifierStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.THUMBPRINT_IDENTIFIER.name())) {
+ createThumbprintKeyIdentifierStructure(outputProcessorChain, x509Certificates);
+ } else if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.BST_EMBEDDED.name())) {
+ createBSTReferenceStructure(outputProcessorChain, tokenId, x509Certificates, useSingleCertificate, true);
+ } else if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.BST_DIRECT_REFERENCE.name())) {
+ createBSTReferenceStructure(outputProcessorChain, tokenId, x509Certificates, useSingleCertificate, false);
+ } else if (keyIdentifierType.name().equals(WSSConstants.KeyIdentifierType.EMBEDDED_SECURITY_TOKEN_REF.name())) {
+ createEmbeddedSecurityTokenReferenceStructure(outputProcessorChain, tokenId);
+ } else {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_ENCRYPTION, "unsupportedSecurityToken", keyIdentifierType.name());
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_SecurityTokenReference);
+ }
+
+ //todo common method
+ protected void createX509SubjectKeyIdentifierStructure(OutputProcessorChain outputProcessorChain, X509Certificate[] x509Certificates) throws XMLSecurityException, XMLStreamException {
+ // As per the 1.1 specification, SKI can only be used for a V3 certificate
+ if (x509Certificates[0].getVersion() != 3) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, "invalidCertForSKI");
+ }
+
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, WSSConstants.NS_X509SubjectKeyIdentifier);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier, attributes);
+ byte data[] = new Merlin().getSKIBytesFromCert(x509Certificates[0]);
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(data));
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier);
+ }
+
+ //todo common method
+ protected void createX509KeyIdentifierStructure(OutputProcessorChain outputProcessorChain, X509Certificate[] x509Certificates) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, WSSConstants.NS_X509_V3_TYPE);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier, attributes);
+ try {
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(x509Certificates[0].getEncoded()));
+ } catch (CertificateEncodingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier);
+ }
+
+ //todo common methdod
+ protected void createThumbprintKeyIdentifierStructure(OutputProcessorChain outputProcessorChain, X509Certificate[] x509Certificates) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, WSSConstants.NS_THUMBPRINT);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier, attributes);
+ try {
+ MessageDigest sha;
+ sha = MessageDigest.getInstance("SHA-1");
+ sha.reset();
+ sha.update(x509Certificates[0].getEncoded());
+ byte[] data = sha.digest();
+
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(data));
+ } catch (CertificateEncodingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_KeyIdentifier);
+ }
+
+ //todo common method
+ protected void createBSTReferenceStructure(OutputProcessorChain outputProcessorChain, String referenceId, X509Certificate[] x509Certificates, boolean useSingleCertificate, boolean embed) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ String valueType;
+ if (useSingleCertificate) {
+ valueType = WSSConstants.NS_X509_V3_TYPE;
+ } else {
+ valueType = WSSConstants.NS_X509PKIPathv1;
+ }
+ attributes.put(WSSConstants.ATT_NULL_URI, "#" + referenceId);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, valueType);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference, attributes);
+ if (embed) {
+ createBinarySecurityTokenStructure(outputProcessorChain, referenceId, x509Certificates, useSingleCertificate);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference);
+ }
+
+ //todo common method
+ protected void createEmbeddedSecurityTokenReferenceStructure(OutputProcessorChain outputProcessorChain, String referenceId) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(WSSConstants.ATT_NULL_URI, "#" + referenceId);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference, attributes);
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_Reference);
+ }
+
+ //todo common method
+ protected void createBinarySecurityTokenStructure(OutputProcessorChain outputProcessorChain, String referenceId, X509Certificate[] x509Certificates, boolean useSingleCertificate) throws XMLStreamException, XMLSecurityException {
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ String valueType;
+ if (useSingleCertificate) {
+ valueType = WSSConstants.NS_X509_V3_TYPE;
+ } else {
+ valueType = WSSConstants.NS_X509PKIPathv1;
+ }
+ attributes.put(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING);
+ attributes.put(WSSConstants.ATT_NULL_ValueType, valueType);
+ attributes.put(WSSConstants.ATT_wsu_Id, referenceId);
+ createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_BinarySecurityToken, attributes);
+ try {
+ if (useSingleCertificate) {
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(x509Certificates[0].getEncoded()));
+ } else {
+ try {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
+ List<X509Certificate> certificates = Arrays.asList(x509Certificates);
+ createCharactersAndOutputAsEvent(outputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(certificateFactory.generateCertPath(certificates).getEncoded()));
+ } catch (CertificateException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
+ } catch (NoSuchProviderException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
+ }
+ }
+ } catch (CertificateEncodingException e) {
+ throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+ }
+ createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_wsse_BinarySecurityToken);
+ }
}
}