String tokenType =
XMLSecurityUtils.getQNameAttribute(
securityTokenReferenceType.getOtherAttributes(),
WSSConstants.ATT_wsse11_TokenType);
final KeyIdentifierType keyIdentifierType
= XMLSecurityUtils.getQNameType(securityTokenReferenceType.getAny(), WSSConstants.TAG_wsse_KeyIdentifier);
if (keyIdentifierType != null) {
String valueType = keyIdentifierType.getValueType();
if (valueType == null) {
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R3054);
}
String encodingType = keyIdentifierType.getEncodingType();
byte[] binaryContent = null;
if (WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING.equals(encodingType)) {
binaryContent = Base64.decodeBase64(keyIdentifierType.getValue());
} else if (!WSSConstants.NS_SAML10_TYPE.equals(valueType) && !WSSConstants.NS_SAML20_TYPE.equals(valueType)) {
if (encodingType == null) {
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R3070);
} else {
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R3071);
}
} else if (encodingType != null
&& (WSSConstants.NS_SAML10_TYPE.equals(valueType) || WSSConstants.NS_SAML20_TYPE.equals(valueType))) {
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R6604);
}
if (WSSConstants.NS_X509_V3_TYPE.equals(valueType)) {
return new X509V3SecurityTokenImpl(
(WSInboundSecurityContext) inboundSecurityContext, crypto, callbackHandler,
binaryContent, securityTokenReferenceType.getId(), securityProperties);
} else if (WSSConstants.NS_X509SubjectKeyIdentifier.equals(valueType)) {
return new X509SKISecurityTokenImpl(
(WSInboundSecurityContext) inboundSecurityContext, crypto, callbackHandler, binaryContent,
securityTokenReferenceType.getId(), securityProperties);
} else if (WSSConstants.NS_THUMBPRINT.equals(valueType)) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
//first look if the token is included in the message (necessary for TokenInclusion policy)...
List<SecurityTokenProvider<? extends InboundSecurityToken>> securityTokenProviders =
inboundSecurityContext.getRegisteredSecurityTokenProviders();
for (int i = 0; i < securityTokenProviders.size(); i++) {
SecurityTokenProvider<? extends InboundSecurityToken> tokenProvider = securityTokenProviders.get(i);
InboundSecurityToken inboundSecurityToken = tokenProvider.getSecurityToken();
if (inboundSecurityToken instanceof X509SecurityToken) {
X509SecurityToken x509SecurityToken = (X509SecurityToken)inboundSecurityToken;
byte[] tokenDigest = messageDigest.digest(x509SecurityToken.getX509Certificates()[0].getEncoded());
if (Arrays.equals(tokenDigest, binaryContent)) {
return createSecurityTokenProxy(inboundSecurityToken,
WSSecurityTokenConstants.KeyIdentifier_ThumbprintIdentifier);
}
}
}
} catch (NoSuchAlgorithmException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
} catch (CertificateEncodingException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN);
}
//...then if none is found create a new SecurityToken instance
return new X509ThumbprintSHA1SecurityTokenImpl(
(WSInboundSecurityContext) inboundSecurityContext, crypto, callbackHandler, binaryContent,
securityTokenReferenceType.getId(), securityProperties);
} else if (WSSConstants.NS_ENCRYPTED_KEY_SHA1.equals(valueType)) {
return new EncryptedKeySha1SecurityTokenImpl(
(WSInboundSecurityContext) inboundSecurityContext, callbackHandler, keyIdentifierType.getValue(),
securityTokenReferenceType.getId());
} else if (WSSConstants.NS_SAML10_TYPE.equals(valueType) || WSSConstants.NS_SAML20_TYPE.equals(valueType)) {
if (WSSConstants.NS_SAML20_TYPE.equals(valueType) && !WSSConstants.NS_SAML20_TOKEN_PROFILE_TYPE.equals(tokenType)) {
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R6617);
} else if (WSSConstants.NS_SAML10_TYPE.equals(valueType) && !WSSConstants.NS_SAML11_TOKEN_PROFILE_TYPE.equals(tokenType)) {
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R6611);
}
SecurityTokenProvider<? extends InboundSecurityToken> securityTokenProvider =
inboundSecurityContext.getSecurityTokenProvider(keyIdentifierType.getValue());
if (securityTokenProvider != null) {
return createSecurityTokenProxy(securityTokenProvider.getSecurityToken(),
WSSecurityTokenConstants.KeyIdentifier_SecurityTokenDirectReference);
}
// Delegate to a CallbackHandler, in case the token is not in the request
return new SamlSecurityTokenImpl((WSInboundSecurityContext) inboundSecurityContext,
keyIdentifierType.getValue(),
WSSecurityTokenConstants.KeyIdentifier_ExternalReference,
securityProperties);
} else if (WSSConstants.NS_Kerberos5_AP_REQ_SHA1.equals(valueType)) {
SecurityTokenProvider<? extends InboundSecurityToken> securityTokenProvider =
inboundSecurityContext.getSecurityTokenProvider(keyIdentifierType.getValue());
if (securityTokenProvider != null) {
return createSecurityTokenProxy(securityTokenProvider.getSecurityToken(),
WSSecurityTokenConstants.KeyIdentifier_SecurityTokenDirectReference);
}
try {
//ok we have to find the token via digesting...
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
List<SecurityTokenProvider<? extends InboundSecurityToken>> securityTokenProviders =
inboundSecurityContext.getRegisteredSecurityTokenProviders();
for (int i = 0; i < securityTokenProviders.size(); i++) {
SecurityTokenProvider<? extends InboundSecurityToken> tokenProvider = securityTokenProviders.get(i);
InboundSecurityToken inboundSecurityToken = tokenProvider.getSecurityToken();
if (inboundSecurityToken instanceof KerberosServiceSecurityToken) {
KerberosServiceSecurityToken kerberosSecurityToken = (KerberosServiceSecurityToken)inboundSecurityToken;
byte[] tokenDigest = messageDigest.digest(kerberosSecurityToken.getBinaryContent());
if (Arrays.equals(tokenDigest, binaryContent)) {
return createSecurityTokenProxy(inboundSecurityToken,
WSSecurityTokenConstants.KeyIdentifier_ThumbprintIdentifier);
}
}
}
} catch (NoSuchAlgorithmException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
// Finally, just delegate to a Callback as per EncryptedKeySHA1
return new EncryptedKeySha1SecurityTokenImpl(
(WSInboundSecurityContext) inboundSecurityContext, callbackHandler,
keyIdentifierType.getValue(), securityTokenReferenceType.getId());
} else {
//we do enforce BSP compliance here but will fail anyway since we cannot identify the referenced token
((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R3063);
}
}