private void doSignature()

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

    }