blob: eb7d531f3e4d65f79debf9ca4145559bfcdeb4f6 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.rampart.builder;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.context.MessageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.EncryptedKeyToken;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.TrustException;
import org.apache.rampart.RampartConstants;
import org.apache.rampart.RampartException;
import org.apache.rampart.RampartMessageData;
import org.apache.rampart.policy.RampartPolicyData;
import org.apache.rampart.util.RampartUtil;
import org.apache.ws.secpolicy.SPConstants;
import org.apache.ws.secpolicy.model.AlgorithmSuite;
import org.apache.ws.secpolicy.model.IssuedToken;
import org.apache.ws.secpolicy.model.SecureConversationToken;
import org.apache.ws.secpolicy.model.SupportingToken;
import org.apache.ws.secpolicy.model.Token;
import org.apache.ws.secpolicy.model.X509Token;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.conversation.ConversationException;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.handler.WSHandlerResult;
import org.apache.ws.security.message.WSSecDKEncrypt;
import org.apache.ws.security.message.WSSecEncrypt;
import org.apache.ws.security.message.WSSecEncryptedKey;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.util.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
public class SymmetricBindingBuilder extends BindingBuilder {
private static Log log = LogFactory.getLog(SymmetricBindingBuilder.class);
private static Log tlog = LogFactory.getLog(RampartConstants.TIME_LOG);
private boolean dotDebug = false;
public SymmetricBindingBuilder(){
dotDebug = tlog.isDebugEnabled();
}
public void build(RampartMessageData rmd) throws RampartException {
log.debug("SymmetricBindingBuilder build invoked");
RampartPolicyData rpd = rmd.getPolicyData();
if(rpd.isIncludeTimestamp()) {
this.addTimestamp(rmd);
}
if(rmd.isInitiator()) {
//Setup required tokens
initializeTokens(rmd);
}
if(SPConstants.ENCRYPT_BEFORE_SIGNING.equals(rpd.getProtectionOrder())) {
this.doEncryptBeforeSig(rmd);
} else {
this.doSignBeforeEncrypt(rmd);
}
log.debug("SymmetricBindingBuilder build invoked : DONE");
}
private void doEncryptBeforeSig(RampartMessageData rmd) throws RampartException {
long t0 = 0, t1 = 0, t2 = 0;
RampartPolicyData rpd = rmd.getPolicyData();
Vector signatureValues = new Vector();
if(dotDebug){
t0 = System.currentTimeMillis();
}
Token encryptionToken = rpd.getEncryptionToken();
Vector encrParts = RampartUtil.getEncryptedParts(rmd);
Vector sigParts = RampartUtil.getSignedParts(rmd);
if(encryptionToken == null && encrParts.size() > 0) {
throw new RampartException("encryptionTokenMissing");
}
if(encryptionToken != null && encrParts.size() > 0) {
//The encryption token can be an IssuedToken or a
//SecureConversationToken
String tokenId = null;
org.apache.rahas.Token tok = null;
if(encryptionToken instanceof IssuedToken) {
tokenId = rmd.getIssuedEncryptionTokenId();
log.debug("Issued EncryptionToken Id : " + tokenId);
} else if(encryptionToken instanceof SecureConversationToken) {
tokenId = rmd.getSecConvTokenId();
log.debug("SCT Id : " + tokenId);
} else if (encryptionToken instanceof X509Token) {
if (rmd.isInitiator()) {
tokenId = setupEncryptedKey(rmd, encryptionToken);
} else {
tokenId = getEncryptedKey(rmd);
}
} //TODO SAMLToken
if(tokenId == null || tokenId.length() == 0) {
throw new RampartException("noSecurityToken");
}
//Hack to handle reference id issues
//TODO Need a better fix
if(tokenId.startsWith("#")) {
tokenId = tokenId.substring(1);
}
/*
* Get hold of the token from the token storage
*/
tok = this.getToken(rmd, tokenId);
/*
* Attach the token into the message based on token inclusion
* values
*/
boolean attached = false;
Element encrTokenElement = null;
Element refList = null;
WSSecDKEncrypt dkEncr = null;
WSSecEncrypt encr = null;
Element encrDKTokenElem = null;
if(SPConstants.INCLUDE_TOEKN_ALWAYS == encryptionToken.getInclusion() ||
SPConstants.INCLUDE_TOKEN_ONCE == encryptionToken.getInclusion() ||
(rmd.isInitiator() && SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == encryptionToken.getInclusion())) {
encrTokenElement = RampartUtil.appendChildToSecHeader(rmd, tok.getToken());
attached = true;
} else if(encryptionToken instanceof X509Token && rmd.isInitiator()) {
encrTokenElement = RampartUtil.appendChildToSecHeader(rmd, tok.getToken());
}
Document doc = rmd.getDocument();
AlgorithmSuite algorithmSuite = rpd.getAlgorithmSuite();
if(encryptionToken.isDerivedKeys()) {
log.debug("Use drived keys");
dkEncr = new WSSecDKEncrypt();
if(attached && tok.getAttachedReference() != null) {
dkEncr.setExternalKey(tok.getSecret(), (Element) doc
.importNode((Element) tok.getAttachedReference(),
true));
} else if(tok.getUnattachedReference() != null) {
dkEncr.setExternalKey(tok.getSecret(), (Element) doc
.importNode((Element) tok.getUnattachedReference(),
true));
} else {
dkEncr.setExternalKey(tok.getSecret(), tok.getId());
}
try {
dkEncr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
dkEncr.setDerivedKeyLength(algorithmSuite.getEncryptionDerivedKeyLength()/8);
dkEncr.prepare(doc);
encrDKTokenElem = dkEncr.getdktElement();
RampartUtil.appendChildToSecHeader(rmd, encrDKTokenElem);
refList = dkEncr.encryptForExternalRef(null, encrParts);
} catch (WSSecurityException e) {
throw new RampartException("errorInDKEncr");
} catch (ConversationException e) {
throw new RampartException("errorInDKEncr");
}
} else {
log.debug("NO derived keys, use the shared secret");
encr = new WSSecEncrypt();
encr.setWsConfig(rmd.getConfig());
encr.setEncKeyId(tokenId);
RampartUtil.setEncryptionUser(rmd, encr);
encr.setEphemeralKey(tok.getSecret());
encr.setDocument(doc);
encr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
// SymmKey is already encrypted, no need to do it again
encr.setEncryptSymmKey(false);
if (!rmd.isInitiator() && tok instanceof EncryptedKeyToken) {
encr.setUseKeyIdentifier(true);
encr.setCustomReferenceValue(((EncryptedKeyToken)tok).getSHA1());
encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
}
try {
encr.prepare(doc, RampartUtil.getEncryptionCrypto(rpd
.getRampartConfig(), rmd.getCustomClassLoader()));
//Encrypt, get hold of the ref list and add it
refList = encr.encryptForExternalRef(null, encrParts);
} catch (WSSecurityException e) {
throw new RampartException("errorInEncryption", e);
}
}
this.mainRefListElement = RampartUtil.appendChildToSecHeader(rmd, refList);
if(dotDebug){
t1 = System.currentTimeMillis();
}
// Sometimes encryption token is not included in the the message
if (encrTokenElement != null) {
this.setInsertionLocation(encrTokenElement);
} else if (timestampElement != null) {
this.setInsertionLocation(timestampElement);
}
RampartUtil.handleEncryptedSignedHeaders(encrParts, sigParts, doc);
HashMap sigSuppTokMap = null;
HashMap endSuppTokMap = null;
HashMap sgndEndSuppTokMap = null;
HashMap sgndEncSuppTokMap = null;
HashMap endEncSuppTokMap = null;
HashMap sgndEndEncSuppTokMap = null;
if(this.timestampElement != null){
sigParts.add(new WSEncryptionPart(RampartUtil
.addWsuIdToElement((OMElement) this.timestampElement)));
}
if(rmd.isInitiator()) {
// Now add the supporting tokens
SupportingToken sgndSuppTokens = rpd.getSignedSupportingTokens();
sigSuppTokMap = this.handleSupportingTokens(rmd, sgndSuppTokens);
SupportingToken endSuppTokens = rpd.getEndorsingSupportingTokens();
endSuppTokMap = this.handleSupportingTokens(rmd, endSuppTokens);
SupportingToken sgndEndSuppTokens = rpd.getSignedEndorsingSupportingTokens();
sgndEndSuppTokMap = this.handleSupportingTokens(rmd, sgndEndSuppTokens);
SupportingToken sgndEncryptedSuppTokens = rpd.getSignedEncryptedSupportingTokens();
sgndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEncryptedSuppTokens);
SupportingToken endorsingEncryptedSuppTokens = rpd.getEndorsingEncryptedSupportingTokens();
endEncSuppTokMap = this.handleSupportingTokens(rmd, endorsingEncryptedSuppTokens);
SupportingToken sgndEndEncSuppTokens = rpd.getSignedEndorsingEncryptedSupportingTokens();
sgndEndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEndEncSuppTokens);
SupportingToken supportingToks = rpd.getSupportingTokens();
this.handleSupportingTokens(rmd, supportingToks);
SupportingToken encryptedSupportingToks = rpd.getEncryptedSupportingTokens();
this.handleSupportingTokens(rmd, encryptedSupportingToks);
//Setup signature parts
sigParts = addSignatureParts(sigSuppTokMap, sigParts);
sigParts = addSignatureParts(sgndEncSuppTokMap, sigParts);
sigParts = addSignatureParts(sgndEndSuppTokMap, sigParts);
sigParts = addSignatureParts(sgndEndEncSuppTokMap, sigParts);
} else {
addSignatureConfirmation(rmd, sigParts);
}
//Sign the message
//We should use the same key in the case of EncryptBeforeSig
if ( sigParts.size() > 0) {
signatureValues.add(this.doSymmSignature(rmd, encryptionToken, tok, sigParts));
this.mainSigId = RampartUtil.addWsuIdToElement((OMElement)this.getInsertionLocation());
}
if(rmd.isInitiator()) {
endSuppTokMap.putAll(endEncSuppTokMap);
//Do endorsed signatures
Vector endSigVals = this.doEndorsedSignatures(rmd, endSuppTokMap);
for (Iterator iter = endSigVals.iterator(); iter.hasNext();) {
signatureValues.add(iter.next());
}
sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
//Do signed endorsing signatures
Vector sigEndSigVals = this.doEndorsedSignatures(rmd, sgndEndSuppTokMap);
for (Iterator iter = sigEndSigVals.iterator(); iter.hasNext();) {
signatureValues.add(iter.next());
}
}
if(dotDebug){
t2 = System.currentTimeMillis();
tlog.debug("Encryption took :" + (t1 - t0)
+", Signature tool :" + (t2 - t1) );
}
//Check for signature protection and encryption of UsernameToken
if(rpd.isSignatureProtection() && this.mainSigId != null ||
encryptedTokensIdList.size() > 0 && rmd.isInitiator()) {
long t3 = 0, t4 = 0;
if(dotDebug){
t3 = System.currentTimeMillis();
}
log.debug("Signature protection");
Vector secondEncrParts = new Vector();
//Now encrypt the signature using the above token
if(rpd.isSignatureProtection()) {
secondEncrParts.add(new WSEncryptionPart(this.mainSigId, "Element"));
}
if(rmd.isInitiator()) {
for (int i = 0 ; i < encryptedTokensIdList.size(); i++) {
secondEncrParts.add(new WSEncryptionPart((String)encryptedTokensIdList.get(i),"Element"));
}
}
Element secondRefList = null;
if(encryptionToken.isDerivedKeys()) {
try {
secondRefList = dkEncr.encryptForExternalRef(null,
secondEncrParts);
RampartUtil.insertSiblingAfter(
rmd,
encrDKTokenElem,
secondRefList);
} catch (WSSecurityException e) {
throw new RampartException("errorInDKEncr");
}
} else {
try {
//Encrypt, get hold of the ref list and add it
secondRefList = encr.encryptForExternalRef(null,
encrParts);
RampartUtil.insertSiblingAfter(
rmd,
encrTokenElement,
secondRefList);
} catch (WSSecurityException e) {
throw new RampartException("errorInEncryption", e);
}
}
if(dotDebug){
t4 = System.currentTimeMillis();
tlog.debug("Signature protection took :" + (t4 - t3));
}
}
} else {
throw new RampartException("encryptionTokenMissing");
}
}
private void doSignBeforeEncrypt(RampartMessageData rmd) throws RampartException {
long t0 = 0, t1 = 0, t2 = 0;
RampartPolicyData rpd = rmd.getPolicyData();
Document doc = rmd.getDocument();
if(dotDebug){
t0 = System.currentTimeMillis();
}
Token sigToken = rpd.getSignatureToken();
String encrTokId = null;
String sigTokId = null;
org.apache.rahas.Token encrTok = null;
org.apache.rahas.Token sigTok = null;
Element sigTokElem = null;
Vector signatureValues = new Vector();
if(sigToken != null) {
if(sigToken instanceof SecureConversationToken) {
sigTokId = rmd.getSecConvTokenId();
} else if(sigToken instanceof IssuedToken) {
sigTokId = rmd.getIssuedSignatureTokenId();
} else if(sigToken instanceof X509Token) {
if (rmd.isInitiator()) {
sigTokId = setupEncryptedKey(rmd, sigToken);
} else {
sigTokId = getEncryptedKey(rmd);
}
}
} else {
throw new RampartException("signatureTokenMissing");
}
if(sigTokId == null || sigTokId.length() == 0) {
throw new RampartException("noSecurityToken");
}
sigTok = this.getToken(rmd, sigTokId);
if(SPConstants.INCLUDE_TOEKN_ALWAYS == sigToken.getInclusion() ||
SPConstants.INCLUDE_TOKEN_ONCE == sigToken.getInclusion() ||
(rmd.isInitiator() &&
SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == sigToken.getInclusion())) {
sigTokElem = RampartUtil.appendChildToSecHeader(rmd,
sigTok.getToken());
this.setInsertionLocation(sigTokElem);
} else if ( rmd.isInitiator() && sigToken instanceof X509Token) {
sigTokElem = RampartUtil.appendChildToSecHeader(rmd, sigTok.getToken());
//Set the insertion location
this.setInsertionLocation(sigTokElem);
}
HashMap sigSuppTokMap = null;
HashMap endSuppTokMap = null;
HashMap sgndEndSuppTokMap = null;
HashMap sgndEncSuppTokMap = null;
HashMap endEncSuppTokMap = null;
HashMap sgndEndEncSuppTokMap = null;
Vector sigParts = RampartUtil.getSignedParts(rmd);
if(this.timestampElement != null){
sigParts.add(new WSEncryptionPart(RampartUtil
.addWsuIdToElement((OMElement) this.timestampElement)));
}
if(rmd.isInitiator()) {
// Now add the supporting tokens
SupportingToken sgndSuppTokens = rpd.getSignedSupportingTokens();
sigSuppTokMap = this.handleSupportingTokens(rmd, sgndSuppTokens);
SupportingToken endSuppTokens = rpd.getEndorsingSupportingTokens();
endSuppTokMap = this.handleSupportingTokens(rmd, endSuppTokens);
SupportingToken sgndEndSuppTokens = rpd.getSignedEndorsingSupportingTokens();
sgndEndSuppTokMap = this.handleSupportingTokens(rmd, sgndEndSuppTokens);
SupportingToken sgndEncryptedSuppTokens = rpd.getSignedEncryptedSupportingTokens();
sgndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEncryptedSuppTokens);
SupportingToken endorsingEncryptedSuppTokens = rpd.getEndorsingEncryptedSupportingTokens();
endEncSuppTokMap = this.handleSupportingTokens(rmd, endorsingEncryptedSuppTokens);
SupportingToken sgndEndEncSuppTokens = rpd.getSignedEndorsingEncryptedSupportingTokens();
sgndEndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEndEncSuppTokens);
SupportingToken supportingToks = rpd.getSupportingTokens();
this.handleSupportingTokens(rmd, supportingToks);
SupportingToken encryptedSupportingToks = rpd.getEncryptedSupportingTokens();
this.handleSupportingTokens(rmd, encryptedSupportingToks);
//Setup signature parts
sigParts = addSignatureParts(sigSuppTokMap, sigParts);
sigParts = addSignatureParts(sgndEncSuppTokMap, sigParts);
sigParts = addSignatureParts(sgndEndSuppTokMap, sigParts);
sigParts = addSignatureParts(sgndEndEncSuppTokMap, sigParts);
} else {
addSignatureConfirmation(rmd, sigParts);
}
if (sigParts.size() > 0 ) {
//Sign the message
signatureValues.add(this.doSymmSignature(rmd, sigToken, sigTok, sigParts));
this.mainSigId = RampartUtil.addWsuIdToElement((OMElement)this.getInsertionLocation());
}
if(rmd.isInitiator()) {
// Adding the endorsing encrypted supporting tokens to endorsing supporting tokens
endSuppTokMap.putAll(endEncSuppTokMap);
//Do endorsed signatures
Vector endSigVals = this.doEndorsedSignatures(rmd, endSuppTokMap);
for (Iterator iter = endSigVals.iterator(); iter.hasNext();) {
signatureValues.add(iter.next());
}
//Adding the signed endorsed encrypted tokens to signed endorsed supporting tokens
sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
//Do signed endorsing signatures
Vector sigEndSigVals = this.doEndorsedSignatures(rmd, sgndEndSuppTokMap);
for (Iterator iter = sigEndSigVals.iterator(); iter.hasNext();) {
signatureValues.add(iter.next());
}
}
if(dotDebug){
t1 = System.currentTimeMillis();
}
//Encryption
Token encrToken = rpd.getEncryptionToken();
Element encrTokElem = null;
if(sigToken.equals(encrToken)) {
//Use the same token
encrTokId = sigTokId;
encrTok = sigTok;
encrTokElem = sigTokElem;
} else {
encrTokId = rmd.getIssuedEncryptionTokenId();
encrTok = this.getToken(rmd, encrTokId);
if(SPConstants.INCLUDE_TOEKN_ALWAYS == encrToken.getInclusion() ||
SPConstants.INCLUDE_TOKEN_ONCE == encrToken.getInclusion() ||
(rmd.isInitiator() && SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == encrToken.getInclusion())) {
encrTokElem = (Element)encrTok.getToken();
//Add the encrToken element before the sigToken element
RampartUtil.insertSiblingBefore(rmd, sigTokElem, encrTokElem);
}
}
Vector encrParts = RampartUtil.getEncryptedParts(rmd);
//Check for signature protection
if(rpd.isSignatureProtection() && this.mainSigId != null) {
//Now encrypt the signature using the above token
encrParts.add(new WSEncryptionPart(this.mainSigId, "Element"));
}
if(rmd.isInitiator()) {
for (int i = 0 ; i < encryptedTokensIdList.size(); i++) {
encrParts.add(new WSEncryptionPart((String)encryptedTokensIdList.get(i),"Element"));
}
}
Element refList = null;
if(encrParts.size() > 0) {
//The sec conv token can be used without derived keys
if(encrToken.isDerivedKeys()) {
try {
WSSecDKEncrypt dkEncr = new WSSecDKEncrypt();
if(encrTokElem != null && encrTok.getAttachedReference() != null) {
dkEncr.setExternalKey(encrTok.getSecret(), (Element) doc
.importNode((Element) encrTok.getAttachedReference(),
true));
} else if(encrTok.getUnattachedReference() != null) {
dkEncr.setExternalKey(encrTok.getSecret(), (Element) doc
.importNode((Element) encrTok.getUnattachedReference(),
true));
} else if (!rmd.isInitiator() && encrToken.isDerivedKeys()) {
// If the Encrypted key used to create the derived key is not
// attached use key identifier as defined in WSS1.1 section
// 7.7 Encrypted Key reference
SecurityTokenReference tokenRef = new SecurityTokenReference(doc);
if(encrTok instanceof EncryptedKeyToken) {
tokenRef.setKeyIdentifierEncKeySHA1(((EncryptedKeyToken)encrTok).getSHA1());
}
dkEncr.setExternalKey(encrTok.getSecret(), tokenRef.getElement());
} else {
dkEncr.setExternalKey(encrTok.getSecret(), encrTok.getId());
}
if(encrTok instanceof EncryptedKeyToken) {
dkEncr.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
+ WSConstants.ENC_KEY_VALUE_TYPE);
}
dkEncr.setSymmetricEncAlgorithm(rpd.getAlgorithmSuite().getEncryption());
dkEncr.setDerivedKeyLength(rpd.getAlgorithmSuite().getEncryptionDerivedKeyLength()/8);
dkEncr.prepare(doc);
Element encrDKTokenElem = null;
encrDKTokenElem = dkEncr.getdktElement();
if(encrTokElem != null) {
RampartUtil.insertSiblingAfter(rmd, encrTokElem, encrDKTokenElem);
} else if (timestampElement != null){
RampartUtil.insertSiblingAfter(rmd, this.timestampElement, encrDKTokenElem);
} else {
RampartUtil.insertSiblingBefore(rmd, this.getInsertionLocation(), encrDKTokenElem);
}
refList = dkEncr.encryptForExternalRef(null, encrParts);
RampartUtil.insertSiblingAfter(rmd,
encrDKTokenElem,
refList);
} catch (WSSecurityException e) {
throw new RampartException("errorInDKEncr");
} catch (ConversationException e) {
throw new RampartException("errorInDKEncr");
}
} else {
try {
WSSecEncrypt encr = new WSSecEncrypt();
encr.setWsConfig(rmd.getConfig());
//Hack to handle reference id issues
//TODO Need a better fix
if(encrTokId.startsWith("#")) {
encrTokId = encrTokId.substring(1);
}
encr.setEncKeyId(encrTokId);
encr.setEphemeralKey(encrTok.getSecret());
RampartUtil.setEncryptionUser(rmd, encr);
encr.setDocument(doc);
encr.setEncryptSymmKey(false);
encr.setSymmetricEncAlgorithm(rpd.getAlgorithmSuite().getEncryption());
// Use key identifier in the KeyInfo in server side
if (!rmd.isInitiator()) {
if(encrTok instanceof EncryptedKeyToken) {
encr.setUseKeyIdentifier(true);
encr.setCustomReferenceValue(((EncryptedKeyToken)encrTok).getSHA1());
encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
}
}
encr.prepare(doc, RampartUtil.getEncryptionCrypto(rpd
.getRampartConfig(), rmd.getCustomClassLoader()));
//Encrypt, get hold of the ref list and add it
refList = encr.encryptForExternalRef(null, encrParts);
if(encrTokElem != null) {
RampartUtil.insertSiblingAfter(rmd,
encrTokElem,
refList);
} else {
RampartUtil.insertSiblingBeforeOrPrepend(rmd,
this.getInsertionLocation(),
refList);
}
} catch (WSSecurityException e) {
throw new RampartException("errorInEncryption", e);
}
}
}
if(dotDebug){
t2 = System.currentTimeMillis();
tlog.debug("Signature took :" + (t1 - t0)
+", Encryption took :" + (t2 - t1) );
}
}
/**
* @param rmd
* @param sigToken
* @return
* @throws RampartException
*/
private String setupEncryptedKey(RampartMessageData rmd, Token sigToken)
throws RampartException {
try {
WSSecEncryptedKey encrKey = this.getEncryptedKeyBuilder(rmd,
sigToken);
String id = encrKey.getId();
byte[] secret = encrKey.getEphemeralKey();
//Create a rahas token from this info and store it so we can use
//it in the next steps
Date created = new Date();
Date expires = new Date();
//TODO make this lifetime configurable ???
expires.setTime(System.currentTimeMillis() + 300000);
org.apache.rahas.EncryptedKeyToken tempTok = new org.apache.rahas.EncryptedKeyToken(
id,
(OMElement) encrKey.getEncryptedKeyElement(),
created,
expires);
tempTok.setSecret(secret);
// Set the SHA1 value of the encrypted key, this is used when the encrypted
// key is referenced via a key identifier of type EncryptedKeySHA1
tempTok.setSHA1(getSHA1(encrKey.getEncryptedEphemeralKey()));
rmd.getTokenStorage().add(tempTok);
String bstTokenId = encrKey.getBSTTokenId();
//If direct ref is used to refer to the cert
//then add the cert to the sec header now
if(bstTokenId != null && bstTokenId.length() > 0) {
RampartUtil.appendChildToSecHeader(rmd,
encrKey.getBinarySecurityTokenElement());
}
return id;
} catch (TrustException e) {
throw new RampartException("errorInAddingTokenIntoStore");
}
}
private String getSHA1(byte[] input) throws RampartException{
MessageDigest sha = null;
try {
sha = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e1) {
throw new RampartException("noSHA1availabe", e1);
}
sha.reset();
sha.update(input);
byte[] data = sha.digest();
return Base64.encode(data);
}
private String getEncryptedKey(RampartMessageData rmd ) throws RampartException {
Vector results = (Vector)rmd.getMsgContext().getProperty(WSHandlerConstants.RECV_RESULTS);
for (int i = 0; i < results.size(); i++) {
WSHandlerResult rResult =
(WSHandlerResult) results.get(i);
Vector wsSecEngineResults = rResult.getResults();
for (int j = 0; j < wsSecEngineResults.size(); j++) {
WSSecurityEngineResult wser =
(WSSecurityEngineResult) wsSecEngineResults.get(j);
Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
if (actInt.intValue() == WSConstants.ENCR) {
if (wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID) != null &&
((String)wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID)).length() != 0) {
try {
String encryptedKeyID = (String)wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID);
Date created = new Date();
Date expires = new Date();
expires.setTime(System.currentTimeMillis() + 300000);
EncryptedKeyToken tempTok = new EncryptedKeyToken(encryptedKeyID,created,expires);
tempTok.setSecret((byte[])wser.get(WSSecurityEngineResult.TAG_DECRYPTED_KEY));
tempTok.setSHA1(getSHA1((byte[])wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_EPHEMERAL_KEY)));
rmd.getTokenStorage().add(tempTok);
return encryptedKeyID;
} catch (TrustException e) {
throw new RampartException("errorInAddingTokenIntoStore");
}
}
}
}
}
return null;
}
/**
* Setup the required tokens
* @param rmd
* @param rpd
* @throws RampartException
*/
private void initializeTokens(RampartMessageData rmd) throws RampartException {
RampartPolicyData rpd = rmd.getPolicyData();
MessageContext msgContext = rmd.getMsgContext();
if(rpd.isSymmetricBinding() && !msgContext.isServerSide()) {
log.debug("Processing symmetric binding: " +
"Setting up encryption token and signature token");
//Setting up encryption token and signature token
Token sigTok = rpd.getSignatureToken();
Token encrTok = rpd.getEncryptionToken();
if(sigTok instanceof IssuedToken) {
log.debug("SignatureToken is an IssuedToken");
if(rmd.getIssuedSignatureTokenId() == null) {
log.debug("No Issuedtoken found, requesting a new token");
IssuedToken issuedToken = (IssuedToken)sigTok;
String id = RampartUtil.getIssuedToken(rmd,
issuedToken);
rmd.setIssuedSignatureTokenId(id);
}
} else if(sigTok instanceof SecureConversationToken) {
log.debug("SignatureToken is a SecureConversationToken");
//TODO check for an existing token and use it
String secConvTokenId = rmd.getSecConvTokenId();
//The RSTR has to be secured with the cancelled token
String action = msgContext.getOptions().getAction();
boolean cancelReqResp = action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RSTR_ACTION_CANCEL_SCT) ||
action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RSTR_ACTION_CANCEL_SCT) ||
action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RST_ACTION_CANCEL_SCT) ||
action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RST_ACTION_CANCEL_SCT);
//In the case of the cancel req or resp we should mark the token as cancelled
if(secConvTokenId != null && cancelReqResp) {
try {
rmd.getTokenStorage().getToken(secConvTokenId).setState(org.apache.rahas.Token.CANCELLED);
msgContext.setProperty(RampartMessageData.SCT_ID, secConvTokenId);
//remove from the local map of contexts
String contextIdentifierKey = RampartUtil.getContextIdentifierKey(msgContext);
RampartUtil.getContextMap(msgContext).remove(contextIdentifierKey);
} catch (TrustException e) {
throw new RampartException("errorExtractingToken");
}
}
if (secConvTokenId == null
|| (secConvTokenId != null &&
(!RampartUtil.isTokenValid(rmd, secConvTokenId) && !cancelReqResp))) {
log.debug("No SecureConversationToken found, " +
"requesting a new token");
SecureConversationToken secConvTok =
(SecureConversationToken) sigTok;
try {
String id = RampartUtil.getSecConvToken(rmd, secConvTok);
rmd.setSecConvTokenId(id);
} catch (TrustException e) {
throw new RampartException("errorInObtainingSct", e);
}
}
}
//If it was the ProtectionToken assertion then sigTok is the
//same as encrTok
if(sigTok.equals(encrTok) && sigTok instanceof IssuedToken) {
log.debug("Symmetric binding uses a ProtectionToken, both" +
" SignatureToken and EncryptionToken are the same");
rmd.setIssuedEncryptionTokenId(rmd.getIssuedEncryptionTokenId());
} else {
//Now we'll have to obtain the encryption token as well :-)
//ASSUMPTION: SecureConversationToken is used as a
//ProtectionToken therefore we only have to process a issued
//token here
log.debug("Obtaining the Encryption Token");
if(rmd.getIssuedEncryptionTokenId() != null) {
log.debug("EncrytionToken not alredy set");
IssuedToken issuedToken = (IssuedToken)encrTok;
String id = RampartUtil.getIssuedToken(rmd,
issuedToken);
rmd.setIssuedEncryptionTokenId(id);
}
}
}
//TODO : Support processing IssuedToken and SecConvToken assertoins
//in supporting tokens, right now we only support UsernameTokens and
//X.509 Tokens
}
}