//Get the IssuedToken and insert it into the message
GenericToken issuedToken = (GenericToken)trustContext.getSecurityToken();
// check if the token is already present
IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding)keyBinding;
//String ikbPolicyId = ikb.getPolicyToken().getTokenId();
String ikbPolicyId = ikb.getUUID();
//Look for TrustToken in TokenCache
HashMap tokCache = context.getTokenCache();
Object tok = tokCache.get(ikbPolicyId);
SecurityTokenReference str = null;
Element strElem = null;
String tokenVersion = ikb.getIncludeToken();
includeIST = (IssuedTokenKeyBinding.INCLUDE_ALWAYS_TO_RECIPIENT.equals(tokenVersion) ||
IssuedTokenKeyBinding.INCLUDE_ALWAYS.equals(tokenVersion) ||
IssuedTokenKeyBinding.INCLUDE_ALWAYS_VER2.equals(tokenVersion) ||
IssuedTokenKeyBinding.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(tokenVersion)
);
if (includeIST && (issuedToken == null)) {
log.log(Level.SEVERE, "WSS1217.null.IssueToken");
throw new XWSSecurityException("Issued Token to be inserted into the Message was Null");
}
//trust token to be inserted into message
if (issuedToken != null) {
// treat the token as an Opaque entity and just insert the token into message
Element elem = (Element)issuedToken.getTokenValue();
//TODO: remove these expensive conversions DOM Imports
if (tok == null) {
issuedTokenElement = XMLUtil.convertToSoapElement(secureMessage.getSOAPPart(), elem);
//Temp FIX for Issue#26: We need an Id to cache and MS not sending Id in some cases
String tokId = issuedTokenElement.getAttribute("Id");
if ("".equals(tokId) &&
MessageConstants.ENCRYPTED_DATA_LNAME.equals(issuedTokenElement.getLocalName())) {
issuedTokenElement.setAttribute("Id", secureMessage.generateId());
}
tokCache.put(ikbPolicyId, issuedTokenElement);
} else {
issuedTokenInserted = true;
// it will be SOAPElement retrieve its wsuId attr
String wsuId = SecurityUtil.getWsuIdOrId((Element)tok);
issuedTokenElementFromMsg = secureMessage.getElementById(wsuId);
if (issuedTokenElementFromMsg == null) {
log.log(Level.SEVERE, "WSS1218.unableto.locate.IssueToken.Message");
throw new XWSSecurityException("Could not locate Issued Token in Message");
}
}
}
if (includeIST) {
if (trustContext.getAttachedSecurityTokenReference() != null) {
strElem = SecurityUtil.convertSTRToElement(trustContext.getAttachedSecurityTokenReference().getTokenValue(), secureMessage.getSOAPPart());
} else {
log.log(Level.SEVERE, "WSS1219.unableto.refer.Attached.IssueToken");
throw new XWSSecurityException("Cannot determine how to reference the Attached Issued Token in the Message");
}
} else {
//Trust Issued Token should not be in message at all, so use an external reference
if (trustContext.getUnAttachedSecurityTokenReference() != null) {
strElem = SecurityUtil.convertSTRToElement(trustContext.getUnAttachedSecurityTokenReference().getTokenValue(), secureMessage.getSOAPPart());
} else {
log.log(Level.SEVERE, "WSS1220.unableto.refer.Un-Attached.IssueToken");
throw new XWSSecurityException("Cannot determine how to reference the Un-Attached Issued Token in the Message");
}
}
//TODO: remove these expensive conversions
Element imported = (Element)secureMessage.getSOAPPart().importNode(strElem,true);
issuedTokenRef = new SecurityTokenReference(XMLUtil.convertToSoapElement(secureMessage.getSOAPPart(), imported), false);
SecurityUtil.updateSamlVsKeyCache(issuedTokenRef, context, _symmetricKey);
} else if (PolicyTypeUtil.secureConversationTokenKeyBinding(keyBinding)) {
SecureConversationTokenKeyBinding sctBinding = (SecureConversationTokenKeyBinding)keyBinding;
//String sctPolicyId = sctBinding.getPolicyToken().getTokenId();
String sctPolicyId = sctBinding.getUUID();
//Look for SCT in TokenCache
HashMap tokCache = context.getTokenCache();
sct = (SecurityContextTokenImpl)tokCache.get(sctPolicyId);
IssuedTokenContext ictx = context.getSecureConversationContext();
if (sct == null) {
SecurityContextToken sct1 =(SecurityContextToken)ictx.getSecurityToken();
if (sct1 == null) {
log.log(Level.SEVERE,"WSS1221.null.SecureConversationToken");
throw new XWSSecurityException("SecureConversation Token not Found");
}
sct = new SecurityContextTokenImpl(
secureMessage.getSOAPPart(), sct1.getIdentifier().toString(), sct1.getInstance(), sct1.getWsuId(), sct1.getExtElements());
// put back in token cache
tokCache.put(sctPolicyId, sct);
} else {
sctTokenInserted = true;
// record the element
sctElement = secureMessage.getElementByWsuId(sct.getWsuId());
}
String sctWsuId = sct.getWsuId();
if (sctWsuId == null) {
sct.setId(secureMessage.generateId());
}
sctWsuId = sct.getWsuId();
secConvRef = new SecurityTokenReference(secureMessage.getSOAPPart());
DirectReference reference = new DirectReference();
if (SecureConversationTokenKeyBinding.INCLUDE_ALWAYS_TO_RECIPIENT.equals(sctBinding.getIncludeToken()) ||
SecureConversationTokenKeyBinding.INCLUDE_ALWAYS.equals(sctBinding.getIncludeToken())) {
reference.setURI("#" + sctWsuId);
} else {
includeSCT = false;
reference.setSCTURI(sct.getIdentifier().toString(), sct.getInstance());
}
secConvRef.setReference(reference);
referenceType = MessageConstants.DIRECT_REFERENCE_TYPE;
keyInfoStrategy = KeyInfoStrategy.getInstance(referenceType);
String jceAlgo = SecurityUtil.getSecretKeyAlgorithm(dataEncAlgo);
_symmetricKey = new SecretKeySpec(ictx.getProofKey(), jceAlgo);
} else if (PolicyTypeUtil.derivedTokenKeyBinding(keyBinding)){
DerivedTokenKeyBinding dtk = (DerivedTokenKeyBinding)keyBinding.clone();
WSSPolicy originalKeyBinding = dtk.getOriginalKeyBinding();
String algorithm = null;
if(algSuite != null){
algorithm = algSuite.getEncryptionAlgorithm();
}
//The offset and length to be used for DKT
long offset = 0; // Default 0
long length = SecurityUtil.getLengthFromAlgorithm(algorithm);
if (PolicyTypeUtil.x509CertificateBinding(originalKeyBinding)) {
//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);
} else{
skb = (SymmetricKeyBinding)originalKeyBinding;
}
if(sendEKSHA1){
String ekSha1Ref = getEKSHA1Ref(context);
//Construct a derivedKeyToken to be used
originalKey = skb.getSecretKey();
byte[] secret = originalKey.getEncoded();
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, secret);
String dktId = secureMessage.generateId();
String nonce = Base64.encode(dkt.getNonce());
//get the symmetric key for encryption key from derivedkeyToken
try{
String jceAlgo = SecurityUtil.getSecretKeyAlgorithm(algorithm);
_symmetricKey = dkt.generateSymmetricKey(jceAlgo);
} catch(Exception e){
log.log(Level.SEVERE, "WSS1216.unableto.get.symmetrickey.Encryption");
throw new XWSSecurityException(e);
}
//STR for DerivedKeyToken
SecurityTokenReference tokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
EncryptedKeySHA1Identifier refElem = new EncryptedKeySHA1Identifier(secureMessage.getSOAPPart());
refElem.setReferenceValue(ekSha1Ref);
tokenRef.setReference(refElem);
//set the wsse11:TokenType attribute as required by WSS 1.1
//TODO: uncomment this once MS is ready to accpet this
//tokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
dktHeadrBlock =
new DerivedKeyTokenHeaderBlock(_secHeader.getOwnerDocument(), tokenRef, nonce, dkt.getOffset(), dkt.getLength() ,dktId);
//Construct the STR for Encryption
DirectReference reference = new DirectReference();
reference.setURI("#"+dktId);
ekTokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
ekTokenRef.setReference(reference);
} else if(wss11Sender || wss10){
dktSender = true;
originalKey = skb.getSecretKey();
if ( context.getX509CertificateBinding() != null ) {
certificateBinding = context.getX509CertificateBinding();
context.setX509CertificateBinding(null);
_x509Cert = certificateBinding.getX509Certificate();
}
_x509Cert = certificateBinding.getX509Certificate();
referenceType = certificateBinding.getReferenceType();
keyInfoStrategy = KeyInfoStrategy.getInstance(referenceType);
_exportCertificate = true;
keyInfoStrategy.setCertificate(_x509Cert);
x509TokenId = certificateBinding.getUUID();
if(x509TokenId == null || x509TokenId.equals("")){
x509TokenId = secureMsg.generateId();
}
if(log.isLoggable(Level.FINEST)){
log.log(Level.FINEST, "Certificate was "+_x509Cert);
log.log(Level.FINEST, "BinaryToken ID "+x509TokenId);
}
HashMap tokenCache = context.getTokenCache();
HashMap insertedX509Cache = context.getInsertedX509Cache();
SecurityUtil.checkIncludeTokenPolicy(context, certificateBinding, x509TokenId);
// ReferenceType adjustment in checkIncludeTokenPolicy is also currently
// causing an insertion of the X509 into the Message
X509SecurityToken insertedx509 =
(X509SecurityToken)context.getInsertedX509Cache().get(x509TokenId);
// this one is used to determine if the whole BST + EK + DKT(opt)
// has been inserted by another filter such as Encryption running before
X509SecurityToken token = (X509SecurityToken)tokenCache.get(x509TokenId);
if(token == null){
if (insertedx509 != null) {
token = insertedx509;
tokenCache.put(x509TokenId, insertedx509);
} else {
String valueType = certificateBinding.getValueType();
if(valueType==null||valueType.equals("")){
//default valueType for X509 as v3
valueType = MessageConstants.X509v3_NS;
}
token = new X509SecurityToken(secureMsg.getSOAPPart(),_x509Cert,x509TokenId, valueType);
tokenCache.put(x509TokenId, token);
}
context.setCurrentSecret(originalKey);
//Store SymmetricKey generated in ProcessingContext
context.setExtraneousProperty("SecretKey", originalKey);
} else{
skbX509TokenInserted = true;
originalKey = context.getCurrentSecret();
}
//
if(insertedx509 == null){
if(MessageConstants.DIRECT_REFERENCE_TYPE.equals(referenceType)){
secureMsg.findOrCreateSecurityHeader().insertHeaderBlock(token);
insertedX509Cache.put(x509TokenId, token);
x509TokenElement = secureMsg.findOrCreateSecurityHeader().getNextSiblingOfTimestamp();
}
} else{
//x509TokenElement = secureMsg.getElementByWsuId(x509TokenId);
x509TokenElement = insertedx509;
}
//}
//Construct a derivedKeyToken to be used
byte[] secret = originalKey.getEncoded();
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, secret);
String dktId = secureMessage.generateId();
String nonce = Base64.encode(dkt.getNonce());
//get the symmetric key for encryption key from derivedkeyToken
try{
String jceAlgo = SecurityUtil.getSecretKeyAlgorithm(algorithm);
_symmetricKey = dkt.generateSymmetricKey(jceAlgo);
} catch(Exception e){
log.log(Level.SEVERE, "WSS1216.unableto.get.symmetrickey.Encryption");
throw new XWSSecurityException(e);
}
//STR for DerivedKeyToken
SecurityTokenReference tokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
DirectReference reference = new DirectReference();
//TODO: PLUGFEST Commeting for now as Microsoft setting the EncryptedKey type on reference valueType
//tokenRef.setTokenType(MessageConstants.EncryptedKey_NS);
//set id of encrypted key in STR of DKT
insertedEkId = (String)ekCache.get(x509TokenId);
if(insertedEkId == null)
insertedEkId = ekId;
reference.setURI("#"+insertedEkId);
reference.setValueType(MessageConstants.EncryptedKey_NS);
tokenRef.setReference(reference);
dktHeadrBlock =
new DerivedKeyTokenHeaderBlock(_secHeader.getOwnerDocument(), tokenRef, nonce, dkt.getOffset(), dkt.getLength(), dktId);
//Construct the STR for Encryption
DirectReference refEnc = new DirectReference();
refEnc.setURI("#"+dktId);
ekTokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
ekTokenRef.setReference(refEnc);
}
} else if (PolicyTypeUtil.secureConversationTokenKeyBinding(originalKeyBinding)) {
sctWithDKT = true;
SecureConversationTokenKeyBinding sctBinding = (SecureConversationTokenKeyBinding)originalKeyBinding;
//String sctPolicyId = sctBinding.getPolicyToken().getTokenId();
String sctPolicyId = sctBinding.getUUID();
//Look for SCT in TokenCache
HashMap tokCache = context.getTokenCache();
sct = (SecurityContextTokenImpl)tokCache.get(sctPolicyId);
IssuedTokenContext ictx = context.getSecureConversationContext();
if (sct == null) {
SecurityContextToken sct1 =(SecurityContextToken)ictx.getSecurityToken();
if (sct1 == null) {
log.log(Level.SEVERE, "WSS1221.null.SecureConversationToken");
throw new XWSSecurityException("SecureConversation Token not Found");
}
sct = new SecurityContextTokenImpl(
secureMessage.getSOAPPart(), sct1.getIdentifier().toString(), sct1.getInstance(), sct1.getWsuId(), sct1.getExtElements());
// put back in token cache
tokCache.put(sctPolicyId, sct);
} else {
sctTokenInserted = true;
// record the element
sctElement = secureMessage.getElementByWsuId(sct.getWsuId());
}
String sctWsuId = sct.getWsuId();
if (sctWsuId == null) {
sct.setId(secureMessage.generateId());
}
sctWsuId = sct.getWsuId();
byte[] secret = context.getSecureConversationContext().getProofKey();
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, secret);
String dktId = secureMessage.generateId();
String nonce = Base64.encode(dkt.getNonce());
//get the symmetric key for encryption key from derivedkeyToken
try{
_symmetricKey = dkt.generateSymmetricKey(SecurityUtil.getSecretKeyAlgorithm(dataEncAlgo));
} catch(Exception e){
log.log(Level.SEVERE, "WSS1216.unableto.get.symmetrickey.Encryption");
throw new XWSSecurityException(e);
}
//STR for DerivedKeyToken
SecurityTokenReference secRef = new SecurityTokenReference(secureMessage.getSOAPPart());
DirectReference reference = new DirectReference();
if (SecureConversationTokenKeyBinding.INCLUDE_ALWAYS_TO_RECIPIENT.equals(sctBinding.getIncludeToken()) ||
SecureConversationTokenKeyBinding.INCLUDE_ALWAYS.equals(sctBinding.getIncludeToken())) {
reference.setURI("#" + sctWsuId);
} else {
includeSCT = false;
reference.setSCTURI(sct.getIdentifier().toString(), sct.getInstance());
}
secRef.setReference(reference);
dktHeadrBlock =
new DerivedKeyTokenHeaderBlock(_secHeader.getOwnerDocument(), secRef, nonce, dkt.getOffset(), dkt.getLength(),dktId);
//Construct the STR for Encryption
DirectReference refEnc = new DirectReference();
refEnc.setURI("#"+dktId);
dktSctTokenRef = new SecurityTokenReference(secureMessage.getSOAPPart());
dktSctTokenRef.setReference(refEnc);
} else if (PolicyTypeUtil.issuedTokenKeyBinding(originalKeyBinding)) {
issuedWithDKT = true;
IssuedTokenContext trustContext = context.getTrustContext();
DerivedKeyToken dkt = new DerivedKeyTokenImpl(offset, length, trustContext.getProofKey());
String dktId = secureMessage.generateId();
String nonce = Base64.encode(dkt.getNonce());
//get the symmetric key for encryption
Key origKey = null;
try{
origKey = new SecretKeySpec(trustContext.getProofKey(), SecurityUtil.getSecretKeyAlgorithm(dataEncAlgo));
} catch(Exception e){
log.log(Level.SEVERE, "WSS1216.unableto.get.symmetrickey.Encryption");
throw new XWSSecurityException(e);
}
//get the symmetric key for encryption key from derivedkeyToken
try{
_symmetricKey = dkt.generateSymmetricKey(SecurityUtil.getSecretKeyAlgorithm(dataEncAlgo));
} catch(Exception e){
log.log(Level.SEVERE, "WSS1216.unableto.get.symmetrickey.Encryption");
throw new XWSSecurityException(e);
}
//Get the IssuedToken and insert it into the message
GenericToken issuedToken = (GenericToken)trustContext.getSecurityToken();
// check if the token is already present
IssuedTokenKeyBinding ikb = (IssuedTokenKeyBinding)originalKeyBinding;
//String ikbPolicyId = ikb.getPolicyToken().getTokenId();
String ikbPolicyId = ikb.getUUID();
//Look for TrustToken in TokenCache
HashMap tokCache = context.getTokenCache();
Object tok = tokCache.get(ikbPolicyId);
SecurityTokenReference str = null;
Element strElem = null;
String tokenVersion = ikb.getIncludeToken();
includeIST = (IssuedTokenKeyBinding.INCLUDE_ALWAYS_TO_RECIPIENT.equals(tokenVersion) ||
IssuedTokenKeyBinding.INCLUDE_ALWAYS.equals(tokenVersion) ||
IssuedTokenKeyBinding.INCLUDE_ALWAYS_VER2.equals(tokenVersion) ||
IssuedTokenKeyBinding.INCLUDE_ALWAYS_TO_RECIPIENT_VER2.equals(tokenVersion)
);