in modules/rampart-core/src/main/java/org/apache/rampart/builder/AsymmetricBindingBuilder.java [667:817]
private void doSignature(RampartMessageData rmd) throws RampartException {
RampartPolicyData rpd = rmd.getPolicyData();
Document doc = rmd.getDocument();
long t0 = 0, t1 = 0;
if(tlog.isDebugEnabled()){
t0 = System.currentTimeMillis();
}
Token sigToken;
if(rmd.isInitiator()) {
sigToken = rpd.getInitiatorToken();
} else {
sigToken = rpd.getRecipientToken();
}
/**
* Note : It doesn't make sense to use Derived Keys in an Asymmetric binding environment to sign messages.
* In asymmetric binding environment we always sign the message using sender's private key. We do *not*
* use a session/ephemeral key to sign the message. We always use PKC keys to sign and verify messages.
* Therefore we do not need to have following code segment.
* TODO Confirm and remove.
*/
if (sigToken.isDerivedKeys()) {
// Set up the encrypted key to use
if(this.encrKey == null) {
setupEncryptedKey(rmd, sigToken);
}
WSSecDKSign dkSign = new WSSecDKSign(rmd.getSecHeader());
dkSign.setTokenIdentifier(this.encryptedKeyId);
// Set the algo info
dkSign.setSignatureAlgorithm(rpd.getAlgorithmSuite()
.getSymmetricSignature());
dkSign.setDerivedKeyLength(rpd.getAlgorithmSuite()
.getSignatureDerivedKeyLength() / 8);
dkSign.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
+ WSConstants.ENC_KEY_VALUE_TYPE);
try {
dkSign.prepare(this.encryptedKeyValue);
if (rpd.isTokenProtection()) {
sigParts.add(new WSEncryptionPart(encrKey.getId()));
}
List<Reference> referenceList = dkSign.addReferencesToSign(sigParts);
/**
* Add <wsc:DerivedKeyToken>..</wsc:DerivedKeyToken> to security
* header. We need to add this just after Encrypted Key and just before <Signature>..</Signature>
* elements. (As a convention)
*/
if (refList == null) {
//dkSign.appendDKElementToHeader(rmd.getSecHeader());
this.sigDKTElement = RampartUtil.insertSiblingAfter(rmd,
this.getInsertionLocation(), dkSign.getdktElement());
this.setInsertionLocation(this.sigDKTElement);
// Do signature
/**
* Create and prepend signature
*/
dkSign.computeSignature(referenceList, false, this.getInsertionLocation());
} else {
this.sigDKTElement = RampartUtil.insertSiblingBefore(rmd, refList, dkSign.getdktElement());
this.setInsertionLocation(this.sigDKTElement);
// Do signature
/**
* Create and append signature
*/
dkSign.computeSignature(referenceList, true, this.getInsertionLocation());
}
if (RampartUtil.encryptFirst(rpd)) {
// always add encrypt elements after signature. Because we need to first verify the signature
// and decrypt at receiver end.
this.setInsertionLocation(dkSign.getSignatureElement());
} else {
// append timestamp element as next insertion location. Cos in sign and encrypt case the
// receiver first need to decrypt the message => The decryption keys should appear first.
this.setInsertionLocation(this.timestampElement);
}
this.mainSigId = RampartUtil
.addWsuIdToElement((OMElement) dkSign
.getSignatureElement());
signatureValues.add(dkSign.getSignatureValue());
signatureElement = dkSign.getSignatureElement();
} catch (WSSecurityException e) {
throw new RampartException("errorInDerivedKeyTokenSignature", e);
} catch (Exception e) {
throw new RampartException("errorInDerivedKeyTokenSignature", e);
}
} else {
WSSecSignature sig = this.getSignatureBuilder(rmd, sigToken);
Element bstElem = sig.getBinarySecurityTokenElement();
if(bstElem != null) {
bstElem = RampartUtil.insertSiblingAfter(rmd, this
.getInsertionLocation(), bstElem);
this.setInsertionLocation(bstElem);
}
if (rmd.getPolicyData().isTokenProtection()
&& sig.getBSTTokenId() != null) {
sigParts.add(new WSEncryptionPart(sig.getBSTTokenId()));
}
try {
sig.setDigestAlgo(rpd.getAlgorithmSuite().getDigest());
List<Reference> referenceList
= sig.addReferencesToSign(sigParts);
// Do signature
if (this.refList == null) {
/**
* If <ReferenceData>..</ReferenceData> is null append <Signature>..</Signature> element
* to current insertion location.
*/
sig.computeSignature(referenceList, false, this.getInsertionLocation());
} else {
/**
* If <ReferenceData>..</ReferenceData> is not null prepend <Signature>..</Signature> element
* to reference data.
*/
sig.computeSignature(referenceList, true, this.refList);
}
signatureElement = sig.getSignatureElement();
this.setInsertionLocation(signatureElement);
this.mainSigId = RampartUtil.addWsuIdToElement((OMElement) signatureElement);
} catch (WSSecurityException e) {
throw new RampartException("errorInSignatureWithX509Token", e);
}
signatureValues.add(sig.getSignatureValue());
}
if(tlog.isDebugEnabled()){
t1 = System.currentTimeMillis();
tlog.debug("Signature took :" + (t1 - t0));
}
}