org.apache.ws.security.message.token.SecurityTokenReference Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wss4j Show documentation
Show all versions of wss4j Show documentation
The Apache WSS4J project provides a Java implementation of the primary security standards
for Web Services, namely the OASIS Web Services Security (WS-Security) specifications
from the OASIS Web Services Security TC.
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ws.security.message.token;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoType;
import org.apache.ws.security.components.crypto.Merlin;
import org.apache.ws.security.message.CallbackLookup;
import org.apache.ws.security.message.DOMCallbackLookup;
import org.apache.ws.security.util.DOM2Writer;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.ws.security.util.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import javax.xml.namespace.QName;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import java.math.BigInteger;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
/**
* Security Token Reference.
*
* @author Davanum Srinivas ([email protected]).
*/
public class SecurityTokenReference {
public static final String SECURITY_TOKEN_REFERENCE = "SecurityTokenReference";
public static final QName STR_QNAME =
new QName(WSConstants.WSSE_NS, SECURITY_TOKEN_REFERENCE);
public static final String SKI_URI =
WSConstants.X509TOKEN_NS + "#X509SubjectKeyIdentifier";
public static final String THUMB_URI =
WSConstants.SOAPMESSAGE_NS11 + "#" + WSConstants.THUMBPRINT;
public static final String ENC_KEY_SHA1_URI =
WSConstants.SOAPMESSAGE_NS11 + "#" + WSConstants.ENC_KEY_SHA1_URI;
private static org.apache.commons.logging.Log log =
org.apache.commons.logging.LogFactory.getLog(SecurityTokenReference.class);
protected Element element = null;
private DOMX509IssuerSerial issuerSerial = null;
private byte[] skiBytes = null;
private Reference reference = null;
/**
* Constructor.
*
* @param elem A SecurityTokenReference element
* @throws WSSecurityException
*/
public SecurityTokenReference(Element elem) throws WSSecurityException {
this(elem, true);
}
/**
* Constructor.
*
* @param elem A SecurityTokenReference element
* @param bspCompliant whether the SecurityTokenReference processing complies with the
* BSP spec
* @throws WSSecurityException
*/
public SecurityTokenReference(Element elem, boolean bspCompliant) throws WSSecurityException {
element = elem;
QName el = new QName(element.getNamespaceURI(), element.getLocalName());
if (!STR_QNAME.equals(el)) {
throw new WSSecurityException(WSSecurityException.FAILURE, "badElement", new Object[] {STR_QNAME, el});
}
if (bspCompliant) {
checkBSPCompliance();
}
if (containsReference()) {
Node node = element.getFirstChild();
while (node != null) {
if (Node.ELEMENT_NODE == node.getNodeType()
&& WSConstants.WSSE_NS.equals(node.getNamespaceURI())
&& "Reference".equals(node.getLocalName())) {
reference = new Reference((Element)node);
break;
}
node = node.getNextSibling();
}
}
}
/**
* Constructor.
*
* @param doc The Document
*/
public SecurityTokenReference(Document doc) {
element = doc.createElementNS(WSConstants.WSSE_NS, "wsse:SecurityTokenReference");
}
/**
* Add the WSSE Namespace to this STR. The namespace is not added by default for
* efficiency purposes.
*/
public void addWSSENamespace() {
WSSecurityUtil.setNamespace(element, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
}
/**
* Add the WSU Namespace to this STR. The namespace is not added by default for
* efficiency purposes.
*/
public void addWSUNamespace() {
WSSecurityUtil.setNamespace(element, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
}
/**
* Add a wsse11:TokenType attribute to this SecurityTokenReference
* @param tokenType the wsse11:TokenType attribute to add
*/
public void addTokenType(String tokenType) {
if (tokenType != null) {
WSSecurityUtil.setNamespace(element, WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX);
element.setAttributeNS(
WSConstants.WSSE11_NS,
WSConstants.WSSE11_PREFIX + ":" + WSConstants.TOKEN_TYPE,
tokenType
);
}
}
/**
* Get the wsse11:TokenType attribute of this SecurityTokenReference
* @return the value of the wsse11:TokenType attribute
*/
public String getTokenType() {
return element.getAttributeNS(
WSConstants.WSSE11_NS, WSConstants.TOKEN_TYPE
);
}
/**
* set the reference.
*
* @param ref
*/
public void setReference(Reference ref) {
Element elem = getFirstElement();
if (elem != null) {
element.replaceChild(ref.getElement(), elem);
} else {
element.appendChild(ref.getElement());
}
this.reference = ref;
}
/**
* Gets the Reference.
*
* @return the Reference
element contained in this
* SecurityTokenReference
* @throws WSSecurityException
*/
public Reference getReference() throws WSSecurityException {
return reference;
}
/**
* Gets the signing token element, which may be a BinarySecurityToken
*
or a SAML token.
*
* The method gets the URI attribute of the {@link Reference} contained in
* the {@link SecurityTokenReference} and tries to find the referenced
* Element in the document. Alternatively, it gets the value of the KeyIdentifier
* contained in the {@link SecurityTokenReference} and tries to find the referenced
* Element in the document.
*
* @param doc the document that contains the binary security token
* element. This could be different from the document
* that contains the SecurityTokenReference (STR). See
* STRTransform.derefenceBST() method
* @param docInfo A WSDocInfo object containing previous results
* @param cb A CallbackHandler object to obtain tokens that are not in the message
* @return Element containing the signing token, must be a BinarySecurityToken
* @throws WSSecurityException if the referenced element is not found.
*/
public Element getTokenElement(
Document doc, WSDocInfo docInfo, CallbackHandler cb
) throws WSSecurityException {
Reference ref = getReference();
String uri = null;
String valueType = null;
if (ref != null) {
uri = ref.getURI();
valueType = ref.getValueType();
} else {
uri = getKeyIdentifierValue();
valueType = getKeyIdentifierValueType();
}
if (log.isDebugEnabled()) {
log.debug("Token reference uri: " + uri);
log.debug("Token reference ValueType: " + valueType);
}
if (uri == null) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "badReferenceURI"
);
}
Element tokElement =
findProcessedTokenElement(doc, docInfo, cb, uri, valueType);
if (tokElement == null) {
tokElement = findUnprocessedTokenElement(doc, docInfo, cb, uri, valueType);
}
if (tokElement == null) {
throw new WSSecurityException(
WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"noToken",
new Object[]{uri}
);
}
return tokElement;
}
/**
* Find a token that has not been processed already - in other words, it searches for
* the element, rather than trying to access previous results to find the element
* @param doc Parent Document
* @param docInfo WSDocInfo instance
* @param cb CallbackHandler instance
* @param uri URI of the element
* @param type Type of the element
* @return A DOM element
* @throws WSSecurityException
*/
public Element findUnprocessedTokenElement(
Document doc,
WSDocInfo docInfo,
CallbackHandler cb,
String uri,
String type
) throws WSSecurityException {
String id = uri;
if (id.charAt(0) == '#') {
id = id.substring(1);
}
//
// Delegate finding the element to the CallbackLookup instance
//
CallbackLookup callbackLookup = null;
if (docInfo != null) {
callbackLookup = docInfo.getCallbackLookup();
}
if (callbackLookup == null) {
callbackLookup = new DOMCallbackLookup(doc);
}
return callbackLookup.getElement(id, type, true);
}
/**
* Find a token that has been processed already - in other words, it access previous
* results to find the element, rather than conducting a general search
* @param doc Parent Document
* @param docInfo WSDocInfo instance
* @param cb CallbackHandler instance
* @param uri URI of the element
* @param type Type of the element
* @return A DOM element
* @throws WSSecurityException
*/
public Element findProcessedTokenElement(
Document doc,
WSDocInfo docInfo,
CallbackHandler cb,
String uri,
String type
) throws WSSecurityException {
String id = uri;
if (id.charAt(0) == '#') {
id = id.substring(1);
}
//
// Try to find it from the WSDocInfo instance first
//
if (docInfo != null) {
Element token = docInfo.getTokenElement(id);
if (token != null) {
return token;
}
}
//
// Try to find a custom token
//
if (cb != null && (WSConstants.WSC_SCT.equals(type)
|| WSConstants.WSC_SCT_05_12.equals(type)
|| WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(type)
|| WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(type)
|| KerberosSecurity.isKerberosToken(type))) {
//try to find a custom token
WSPasswordCallback pwcb =
new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
try {
cb.handle(new Callback[]{pwcb});
Element assertionElem = pwcb.getCustomToken();
if (assertionElem != null) {
return (Element)doc.importNode(assertionElem, true);
}
} catch (Exception e) {
log.debug(e.getMessage(), e);
// Consume this failure
}
}
return null;
}
/**
* Sets the KeyIdentifier Element as a X509 certificate.
* Takes a X509 certificate, converts its data into base 64 and inserts
* it into a wsse:KeyIdentifier
element, which is placed
* in the wsse:SecurityTokenReference
element.
*
* @param cert is the X509 certificate to be inserted as key identifier
*/
public void setKeyIdentifier(X509Certificate cert)
throws WSSecurityException {
Document doc = element.getOwnerDocument();
byte data[] = null;
try {
data = cert.getEncoded();
} catch (CertificateEncodingException e) {
throw new WSSecurityException(
WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e
);
}
Text text = doc.createTextNode(Base64.encode(data));
createKeyIdentifier(doc, X509Security.X509_V3_TYPE, text, true);
}
/**
* Sets the KeyIdentifier Element as a X509 Subject-Key-Identifier (SKI).
* Takes a X509 certificate, gets the SKI data, converts it into base 64 and
* inserts it into a wsse:KeyIdentifier
element, which is placed
* in the wsse:SecurityTokenReference
element.
*
* @param cert is the X509 certificate to get the SKI
* @param crypto is the Crypto implementation. Used to read SKI info bytes from certificate
*/
public void setKeyIdentifierSKI(X509Certificate cert, Crypto crypto)
throws WSSecurityException {
//
// As per the 1.1 specification, SKI can only be used for a V3 certificate
//
if (cert.getVersion() != 3) {
throw new WSSecurityException(
WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,
"invalidCertForSKI",
new Object[]{Integer.valueOf(cert.getVersion())}
);
}
Document doc = element.getOwnerDocument();
// Fall back to Merlin if crypto parameter is null
Crypto skiCrypto = crypto;
if (skiCrypto == null) {
skiCrypto = new Merlin();
}
byte data[] = skiCrypto.getSKIBytesFromCert(cert);
Text text = doc.createTextNode(Base64.encode(data));
createKeyIdentifier(doc, SKI_URI, text, true);
}
/**
* Sets the KeyIdentifier Element as a Thumbprint.
*
* Takes a X509 certificate, computes its thumbprint using SHA-1, converts
* into base 64 and inserts it into a wsse:KeyIdentifier
* element, which is placed in the wsse:SecurityTokenReference
* element.
*
* @param cert is the X509 certificate to get the thumbprint
*/
public void setKeyIdentifierThumb(X509Certificate cert) throws WSSecurityException {
Document doc = element.getOwnerDocument();
byte[] encodedCert = null;
try {
encodedCert = cert.getEncoded();
} catch (CertificateEncodingException e1) {
throw new WSSecurityException(
WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e1
);
}
try {
byte[] encodedBytes = WSSecurityUtil.generateDigest(encodedCert);
org.w3c.dom.Text text = doc.createTextNode(Base64.encode(encodedBytes));
createKeyIdentifier(doc, THUMB_URI, text, true);
} catch (WSSecurityException e1) {
throw new WSSecurityException(
WSSecurityException.FAILURE, "noSHA1availabe", null, e1
);
}
}
public void setKeyIdentifierEncKeySHA1(String value) throws WSSecurityException {
Document doc = element.getOwnerDocument();
org.w3c.dom.Text text = doc.createTextNode(value);
createKeyIdentifier(doc, ENC_KEY_SHA1_URI, text, true);
}
public void setKeyIdentifier(String valueType, String keyIdVal) throws WSSecurityException {
setKeyIdentifier(valueType, keyIdVal, false);
}
public void setKeyIdentifier(String valueType, String keyIdVal, boolean base64)
throws WSSecurityException {
Document doc = element.getOwnerDocument();
createKeyIdentifier(doc, valueType, doc.createTextNode(keyIdVal), base64);
}
private void createKeyIdentifier(Document doc, String uri, Node node, boolean base64) {
Element keyId = doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
keyId.setAttributeNS(null, "ValueType", uri);
if (base64) {
keyId.setAttributeNS(null, "EncodingType", BinarySecurity.BASE64_ENCODING);
}
keyId.appendChild(node);
Element elem = getFirstElement();
if (elem != null) {
element.replaceChild(keyId, elem);
} else {
element.appendChild(keyId);
}
}
/**
* get the first child element.
*
* @return the first Element
child node
*/
public Element getFirstElement() {
for (Node currentChild = element.getFirstChild();
currentChild != null;
currentChild = currentChild.getNextSibling()
) {
if (Node.ELEMENT_NODE == currentChild.getNodeType()) {
return (Element) currentChild;
}
}
return null;
}
/**
* Gets the KeyIdentifier.
*
* @return the the X509 certificate or zero if a unknown key identifier
* type was detected.
*/
public X509Certificate[] getKeyIdentifier(Crypto crypto) throws WSSecurityException {
Element elem = getFirstElement();
String value = elem.getAttributeNS(null, "ValueType");
if (X509Security.X509_V3_TYPE.equals(value)) {
X509Security token = new X509Security(elem);
if (token != null) {
X509Certificate cert = token.getX509Certificate(crypto);
return new X509Certificate[]{cert};
}
} else if (SKI_URI.equals(value)) {
X509Certificate cert = getX509SKIAlias(crypto);
if (cert != null) {
return new X509Certificate[]{cert};
}
} else if (THUMB_URI.equals(value)) {
Node node = getFirstElement().getFirstChild();
if (node == null) {
return null;
}
if (Node.TEXT_NODE == node.getNodeType()) {
byte[] thumb = Base64.decode(((Text) node).getData());
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.THUMBPRINT_SHA1);
cryptoType.setBytes(thumb);
X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
if (certs != null) {
return new X509Certificate[]{certs[0]};
}
}
}
return null;
}
public String getKeyIdentifierValue() {
if (containsKeyIdentifier()) {
Node node = getFirstElement().getFirstChild();
if (node == null) {
return null;
}
if (node.getNodeType() == Node.TEXT_NODE) {
return ((Text) node).getData();
}
}
return null;
}
public String getKeyIdentifierValueType() {
if (containsKeyIdentifier()) {
Element elem = getFirstElement();
return elem.getAttributeNS(null, "ValueType");
}
return null;
}
public String getKeyIdentifierEncodingType() {
if (containsKeyIdentifier()) {
Element elem = getFirstElement();
return elem.getAttributeNS(null, "EncodingType");
}
return null;
}
public X509Certificate getX509SKIAlias(Crypto crypto) throws WSSecurityException {
if (skiBytes == null) {
skiBytes = getSKIBytes();
if (skiBytes == null) {
return null;
}
}
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.SKI_BYTES);
cryptoType.setBytes(skiBytes);
X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
if (certs != null) {
return certs[0];
}
return null;
}
public byte[] getSKIBytes() {
if (skiBytes != null) {
return skiBytes;
}
Node node = getFirstElement().getFirstChild();
if (node == null) {
return null;
}
if (node.getNodeType() == Node.TEXT_NODE) {
try {
skiBytes = Base64.decode(((Text) node).getData());
} catch (WSSecurityException e) {
return null;
}
}
return skiBytes;
}
/**
* Sets the X509Data.
*
* @param domX509Data the {@link DOMX509Data} to put into this
* SecurityTokenReference
*/
public void setX509Data(DOMX509Data domX509Data) {
Element elem = getFirstElement();
if (elem != null) {
element.replaceChild(domX509Data.getElement(), elem);
} else {
element.appendChild(domX509Data.getElement());
}
}
/**
* Set an unknown element.
*
* @param unknownElement the org.w3c.dom.Element to put into this
* SecurityTokenReference
*/
public void setUnknownElement(Element unknownElement) {
Element elem = getFirstElement();
if (elem != null) {
element.replaceChild(unknownElement, elem);
} else {
element.appendChild(unknownElement);
}
}
/**
* Gets the certificate identified with X509 issuerSerial data.
*
* @return a certificate array or null if nothing found
*/
public X509Certificate[] getX509IssuerSerial(Crypto crypto) throws WSSecurityException {
if (issuerSerial == null) {
issuerSerial = getIssuerSerial();
if (issuerSerial == null) {
return null;
}
}
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ISSUER_SERIAL);
cryptoType.setIssuerSerial(issuerSerial.getIssuer(), issuerSerial.getSerialNumber());
return crypto.getX509Certificates(cryptoType);
}
private DOMX509IssuerSerial getIssuerSerial() throws WSSecurityException {
if (issuerSerial != null) {
return issuerSerial;
}
Element elem = getFirstElement();
if (elem == null) {
return null;
}
if (WSConstants.X509_DATA_LN.equals(elem.getLocalName())) {
elem =
WSSecurityUtil.findElement(
elem, WSConstants.X509_ISSUER_SERIAL_LN, WSConstants.SIG_NS
);
}
issuerSerial = new DOMX509IssuerSerial(elem);
return issuerSerial;
}
/**
* Method containsReference
*
* @return true if the SecurityTokenReference
contains
* a wsse:Reference
element
*/
public boolean containsReference() {
return lengthReference() > 0;
}
/**
* Method lengthReference.
*
* @return number of wsse:Reference
elements in
* the SecurityTokenReference
*/
public int lengthReference() {
return length(WSConstants.WSSE_NS, "Reference");
}
/**
* Method containsX509IssuerSerial
*
* @return true if the SecurityTokenReference
contains
* a ds:IssuerSerial
element
*/
public boolean containsX509IssuerSerial() {
return lengthX509IssuerSerial() > 0;
}
/**
* Method containsX509Data
*
* @return true if the SecurityTokenReference
contains
* a ds:X509Data
element
*/
public boolean containsX509Data() {
return lengthX509Data() > 0;
}
/**
* Method lengthX509IssuerSerial.
*
* @return number of ds:IssuerSerial
elements in
* the SecurityTokenReference
*/
public int lengthX509IssuerSerial() {
return length(WSConstants.SIG_NS, WSConstants.X509_ISSUER_SERIAL_LN);
}
/**
* Method lengthX509Data.
*
* @return number of ds:IssuerSerial
elements in
* the SecurityTokenReference
*/
public int lengthX509Data() {
return length(WSConstants.SIG_NS, WSConstants.X509_DATA_LN);
}
/**
* Method containsKeyIdentifier.
*
* @return true if the SecurityTokenReference
contains
* a wsse:KeyIdentifier
element
*/
public boolean containsKeyIdentifier() {
return lengthKeyIdentifier() > 0;
}
/**
* Method lengthKeyIdentifier.
*
* @return number of wsse:KeyIdentifier
elements in
* the SecurityTokenReference
*/
public int lengthKeyIdentifier() {
return length(WSConstants.WSSE_NS, "KeyIdentifier");
}
/**
* Method length.
*
* @param namespace
* @param localname
* @return number of elements with matching localname and namespace
*/
public int length(String namespace, String localname) {
int result = 0;
Node node = element.getFirstChild();
while (node != null) {
if (Node.ELEMENT_NODE == node.getNodeType()) {
String ns = node.getNamespaceURI();
String name = node.getLocalName();
if ((((namespace != null) && namespace.equals(ns))
|| ((namespace == null) && (ns == null)))
&& (localname.equals(name))
) {
result++;
}
}
node = node.getNextSibling();
}
return result;
}
/**
* Get the DOM element.
*
* @return the DOM element
*/
public Element getElement() {
return element;
}
/**
* set the id.
*
* @param id
*/
public void setID(String id) {
element.setAttributeNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":Id", id);
}
/**
* Get the id
* @return the wsu ID of the element
*/
public String getID() {
return element.getAttributeNS(WSConstants.WSU_NS, "Id");
}
/**
* return the string representation.
*
* @return a representation of this SecurityTokenReference element as a String
*/
public String toString() {
return DOM2Writer.nodeToString((Node) element);
}
/**
* A method to check that the SecurityTokenReference is compliant with the BSP spec.
* @throws WSSecurityException
*/
private void checkBSPCompliance() throws WSSecurityException {
// We can only have one token reference
int result = 0;
Node node = element.getFirstChild();
Element child = null;
while (node != null) {
if (Node.ELEMENT_NODE == node.getNodeType()) {
result++;
child = (Element)node;
}
node = node.getNextSibling();
}
if (result != 1) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "invalidDataRef"
);
}
if ("KeyIdentifier".equals(child.getLocalName())
&& WSConstants.WSSE_NS.equals(child.getNamespaceURI())) {
String valueType = getKeyIdentifierValueType();
// ValueType cannot be null
if (valueType == null || "".equals(valueType)) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "invalidValueType"
);
}
String encodingType = getFirstElement().getAttributeNS(null, "EncodingType");
// Encoding Type must be equal to Base64Binary if it's specified
if (encodingType != null && !"".equals(encodingType)
&& !BinarySecurity.BASE64_ENCODING.equals(encodingType)) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY,
"badEncodingType",
new Object[] {encodingType}
);
}
// Encoding type must be specified other than for a SAML Assertion
if (!WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(valueType)
&& !WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(valueType)
&& (encodingType == null || "".equals(encodingType))) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "noEncodingType"
);
}
} else if ("Embedded".equals(child.getLocalName())) {
result = 0;
node = child.getFirstChild();
while (node != null) {
if (Node.ELEMENT_NODE == node.getNodeType()) {
result++;
// We cannot have a SecurityTokenReference child element
if ("SecurityTokenReference".equals(node.getLocalName())
&& WSConstants.WSSE_NS.equals(node.getNamespaceURI())) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "invalidEmbeddedRef"
);
}
}
node = node.getNextSibling();
}
// We can only have one embedded child
if (result != 1) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "invalidEmbeddedRef"
);
}
}
}
@Override
public int hashCode() {
int result = 17;
try {
Reference reference = getReference();
if (reference != null) {
result = 31 * result + reference.hashCode();
}
} catch (WSSecurityException e) {
log.error(e);
}
String keyIdentifierEncodingType = getKeyIdentifierEncodingType();
if (keyIdentifierEncodingType != null) {
result = 31 * result + keyIdentifierEncodingType.hashCode();
}
String keyIdentifierValueType = getKeyIdentifierValueType();
if (keyIdentifierValueType != null) {
result = 31 * result + keyIdentifierValueType.hashCode();
}
String keyIdentifierValue = getKeyIdentifierValue();
if (keyIdentifierValue != null) {
result = 31 * result + keyIdentifierValue.hashCode();
}
String tokenType = getTokenType();
if (tokenType != null) {
result = 31 * result + tokenType.hashCode();
}
byte[] skiBytes = getSKIBytes();
if (skiBytes != null) {
result = 31 * result + Arrays.hashCode(skiBytes);
}
String issuer = null;
BigInteger serialNumber = null;
try {
issuer = getIssuerSerial().getIssuer();
serialNumber = getIssuerSerial().getSerialNumber();
} catch (WSSecurityException e) {
log.error(e);
}
if (issuer != null) {
result = 31 * result + issuer.hashCode();
}
if (serialNumber != null) {
result = 31 * result + serialNumber.hashCode();
}
return result;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof SecurityTokenReference)) {
return false;
}
SecurityTokenReference tokenReference = (SecurityTokenReference)object;
try {
if (!getReference().equals(tokenReference.getReference())) {
return false;
}
} catch (WSSecurityException e) {
log.error(e);
return false;
}
if (!compare(getKeyIdentifierEncodingType(), tokenReference.getKeyIdentifierEncodingType())) {
return false;
}
if (!compare(getKeyIdentifierValueType(), tokenReference.getKeyIdentifierValueType())) {
return false;
}
if (!compare(getKeyIdentifierValue(), tokenReference.getKeyIdentifierValue())) {
return false;
}
if (!compare(getTokenType(), tokenReference.getTokenType())) {
return false;
}
if (!Arrays.equals(getSKIBytes(), tokenReference.getSKIBytes())) {
return false;
}
try {
if (getIssuerSerial() != null && tokenReference.getIssuerSerial() != null) {
if (!compare(getIssuerSerial().getIssuer(), tokenReference.getIssuerSerial().getIssuer())) {
return false;
}
if (!compare(getIssuerSerial().getSerialNumber(), tokenReference.getIssuerSerial().getSerialNumber())) {
return false;
}
}
} catch (WSSecurityException e) {
log.error(e);
return false;
}
return true;
}
private boolean compare(String item1, String item2) {
if (item1 == null && item2 != null) {
return false;
} else if (item1 != null && !item1.equals(item2)) {
return false;
}
return true;
}
private boolean compare(BigInteger item1, BigInteger item2) {
if (item1 == null && item2 != null) {
return false;
} else if (item1 != null && !item1.equals(item2)) {
return false;
}
return true;
}
}