blob: 26c7f0a456b44cb6b365300c7bf9a3cac4420ba7 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.wss4j.stax.utils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import org.apache.commons.codec.binary.Base64;
import org.apache.wss4j.common.crypto.Merlin;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.stax.ext.WSSConstants;
import org.apache.wss4j.stax.ext.WSSSecurityProperties;
import org.apache.wss4j.stax.securityEvent.DerivedKeyTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.EncryptedKeyTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.HttpsTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.KerberosTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.KeyValueTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.RelTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.SamlTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.SecurityContextTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.UsernameTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.X509TokenSecurityEvent;
import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.ext.AbstractOutputProcessor;
import org.apache.xml.security.stax.ext.OutputProcessorChain;
import org.apache.xml.security.stax.ext.SecurePart;
import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.stax.ext.XMLSecurityUtils;
import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.stax.impl.EncryptionPartDef;
import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityToken;
public class WSSUtils extends XMLSecurityUtils {
protected WSSUtils() {
super();
}
/**
* Executes the Callback handling. Typically used to fetch passwords
*
* @param callbackHandler
* @param callback
* @throws WSSecurityException if the callback couldn't be executed
*/
public static void doPasswordCallback(CallbackHandler callbackHandler, Callback callback)
throws WSSecurityException {
if (callbackHandler == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCallback");
}
try {
callbackHandler.handle(new Callback[]{callback});
} catch (IOException | UnsupportedCallbackException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
}
/**
* Try to get the secret key from a CallbackHandler implementation
*
* @param callbackHandler a CallbackHandler implementation
* @throws WSSecurityException
*/
public static void doSecretKeyCallback(CallbackHandler callbackHandler, Callback callback, String id)
throws WSSecurityException {
if (callbackHandler != null) {
try {
callbackHandler.handle(new Callback[]{callback});
} catch (IOException | UnsupportedCallbackException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "noPassword");
}
}
}
public static String doPasswordDigest(byte[] nonce, String created, String password) throws WSSecurityException {
try {
byte[] b1 = nonce != null ? nonce : new byte[0];
byte[] b2 = created != null ? created.getBytes(StandardCharsets.UTF_8) : new byte[0];
byte[] b3 = password.getBytes(StandardCharsets.UTF_8);
byte[] b4 = new byte[b1.length + b2.length + b3.length];
int offset = 0;
System.arraycopy(b1, 0, b4, offset, b1.length);
offset += b1.length;
System.arraycopy(b2, 0, b4, offset, b2.length);
offset += b2.length;
System.arraycopy(b3, 0, b4, offset, b3.length);
MessageDigest sha = MessageDigest.getInstance("SHA-1");
sha.reset();
sha.update(b4);
return new String(Base64.encodeBase64(sha.digest()));
} catch (NoSuchAlgorithmException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "decoding.general");
}
}
public static String getSOAPMessageVersionNamespace(XMLSecEvent xmlSecEvent) {
XMLSecStartElement xmlSecStartElement = xmlSecEvent.getStartElementAtLevel(1);
if (xmlSecStartElement != null) {
if (WSSConstants.TAG_SOAP11_ENVELOPE.equals(xmlSecStartElement.getName())) {
return WSSConstants.NS_SOAP11;
} else if (WSSConstants.TAG_SOAP12_ENVELOPE.equals(xmlSecStartElement.getName())) {
return WSSConstants.NS_SOAP12;
}
}
return null;
}
public static boolean isInSOAPHeader(XMLSecEvent xmlSecEvent) {
final List<QName> elementPath = xmlSecEvent.getElementPath();
return isInSOAPHeader(elementPath);
}
public static boolean isInSOAPHeader(List<QName> elementPath) {
if (elementPath.size() > 1) {
final QName secondLevelElementName = elementPath.get(1);
return WSSConstants.TAG_SOAP_HEADER_LN.equals(secondLevelElementName.getLocalPart())
&& elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
}
return false;
}
public static boolean isInSOAPBody(XMLSecEvent xmlSecEvent) {
final List<QName> elementPath = xmlSecEvent.getElementPath();
return isInSOAPBody(elementPath);
}
public static boolean isInSOAPBody(List<QName> elementPath) {
if (elementPath.size() > 1) {
final QName secondLevelElementName = elementPath.get(1);
return WSSConstants.TAG_SOAP_BODY_LN.equals(secondLevelElementName.getLocalPart())
&& elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
}
return false;
}
public static boolean isInSecurityHeader(XMLSecEvent xmlSecEvent, String actorOrRole) {
final List<QName> elementPath = xmlSecEvent.getElementPath();
return isInSecurityHeader(xmlSecEvent, elementPath, actorOrRole);
}
public static boolean isInSecurityHeader(XMLSecEvent xmlSecEvent, List<QName> elementPath, String actorOrRole) {
if (elementPath.size() > 2) {
final QName secondLevelElementName = elementPath.get(1);
return WSSConstants.TAG_WSSE_SECURITY.equals(elementPath.get(2))
&& isResponsibleActorOrRole(xmlSecEvent.getStartElementAtLevel(3), actorOrRole)
&& WSSConstants.TAG_SOAP_HEADER_LN.equals(secondLevelElementName.getLocalPart())
&& elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
}
return false;
}
public static boolean isSecurityHeaderElement(XMLSecEvent xmlSecEvent, String actorOrRole) {
if (!xmlSecEvent.isStartElement()) {
return false;
}
final List<QName> elementPath = xmlSecEvent.getElementPath();
if (elementPath.size() == 3) {
final QName secondLevelElementName = elementPath.get(1);
return WSSConstants.TAG_WSSE_SECURITY.equals(elementPath.get(2))
&& isResponsibleActorOrRole(xmlSecEvent.getStartElementAtLevel(3), actorOrRole)
&& WSSConstants.TAG_SOAP_HEADER_LN.equals(secondLevelElementName.getLocalPart())
&& elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
}
return false;
}
public static boolean isResponsibleActorOrRole(XMLSecStartElement xmlSecStartElement, String responsibleActor) {
final QName actorRole;
final String soapVersionNamespace = getSOAPMessageVersionNamespace(xmlSecStartElement);
if (WSSConstants.NS_SOAP11.equals(soapVersionNamespace)) {
actorRole = WSSConstants.ATT_SOAP11_ACTOR;
} else {
actorRole = WSSConstants.ATT_SOAP12_ROLE;
}
String actor = null;
Attribute attribute = xmlSecStartElement.getAttributeByName(actorRole);
if (attribute != null) {
actor = attribute.getValue();
}
if (responsibleActor == null) {
return actor == null;
} else {
return responsibleActor.equals(actor);
}
}
public static void createBinarySecurityTokenStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain,
String referenceId, X509Certificate[] x509Certificates,
boolean useSingleCertificate)
throws XMLStreamException, XMLSecurityException {
String valueType;
if (useSingleCertificate) {
valueType = WSSConstants.NS_X509_V3_TYPE;
} else {
valueType = WSSConstants.NS_X509_PKIPATH_V1;
}
List<XMLSecAttribute> attributes = new ArrayList<>(3);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, valueType));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_WSU_ID, referenceId));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN,
false, attributes);
try {
if (useSingleCertificate) {
String encodedCert =
new Base64(76, new byte[]{'\n'}).encodeToString(x509Certificates[0].getEncoded());
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
} else {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
List<X509Certificate> certificates = Arrays.asList(x509Certificates);
String encodedCert =
new Base64(76, new byte[]{'\n'}).encodeToString(certificateFactory.generateCertPath(certificates).getEncoded());
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
} catch (CertificateException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
}
} catch (CertificateEncodingException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
}
public static void createX509SubjectKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
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 WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidCertForSKI");
}
List<XMLSecAttribute> attributes = new ArrayList<>(2);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
WSSConstants.NS_X509_SKI));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
byte[] data = new Merlin().getSKIBytesFromCert(x509Certificates[0]);
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain,
new Base64(76, new byte[]{'\n'}).encodeToString(data));
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createX509KeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain,
X509Certificate[] x509Certificates)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(2);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
WSSConstants.NS_X509_V3_TYPE));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
try {
String encodedCert = new Base64(76, new byte[]{'\n'}).encodeToString(x509Certificates[0].getEncoded());
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
} catch (CertificateEncodingException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createThumbprintKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain,
X509Certificate[] x509Certificates)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(2);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
WSSConstants.NS_THUMBPRINT));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byte[] data = sha.digest(x509Certificates[0].getEncoded());
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain,
new Base64(76, new byte[]{'\n'}).encodeToString(data));
} catch (CertificateEncodingException | NoSuchAlgorithmException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createEncryptedKeySha1IdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain, Key key)
throws XMLStreamException, XMLSecurityException {
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byte[] data = sha.digest(key.getEncoded());
createEncryptedKeySha1IdentifierStructure(abstractOutputProcessor, outputProcessorChain,
new Base64(76, new byte[]{'\n'}).encodeToString(data));
} catch (NoSuchAlgorithmException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
}
public static void createEncryptedKeySha1IdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain, String identifier)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(2);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
WSSConstants.NS_ENCRYPTED_KEY_SHA1));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, identifier);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createKerberosSha1IdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain, String identifier)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(2);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
WSSConstants.NS_KERBEROS5_AP_REQ_SHA1));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, identifier);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createBSTReferenceStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain, String referenceId,
String valueType, boolean includedInMessage)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(2);
String uri = includedInMessage ? "#" + referenceId : referenceId;
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI, uri));
if (valueType != null) {
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, valueType));
}
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE,
false, attributes);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE);
}
public static void createEmbeddedKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain,
WSSecurityTokenConstants.TokenType tokenType, String referenceId)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(1);
if (WSSecurityTokenConstants.SAML_10_TOKEN.equals(tokenType) || WSSecurityTokenConstants.SAML_11_TOKEN.equals(tokenType)) {
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML10_TYPE));
} else if (WSSecurityTokenConstants.SAML_20_TOKEN.equals(tokenType)) {
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML20_TYPE));
}
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, referenceId);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createSAMLKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain,
WSSecurityTokenConstants.TokenType tokenType, String referenceId)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(1);
if (WSSecurityTokenConstants.SAML_10_TOKEN.equals(tokenType) || WSSecurityTokenConstants.SAML_11_TOKEN.equals(tokenType)) {
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML10_TYPE));
} else if (WSSecurityTokenConstants.SAML_20_TOKEN.equals(tokenType)) {
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML20_TYPE));
}
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
false, attributes);
abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, referenceId);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
}
public static void createUsernameTokenReferenceStructure(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain, String tokenId)
throws XMLStreamException, XMLSecurityException {
List<XMLSecAttribute> attributes = new ArrayList<>(2);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI, "#" + tokenId));
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
WSSConstants.NS_USERNAMETOKEN_PROFILE_USERNAME_TOKEN));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE,
false, attributes);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE);
}
public static void createReferenceListStructureForEncryption(AbstractOutputProcessor abstractOutputProcessor,
OutputProcessorChain outputProcessorChain)
throws XMLStreamException, XMLSecurityException {
List<EncryptionPartDef> encryptionPartDefs =
outputProcessorChain.getSecurityContext().getAsList(EncryptionPartDef.class);
if (encryptionPartDefs == null) {
return;
}
List<XMLSecAttribute> attributes;
abstractOutputProcessor.createStartElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_xenc_ReferenceList, true, null);
//output the references to the encrypted data:
Iterator<EncryptionPartDef> encryptionPartDefIterator = encryptionPartDefs.iterator();
while (encryptionPartDefIterator.hasNext()) {
EncryptionPartDef encryptionPartDef = encryptionPartDefIterator.next();
attributes = new ArrayList<>(1);
attributes.add(abstractOutputProcessor.createAttribute(
XMLSecurityConstants.ATT_NULL_URI, "#" + encryptionPartDef.getEncRefId()));
abstractOutputProcessor.createStartElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_xenc_DataReference, false, attributes);
final String compressionAlgorithm =
((WSSSecurityProperties)abstractOutputProcessor.getSecurityProperties()).getEncryptionCompressionAlgorithm();
if (compressionAlgorithm != null) {
abstractOutputProcessor.createStartElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms, true, null);
attributes = new ArrayList<>(1);
attributes.add(abstractOutputProcessor.createAttribute(
XMLSecurityConstants.ATT_NULL_Algorithm, compressionAlgorithm));
abstractOutputProcessor.createStartElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform, false, attributes);
abstractOutputProcessor.createEndElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform);
abstractOutputProcessor.createEndElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms);
}
abstractOutputProcessor.createEndElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_xenc_DataReference);
}
abstractOutputProcessor.createEndElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_xenc_ReferenceList);
}
public static void createEncryptedDataStructureForAttachments(
AbstractOutputProcessor abstractOutputProcessor, OutputProcessorChain outputProcessorChain)
throws XMLStreamException, XMLSecurityException {
List<EncryptionPartDef> encryptionPartDefs =
outputProcessorChain.getSecurityContext().getAsList(EncryptionPartDef.class);
if (encryptionPartDefs == null) {
return;
}
Iterator<EncryptionPartDef> encryptionPartDefIterator = encryptionPartDefs.iterator();
while (encryptionPartDefIterator.hasNext()) {
EncryptionPartDef encryptionPartDef = encryptionPartDefIterator.next();
if (encryptionPartDef.getCipherReferenceId() == null) {
continue;
}
List<XMLSecAttribute> attributes = new ArrayList<>(3);
attributes.add(abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Id,
encryptionPartDef.getEncRefId()));
if (encryptionPartDef.getModifier() == SecurePart.Modifier.Element) {
attributes.add(
abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Type,
WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE));
} else {
attributes.add(
abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Type,
WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY));
}
attributes.add(
abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_MimeType,
encryptionPartDef.getMimeType()));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_EncryptedData, true, attributes);
attributes = new ArrayList<>(1);
attributes.add(abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm,
abstractOutputProcessor.getSecurityProperties().getEncryptionSymAlgorithm()));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_EncryptionMethod, false, attributes);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_EncryptionMethod);
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_dsig_KeyInfo, true, null);
attributes = new ArrayList<>(1);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_WSSE11_TOKEN_TYPE,
WSSConstants.NS_WSS_ENC_KEY_VALUE_TYPE));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE, true, attributes);
attributes = new ArrayList<XMLSecAttribute>(1);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI,
"#" + encryptionPartDef.getKeyId()));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_REFERENCE, false, attributes);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_REFERENCE);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_dsig_KeyInfo);
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_CipherData, false, null);
attributes = new ArrayList<>(1);
attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI,
"cid:" + encryptionPartDef.getCipherReferenceId()));
abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_CipherReference, false, attributes);
abstractOutputProcessor.createStartElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_xenc_Transforms, false, null);
attributes = new ArrayList<>(1);
attributes.add(abstractOutputProcessor.createAttribute(
XMLSecurityConstants.ATT_NULL_Algorithm, WSSConstants.SWA_ATTACHMENT_CIPHERTEXT_TRANS));
abstractOutputProcessor.createStartElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform, true, attributes);
abstractOutputProcessor.createEndElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform);
abstractOutputProcessor.createEndElementAndOutputAsEvent(
outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_CipherReference);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_CipherData);
abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
XMLSecurityConstants.TAG_xenc_EncryptedData);
}
}
@SuppressWarnings("unchecked")
public static TokenSecurityEvent<? extends InboundSecurityToken>
createTokenSecurityEvent(final InboundSecurityToken inboundSecurityToken, String correlationID)
throws WSSecurityException {
WSSecurityTokenConstants.TokenType tokenType = inboundSecurityToken.getTokenType();
TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent;
if (WSSecurityTokenConstants.X509V1Token.equals(tokenType)
|| WSSecurityTokenConstants.X509V3Token.equals(tokenType)
|| WSSecurityTokenConstants.X509Pkcs7Token.equals(tokenType)
|| WSSecurityTokenConstants.X509PkiPathV1Token.equals(tokenType)) {
tokenSecurityEvent = new X509TokenSecurityEvent();
} else if (WSSecurityTokenConstants.USERNAME_TOKEN.equals(tokenType)) {
tokenSecurityEvent = new UsernameTokenSecurityEvent();
} else if (WSSecurityTokenConstants.KERBEROS_TOKEN.equals(tokenType)) {
tokenSecurityEvent = new KerberosTokenSecurityEvent();
} else if (WSSecurityTokenConstants.SECURITY_CONTEXT_TOKEN.equals(tokenType)) {
tokenSecurityEvent = new SecurityContextTokenSecurityEvent();
} else if (WSSecurityTokenConstants.SAML_10_TOKEN.equals(tokenType)
|| WSSecurityTokenConstants.SAML_11_TOKEN.equals(tokenType)
|| WSSecurityTokenConstants.SAML_20_TOKEN.equals(tokenType)) {
tokenSecurityEvent = new SamlTokenSecurityEvent();
} else if (WSSecurityTokenConstants.REL_TOKEN.equals(tokenType)) {
tokenSecurityEvent = new RelTokenSecurityEvent();
} else if (WSSecurityTokenConstants.HTTPS_TOKEN.equals(tokenType)) {
tokenSecurityEvent = new HttpsTokenSecurityEvent();
} else if (WSSecurityTokenConstants.KeyValueToken.equals(tokenType)) {
tokenSecurityEvent = new KeyValueTokenSecurityEvent();
} else if (WSSecurityTokenConstants.DerivedKeyToken.equals(tokenType)) {
tokenSecurityEvent = new DerivedKeyTokenSecurityEvent();
} else if (WSSecurityTokenConstants.EncryptedKeyToken.equals(tokenType)) {
tokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
} else {
throw new WSSecurityException(WSSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN);
}
((TokenSecurityEvent<SecurityToken>)tokenSecurityEvent).setSecurityToken(inboundSecurityToken);
tokenSecurityEvent.setCorrelationID(correlationID);
return (TokenSecurityEvent<? extends InboundSecurityToken>)tokenSecurityEvent;
}
public static boolean pathMatches(List<QName> path1, List<QName> path2,
boolean matchAnySoapNS, boolean lastElementWildCard) {
if (path1 == null) {
throw new IllegalArgumentException("Internal error");
}
if (path2 == null || path1.size() != path2.size()) {
return false;
}
Iterator<QName> path1Iterator = path1.iterator();
Iterator<QName> path2Iterator = path2.iterator();
while (path1Iterator.hasNext()) {
QName qName1 = path1Iterator.next();
QName qName2 = path2Iterator.next();
if (matchAnySoapNS && (WSSConstants.NS_SOAP11.equals(qName1.getNamespaceURI())
|| WSSConstants.NS_SOAP12.equals(qName1.getNamespaceURI()))) {
if (!qName1.getLocalPart().equals(qName2.getLocalPart())) {
return false;
}
} else if (!qName1.equals(qName2)) {
if (!path1Iterator.hasNext() && lastElementWildCard) {
if (!qName1.getNamespaceURI().equals(qName2.getNamespaceURI())) {
return false;
}
} else {
return false;
}
}
}
return true;
}
public static String pathAsString(List<QName> path) {
StringBuilder stringBuilder = new StringBuilder();
Iterator<QName> pathIterator = path.iterator();
while (pathIterator.hasNext()) {
QName qName = pathIterator.next();
stringBuilder.append('/');
stringBuilder.append(qName.toString());
}
return stringBuilder.toString();
}
@SuppressWarnings("unchecked")
public static <T extends SecurityToken> T getRootToken(T securityToken) throws XMLSecurityException {
T tmp = securityToken;
while (tmp.getKeyWrappingToken() != null) {
tmp = (T)tmp.getKeyWrappingToken();
}
return tmp;
}
}