private void doEncryptBeforeSig()

in modules/rampart-core/src/main/java/org/apache/rampart/builder/AsymmetricBindingBuilder.java [99:355]


    private void doEncryptBeforeSig(RampartMessageData rmd)
            throws RampartException {
    	
    	long t0 = 0, t1 = 0, t2 = 0;
    	if(tlog.isDebugEnabled()){
    		t0 = System.currentTimeMillis();
    	}
        RampartPolicyData rpd = rmd.getPolicyData();
        Document doc = rmd.getDocument();
        RampartConfig config = rpd.getRampartConfig();

        /*
         * We need to hold on to these elements to use them as reference in the
         * case of encrypting the signature
         */
        Element encrDKTokenElem = null;
        WSSecEncrypt encr = null;
        refList = null;
        WSSecDKEncrypt dkEncr = null;
        SecretKey symmetricKey = null;

        /*
         * We MUST use keys derived from the same token
         */
        Token encryptionToken = null;
        if(rmd.isInitiator()) {
            encryptionToken = rpd.getRecipientToken();
        } else {
            encryptionToken = rpd.getInitiatorToken();
        }
        List<WSEncryptionPart> encrParts = RampartUtil.getEncryptedParts(rmd);
        
        //Signed parts are determined before encryption because encrypted signed  headers
        //will not be included otherwise
        this.sigParts = RampartUtil.getSignedParts(rmd);
        
        if(encryptionToken == null && encrParts.size() > 0) {
            throw new RampartException("encryptionTokenMissing");
        }
        
        if (encryptionToken != null && encrParts.size() > 0) {
            
            //Check for RampartConfig assertion
            if(rpd.getRampartConfig() == null) {
                //We'er missing the extra info rampart needs
                throw new RampartException("rampartConigMissing");
            }
            
            if (encryptionToken.isDerivedKeys()) {
                try {
                    this.setupEncryptedKey(rmd, encryptionToken);
                    // Create the DK encryption builder
                    dkEncr = new WSSecDKEncrypt(doc);
                    dkEncr.setTokenIdentifier(this.encryptedKeyId);
                    dkEncr.setDerivedKeyLength(rpd.getAlgorithmSuite().getEncryptionDerivedKeyLength()/8);
                    dkEncr.prepare(this.encryptedKeyValue);

                    // Get and add the DKT element
                    this.encrDKTElement = dkEncr.getdktElement();
                    encrDKTokenElem = RampartUtil.appendChildToSecHeader(rmd, this.encrDKTElement);

                    refList = dkEncr.encryptForExternalRef(null, encrParts);

                } catch (WSSecurityException e) {
                    throw new RampartException("errorCreatingEncryptedKey", e);
                } catch (Exception e) {
                    throw new RampartException("errorInDKEncr", e);
                }
            } else {
                try {
                    WSSecHeader secHeader = new WSSecHeader(doc);
                    secHeader.insertSecurityHeader();
            
                    encr = new WSSecEncrypt(secHeader);

                    KeyGenerator keyGen = KeyUtils.getKeyGenerator(rpd.getAlgorithmSuite().getEncryption());
                    symmetricKey = keyGen.generateKey();
            
                    //Element refs = encr.encryptForRef(null, encrParts, symmetricKey);
                    //encr.addInternalRefElement(refs);


                    RampartUtil.setEncryptionUser(rmd, encr);
                    encr.setSymmetricEncAlgorithm(rpd.getAlgorithmSuite().getEncryption());
                    RampartUtil.setKeyIdentifierType(rmd, encr, encryptionToken);
                    encr.setKeyEncAlgo(rpd.getAlgorithmSuite().getAsymmetricKeyWrap());
                    encr.prepare(RampartUtil.getEncryptionCrypto(config, rmd.getCustomClassLoader()), symmetricKey);

                    Element bstElem = encr.getBinarySecurityTokenElement();
                    if (bstElem != null) {
                        RampartUtil.appendChildToSecHeader(rmd, bstElem);
                    }

                    this.encrTokenElement = encr.getEncryptedKeyElement();
                    this.encrTokenElement = RampartUtil.appendChildToSecHeader(rmd,
                            encrTokenElement);

                    refList = encr.encryptForRef(null, encrParts, symmetricKey);

                } catch (WSSecurityException e) {
                    throw new RampartException("errorInEncryption", e);
                }
            }

            refList = RampartUtil.appendChildToSecHeader(rmd, refList);
            
            if(tlog.isDebugEnabled()){
            	t1 = System.currentTimeMillis();
            }

            this.setInsertionLocation(encrTokenElement);

            RampartUtil.handleEncryptedSignedHeaders(encrParts, this.sigParts, doc);

            // TODO may contain deifferent types of objects as values, therefore cannot use strongly type maps
            // need to figure out a way
            HashMap<Token,Object> sigSuppTokMap = null;
            HashMap<Token,Object> endSuppTokMap = null;
            HashMap<Token,Object> sgndEndSuppTokMap = null;
            HashMap<Token,Object> sgndEncSuppTokMap = null;
            HashMap<Token,Object> endEncSuppTokMap = null;
            HashMap<Token,Object> sgndEndEncSuppTokMap = null;
            
            if(this.timestampElement != null){
            	sigParts.add(RampartUtil.createEncryptionPart(WSConstants.TIMESTAMP_TOKEN_LN,
                            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);
                
                List<SupportingToken> supportingToks = rpd.getSupportingTokensList();
                for (SupportingToken supportingTok : supportingToks) {
                    this.handleSupportingTokens(rmd, supportingTok);
                } 
                
                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 &&
                    rmd.isInitiator() && rpd.getInitiatorToken() != null) || 
                    (!rmd.isInitiator() && rpd.getRecipientToken() != null)) {
                this.doSignature(rmd);
            }

            if (rmd.isInitiator()) {

                if (endSuppTokMap != null) {
                    endSuppTokMap.putAll(endEncSuppTokMap);
                }
                // Do endorsed signatures
                List<byte[]> endSigVals = this.doEndorsedSignatures(rmd,
                        endSuppTokMap);
                for (byte[] endSigVal : endSigVals) {
                    signatureValues.add(endSigVal);
                }

                sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
                // Do signed endorsing signatures
                List<byte[]> sigEndSigVals = this.doEndorsedSignatures(rmd,
                        sgndEndSuppTokMap);
                for (byte[] sigEndSigVal : sigEndSigVals) {
                    signatureValues.add(sigEndSigVal);
                }
            }
            
            if(tlog.isDebugEnabled()){
            	t2 = System.currentTimeMillis();
            	tlog.debug("Encryption took :" + (t1 - t0)
            				+", Signature tool :" + (t2 - t1) );
            }

            // Check for signature protection
            if (rpd.isSignatureProtection() && this.mainSigId != null) {
            	long t3 = 0, t4 = 0;
            	if(tlog.isDebugEnabled()){
            		t3 = System.currentTimeMillis();
            	}

                List<WSEncryptionPart> secondEncrParts = new ArrayList<WSEncryptionPart>();

                // Now encrypt the signature using the above token
                secondEncrParts.add(new WSEncryptionPart(this.mainSigId,
                        "Element"));
                
                if(rmd.isInitiator()) {
                    for (String anEncryptedTokensIdList : encryptedTokensIdList) {
                        secondEncrParts.add(new WSEncryptionPart(anEncryptedTokensIdList, "Element"));
                    }
                }

                Element secondRefList = null;

                if (encryptionToken.isDerivedKeys()) {
                    try {

                        secondRefList = dkEncr.encryptForExternalRef(null,
                                secondEncrParts);
                        RampartUtil.insertSiblingAfter(rmd, encrDKTokenElem,
                                secondRefList);

                    } catch (WSSecurityException e) {
                        throw new RampartException("errorCreatingEncryptedKey",
                                e);
                    }
                } else {
                    try {
                        // Encrypt, get hold of the ref list and add it
                        secondRefList = encr.encryptForRef(null,
                                secondEncrParts, symmetricKey);

                        // Insert the ref list after the encrypted key elem
                        this.setInsertionLocation(RampartUtil
                                .insertSiblingAfter(rmd, encrTokenElement,
                                        secondRefList));
                    } catch (WSSecurityException e) {
                        throw new RampartException("errorInEncryption", e);
                    }
                }
                if(tlog.isDebugEnabled()){
            		t4 = System.currentTimeMillis();
            		tlog.debug("Signature protection took :" + (t4 - t3));
            	}
            }
        }
        
        

    }