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);