private void doEncryptBeforeSig()

in modules/rampart-core/src/main/java/org/apache/rampart/builder/SymmetricBindingBuilder.java [89:381]


    private void doEncryptBeforeSig(RampartMessageData rmd) throws RampartException {
        
    	long t0 = 0, t1 = 0, t2 = 0;
    	       	
        RampartPolicyData rpd = rmd.getPolicyData();
        
        List<byte[]> signatureValues = new ArrayList<byte[]>();
        
    	if(tlog.isDebugEnabled()){
    		t0 = System.currentTimeMillis();
    	}
        
        Token encryptionToken = rpd.getEncryptionToken();
        List<WSEncryptionPart> encrParts = RampartUtil.getEncryptedParts(rmd);

        List<WSEncryptionPart> 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();
                if (log.isDebugEnabled()) {
                    log.debug("Issued EncryptionToken Id : " + tokenId);
                }
            } else if(encryptionToken instanceof SecureConversationToken) {
                tokenId = rmd.getSecConvTokenId();
                if (log.isDebugEnabled()) {
                    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(doc);
                
                if(attached && tok.getAttachedReference() != null) {
                    
                    dkEncr.setStrElem((Element) doc.importNode((Element) tok.getAttachedReference(), true));
                } else if(tok.getUnattachedReference() != null) {
                    dkEncr.setStrElem((Element) doc.importNode((Element) tok.getUnattachedReference(), true));
                } else {
                    dkEncr.setTokenIdentifier(tok.getId());
                }
                try {
                    dkEncr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
                    dkEncr.setDerivedKeyLength(algorithmSuite.getEncryptionDerivedKeyLength()/8);
                    dkEncr.prepare(tok.getSecret());
                    encrDKTokenElem = dkEncr.getdktElement();
                    RampartUtil.appendChildToSecHeader(rmd, encrDKTokenElem);
                    
                    refList = dkEncr.encryptForExternalRef(null, encrParts);
                    
                } catch (Exception e) {
                    throw new RampartException("errorInDKEncr");
                }
            } else {
                log.debug("NO derived keys, use the shared secret");
                encr = new WSSecEncrypt(doc);
                
                encr.setEncKeyId(tokenId);
                RampartUtil.setEncryptionUser(rmd, encr);

                encr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
                // SymmKey is already encrypted, no need to do it again
                encr.setEncryptSymmKey(false);
                if (!rmd.isInitiator() && tok instanceof EncryptedKeyToken) {
                    // TODO was encr.setUseKeyIdentifier(true); - verify
                    encr.setEncKeyIdDirectId(true);
                    encr.setCustomReferenceValue(((EncryptedKeyToken)tok).getSHA1());
                    encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
                }
                
                try {
                    SecretKey key = new SecretKeySpec(tok.getSecret(), rpd.getAlgorithmSuite().getEncryption());
                    encr.prepare(RampartUtil.getEncryptionCrypto(rpd.getRampartConfig(), rmd.getCustomClassLoader()), key);
                    //Encrypt, get hold of the ref list and add it
                    refList = encr.encryptForRef(null, encrParts, key);
                } catch (WSSecurityException e) {
                    throw new RampartException("errorInEncryption", e);
                }
            }
            
            this.mainRefListElement = RampartUtil.appendChildToSecHeader(rmd, refList);
            
            if(tlog.isDebugEnabled()){
            	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);
                
                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);
            }
		
            
            //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
                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 and encryption of UsernameToken
            if(rpd.isSignatureProtection() && this.mainSigId != null || 
                    encryptedTokensIdList.size() > 0 && rmd.isInitiator()) {
            	long t3 = 0, t4 = 0;
            	if(tlog.isDebugEnabled()){
            		t3 = System.currentTimeMillis();
            	}
                log.debug("Signature protection");
                List<WSEncryptionPart> secondEncrParts = new ArrayList<WSEncryptionPart>();
                
                //Now encrypt the signature using the above token
                if(rpd.isSignatureProtection()) {
                    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("errorInDKEncr");
                    }
                } else {
                    try {
                        //Encrypt, get hold of the ref list and add it
                        SecretKey key = new SecretKeySpec(tok.getSecret(), rpd.getAlgorithmSuite().getEncryption());
                        encr.prepare(RampartUtil.getEncryptionCrypto(rpd
                                .getRampartConfig(), rmd.getCustomClassLoader()), key);
                                       
                        secondRefList = encr.encryptForRef(null, encrParts, key);
                        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));
            	}
            }
           
        } else {
            throw new RampartException("encryptionTokenMissing");
        }
    }