// this is becuase SecurityPolicy Converter never produces this combination
logger.log(Level.SEVERE, LogStringsMessages.WSS_1327_UNSUPPORTED_ASYMMETRICBINDING_DERIVEDKEY_X_509_TOKEN());
throw new XWSSecurityException("Asymmetric Binding with DerivedKeys under X509Token Policy Not Yet Supported");
} else if ( PolicyTypeUtil.symmetricKeyBinding(originalKeyBinding)) {
SymmetricKeyBinding skb = null;
if ( context.getSymmetricKeyBinding() != null) {
skb = context.getSymmetricKeyBinding();
context.setSymmetricKeyBinding(null);
}
//Construct a derivedKeyToken to be used
Key originalKey = null;
if(context.getCurrentSecret() != null){
originalKey = context.getCurrentSecret();
}else{
originalKey = skb.getSecretKey();
context.setCurrentSecret(originalKey);
}
byte[] secret = originalKey.getEncoded();
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, secret);
//get the signing key for signature from derivedkeyToken
signingKey = dkt.generateSymmetricKey(jceAlgo);
Node[] nxtSiblingContainer = new Node[1];
keyInfo = prepareForSymmetricKeySignature(context, keyBinding, originalKey, signaturePolicy, nxtSiblingContainer, null, dkt);
nextSibling = nxtSiblingContainer[0];
} else if ( PolicyTypeUtil.issuedTokenKeyBinding(originalKeyBinding)) {
byte[] prfKey = context.getTrustContext().getProofKey();
if (prfKey == null) {
//handle Asymmetric Issued Token
X509Certificate cert =
context.getTrustContext().getRequestorCertificate();
if (cert == null){
logger.log(Level.SEVERE, LogStringsMessages.WSS_1328_ILLEGAL_CERTIFICATE_KEY_NULL());
throw new XWSSecurityException(
"Requestor Certificate and Proof Key are both null for Issued Token");
}
signingKey = context.getSecurityEnvironment().
getPrivateKey(context.getExtraneousProperties(), cert);
//Get the IssuedToken and insert it into the message
GenericToken issuedToken =
(GenericToken)context.getTrustContext().getSecurityToken();
Element elem = (Element)issuedToken.getTokenValue();
SOAPElement tokenElem =
XMLUtil.convertToSoapElement(secureMessage.getSOAPPart(), elem);
//FIX for Issue 26: We need an Id to cache and MS is not setting in
//some cases
String tokId = tokenElem.getAttribute("Id");
if ("".equals(tokId) &&
MessageConstants.ENCRYPTED_DATA_LNAME.equals(
tokenElem.getLocalName())) {
tokenElem.setAttribute("Id", secureMessage.generateId());
}
context.getTokenCache().put(keyBinding.getUUID(), tokenElem);
IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding)originalKeyBinding;
String iTokenType = ikb.getIncludeToken();
boolean includeToken = (ikb.INCLUDE_ALWAYS_TO_RECIPIENT.equals(iTokenType) ||
ikb.INCLUDE_ALWAYS.equals(iTokenType) ||
ikb.INCLUDE_ALWAYS_VER2.equals(iTokenType) ||
ikb.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(iTokenType)
);
Element strElem = null;
if (includeToken) {
strElem =(Element)context.getTrustContext().
getAttachedSecurityTokenReference().getTokenValue();
}else {
strElem = (Element)context.getTrustContext().
getUnAttachedSecurityTokenReference().getTokenValue();
}
//TODO: remove these expensive conversions
Element imported = (Element)
secureMessage.getSOAPPart().importNode(strElem,true);
SecurityTokenReference str = new SecurityTokenReference(
XMLUtil.convertToSoapElement(secureMessage.getSOAPPart(),
(Element)imported.cloneNode(true)), false);
if (tokenElem != null) {
if(includeToken) {
secureMessage.findOrCreateSecurityHeader().
insertHeaderBlockElement(tokenElem);
nextSibling = tokenElem.getNextSibling();
} else {
nextSibling = null;
}
context.setIssuedSAMLToken(tokenElem);
}
keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,str);
SecurityUtil.updateSamlVsKeyCache(str, context, cert.getPublicKey());
} else {
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, prfKey);
signingKey = dkt.generateSymmetricKey(jceAlgo);
Node[] nxtSiblingContainer = new Node[1];
//NOTE: passing the proofKey here as original key
String secretKeyAlg = "AES";
if (algSuite != null) {
secretKeyAlg = SecurityUtil.getSecretKeyAlgorithm(algSuite.getEncryptionAlgorithm());
}
Key originalKey = new SecretKeySpec(prfKey, secretKeyAlg);
keyInfo = prepareForSymmetricKeySignature(
context, keyBinding, originalKey, signaturePolicy, nxtSiblingContainer, null, dkt);
nextSibling = nxtSiblingContainer[0];
}
} else if (PolicyTypeUtil.secureConversationTokenKeyBinding(originalKeyBinding)) {
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, context.getSecureConversationContext().getProofKey());
//get the signing key for signature from derivedkeyToken
signingKey = dkt.generateSymmetricKey(jceAlgo);
Node[] nxtSiblingContainer = new Node[1];
keyInfo = prepareForSymmetricKeySignature(context, keyBinding, null, signaturePolicy, nxtSiblingContainer, null, dkt);
nextSibling = nxtSiblingContainer[0];
}
} else if ( PolicyTypeUtil.issuedTokenKeyBinding(keyBinding)) {
Node[] nxtSiblingContainer = new Node[1];
// look for the proof token inside the IssuedToken
byte[] proofKey = context.getTrustContext().getProofKey();
if (proofKey == null) {
//handle Asymmetric Issued Token
X509Certificate cert =
context.getTrustContext().getRequestorCertificate();
if (cert == null){
logger.log(Level.SEVERE,LogStringsMessages.WSS_1328_ILLEGAL_CERTIFICATE_KEY_NULL());
throw new XWSSecurityException(
"Requestor Certificate and Proof Key are both null for Issued Token");
}
signingKey = context.getSecurityEnvironment().
getPrivateKey(context.getExtraneousProperties(), cert);
//Get the IssuedToken and insert it into the message
GenericToken issuedToken =
(GenericToken)context.getTrustContext().getSecurityToken();
Element elem = (Element)issuedToken.getTokenValue();
SOAPElement tokenElem =
XMLUtil.convertToSoapElement(secureMessage.getSOAPPart(), elem);
//FIX for Issue 26: We need an Id to cache and MS is not setting in
//some cases
String tokId = tokenElem.getAttribute("Id");
if ("".equals(tokId) &&
MessageConstants.ENCRYPTED_DATA_LNAME.equals(
tokenElem.getLocalName())) {
tokenElem.setAttribute("Id", secureMessage.generateId());
}
context.getTokenCache().put(keyBinding.getUUID(), tokenElem);
IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding)keyBinding;
String iTokenType = ikb.getIncludeToken();
boolean includeToken = (ikb.INCLUDE_ALWAYS_TO_RECIPIENT.equals(iTokenType) ||
ikb.INCLUDE_ALWAYS.equals(iTokenType) ||
ikb.INCLUDE_ALWAYS_VER2.equals(iTokenType) ||
ikb.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(iTokenType)
);
Element strElem = null;
if (includeToken) {
strElem =(Element)context.getTrustContext().
getAttachedSecurityTokenReference().getTokenValue();
}else {
strElem = (Element)context.getTrustContext().
getUnAttachedSecurityTokenReference().getTokenValue();
}
//TODO: remove these expensive conversions
Element imported = (Element)
secureMessage.getSOAPPart().importNode(strElem,true);
SecurityTokenReference str = new SecurityTokenReference(
XMLUtil.convertToSoapElement(secureMessage.getSOAPPart(),
(Element)imported.cloneNode(true)), false);
if (tokenElem != null) {
if(includeToken) {
secureMessage.findOrCreateSecurityHeader().
insertHeaderBlockElement(tokenElem);
nextSibling = tokenElem.getNextSibling();
} else {
nextSibling = null;
}
context.setIssuedSAMLToken(tokenElem);
}
keyInfo = dsigHelper.constructKeyInfo(signaturePolicy,str);
SecurityUtil.updateSamlVsKeyCache(str, context, cert.getPublicKey());
} else {
// symmetric issued
String secretKeyAlg = "AES"; // hardcoding to AES for now
if (algSuite != null) {
secretKeyAlg = SecurityUtil.getSecretKeyAlgorithm(algSuite.getEncryptionAlgorithm());
}
//TODO: assuming proofkey is a byte array in case of Trust as well
signingKey = new SecretKeySpec(proofKey, secretKeyAlg);
keyInfo = prepareForSymmetricKeySignature(
context, keyBinding, signingKey, signaturePolicy, nxtSiblingContainer, null, null);
nextSibling = nxtSiblingContainer[0];
}
} else if (PolicyTypeUtil.secureConversationTokenKeyBinding(keyBinding)) {
//Hack to get the nextSibling node from prepareForSymmetricKeySignature
Node[] nxtSiblingContainer = new Node[1];
keyInfo = prepareForSymmetricKeySignature(
context, keyBinding, null, signaturePolicy, nxtSiblingContainer, null, null);
// look for the proof token inside the secureConversationToken
String secretKeyAlg = "AES"; // hardcoding to AES for now
if (algSuite != null) {
secretKeyAlg = SecurityUtil.getSecretKeyAlgorithm(algSuite.getEncryptionAlgorithm());
}
signingKey = new SecretKeySpec(context.getSecureConversationContext().getProofKey(), secretKeyAlg);
nextSibling = nxtSiblingContainer[0];
} else if(PolicyTypeUtil.x509CertificateBinding(keyBinding)) {
AuthenticationTokenPolicy.X509CertificateBinding certInfo = null;
if ( context.getX509CertificateBinding() != null ) {
certInfo = context.getX509CertificateBinding();
context.setX509CertificateBinding(null);
} else {
certInfo = (AuthenticationTokenPolicy.X509CertificateBinding)keyBinding;
}
PrivateKeyBinding privKBinding = (PrivateKeyBinding)certInfo.getKeyBinding();
signingKey = privKBinding.getPrivateKey();
Node[] nxtSiblingContainer = new Node[1];
keyInfo = handleX509Binding(context, signaturePolicy, certInfo, nxtSiblingContainer);
nextSibling = nxtSiblingContainer[0];
} else if (PolicyTypeUtil.samlTokenPolicy(keyBinding)) {
// populate the policy, the handler should also add a privateKey binding for HOK
AuthenticationTokenPolicy.SAMLAssertionBinding samlBinding =
(AuthenticationTokenPolicy.SAMLAssertionBinding)keyBinding;
PrivateKeyBinding privKBinding = (PrivateKeyBinding)samlBinding.getKeyBinding();
if (privKBinding == null) {
logger.log(Level.SEVERE, LogStringsMessages.WSS_1329_NULL_PRIVATEKEYBINDING_SAML_POLICY());
throw new XWSSecurityException("PrivateKey binding not set for SAML Policy by CallbackHandler");
}
signingKey = privKBinding.getPrivateKey();
if (signingKey == null) {
logger.log(Level.SEVERE, LogStringsMessages.WSS_1330_NULL_PRIVATEKEY_SAML_POLICY());
throw new XWSSecurityException("PrivateKey null inside PrivateKeyBinding set for SAML Policy ");
}
String referenceType = samlBinding.getReferenceType();
if (referenceType.equals(MessageConstants.EMBEDDED_REFERENCE_TYPE)) {
logger.log(Level.SEVERE, LogStringsMessages.WSS_1331_UNSUPPORTED_EMBEDDED_REFERENCE_SAML());
throw new XWSSecurityException("Embedded Reference Type for SAML Assertions not supported yet");
}
String assertionId = samlBinding.getAssertionId();
Element _assertion = samlBinding.getAssertion();
Element _authorityBinding = samlBinding.getAuthorityBinding();
if (assertionId == null) {
if (_assertion == null) {
logger.log(Level.SEVERE, LogStringsMessages.WSS_1332_NULL_SAML_ASSERTION_SAML_ASSERTION_ID());
throw new XWSSecurityException(
"None of SAML Assertion, SAML Assertion Id information was set into " +
" the Policy by the CallbackHandler");
}
if(_assertion.getAttributeNode("ID") != null){
assertionId = _assertion.getAttribute("ID");
}else{
assertionId = _assertion.getAttribute("AssertionID");
}
}
SecurityTokenReference tokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
String strId = samlBinding.getSTRID();
if(strId == null){
strId = secureMessage.generateId();
}
tokenRef.setWsuId(strId);
// set wsse11:TokenType to SAML1.1 or SAML2.0
if(_assertion.getAttributeNode("ID") != null){
tokenRef.setTokenType(MessageConstants.WSSE_SAML_v2_0_TOKEN_TYPE);
}else{
tokenRef.setTokenType(MessageConstants.WSSE_SAML_v1_1_TOKEN_TYPE);
}
if (_authorityBinding != null) {
tokenRef.setSamlAuthorityBinding(_authorityBinding,
secureMessage.getSOAPPart());
}
if ((_assertion != null) && (_authorityBinding == null)) {
//insert the SAML Assertion
SamlAssertionHeaderBlock samlHeaderblock =
new SamlAssertionHeaderBlock(_assertion, secureMessage.getSOAPPart());
secureMessage.findOrCreateSecurityHeader().insertHeaderBlock(samlHeaderblock);
// setting ValueType of Keydentifier to SAML1.1 0r SAML2.0
KeyIdentifierStrategy strat = new KeyIdentifierStrategy(assertionId);
strat.insertKey(tokenRef, secureMessage);
keyInfo = dsigHelper.constructKeyInfo(signaturePolicy, tokenRef);
nextSibling = samlHeaderblock.getAsSoapElement().getNextSibling();
} else {
nextSibling = securityHeader.getNextSiblingOfTimestamp();
}
}else if(PolicyTypeUtil.symmetricKeyBinding(keyBinding)){
SymmetricKeyBinding skb = null;
if ( context.getSymmetricKeyBinding() != null) {
skb = context.getSymmetricKeyBinding();
context.setSymmetricKeyBinding(null);
} else {
skb = (SymmetricKeyBinding)keyBinding;
}
// sign method is HMACSHA-1 for symmetric keys
if(!skb.getKeyIdentifier().equals(MessageConstants._EMPTY)){
signingKey = skb.getSecretKey();
String symmetricKeyName = skb.getKeyIdentifier();
keyInfo = dsigHelper.constructKeyInfo(signaturePolicy, symmetricKeyName);
nextSibling = securityHeader.getNextSiblingOfTimestamp();
} else if(sendEKSHA1){
//get the signing key and EKSHA1 reference from the Subject, it was stored from the incoming message
String ekSha1Ref = getEKSHA1Ref(context);
signingKey = skb.getSecretKey();
SecurityTokenReference secTokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
EncryptedKeySHA1Identifier refElem = new EncryptedKeySHA1Identifier(secureMessage.getSOAPPart());
refElem.setReferenceValue(ekSha1Ref);
secTokenRef.setReference(refElem);
//set the wsse11:TokenType attribute as required by WSS 1.1
//secTokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
keyInfo = dsigHelper.constructKeyInfo(signaturePolicy, secTokenRef);
nextSibling = securityHeader.getNextSiblingOfTimestamp();
//TODO: the below condition is always true
}else if(wss11Sender || wss10){
signingKey = skb.getSecretKey();
AuthenticationTokenPolicy.X509CertificateBinding x509Binding = null;
X509Certificate cert = null;
if(!skb.getCertAlias().equals(MessageConstants._EMPTY)){
x509Binding = new AuthenticationTokenPolicy.X509CertificateBinding();
x509Binding.newPrivateKeyBinding();
x509Binding.setCertificateIdentifier(skb.getCertAlias());
cert = context.getSecurityEnvironment().getCertificate(context.getExtraneousProperties(), x509Binding.getCertificateIdentifier(), false);
x509Binding.setX509Certificate(cert);
x509Binding.setReferenceType("Direct");
}else if ( context.getX509CertificateBinding() != null ) {