private void doSignBeforeEncrypt()

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


    private void doSignBeforeEncrypt(RampartMessageData rmd) throws RampartException {
    	
    	long t0 = 0, t1 = 0, t2 = 0;
    	    	  	
        RampartPolicyData rpd = rmd.getPolicyData();
        Document doc = rmd.getDocument();
        
        if(tlog.isDebugEnabled()){
    		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;
        
        List<byte[]> signatureValues = new ArrayList<byte[]>();
        
        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)
                || sigToken instanceof SecureConversationToken) {
            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;
        
        List<WSEncryptionPart> 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);
            
            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 ) {
            //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
            List<byte[]> endSigVals = this.doEndorsedSignatures(rmd, endSuppTokMap);

            for (byte[] endSigVal : endSigVals) {
                signatureValues.add(endSigVal);
            }
             
            //Adding the signed endorsed encrypted tokens to signed endorsed supporting tokens
            sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
            //Do signed endorsing signatures
            List<byte[]> sigEndSigVals = this.doEndorsedSignatures(rmd, sgndEndSuppTokMap);
            for (byte[] sigEndSigVal : sigEndSigVals) {
                signatureValues.add(sigEndSigVal);
            }
        }
        
        if(tlog.isDebugEnabled()){
    		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);
            }
            
        }
    
        List<WSEncryptionPart> 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 (String anEncryptedTokensIdList : encryptedTokensIdList) {
                encrParts.add(new WSEncryptionPart(anEncryptedTokensIdList, "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(doc);
                    
                    //Check whether it is security policy 1.2 and use the secure conversation accordingly
                    if (SPConstants.SP_V12 == encrToken.getVersion()) {
                        dkEncr.setWscVersion(ConversationConstants.VERSION_05_12);
                    }

                    if(encrTokElem != null && encrTok.getAttachedReference() != null) {
                        dkEncr.setStrElem((Element) doc.importNode((Element) encrTok.getAttachedReference(), true));
                    } else if(encrTok.getUnattachedReference() != null) {
                        dkEncr.setStrElem((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.setStrElem(tokenRef.getElement());
                        tokenRef.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);  // TODO check this
                    	
                    } else {
                        dkEncr.setTokenIdentifier(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(encrTok.getSecret());
                    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 (Exception e) {
                    throw new RampartException("errorInDKEncr");
                }                
            } else {
                try {
                    
                    WSSecEncrypt encr = new WSSecEncrypt(doc);
                    
                    //Hack to handle reference id issues
                    //TODO Need a better fix
                    if(encrTokId.startsWith("#")) {
                        encrTokId = encrTokId.substring(1);
                    }
                    encr.setEncKeyId(encrTokId);
                    
                    RampartUtil.setEncryptionUser(rmd, encr);
                    encr.setEncryptSymmKey(false);
                    encr.setSymmetricEncAlgorithm(rpd.getAlgorithmSuite().getEncryption());
                    // Use key identifier in the KeyInfo in server side
                    if (!rmd.isInitiator()) {
                        if(encrTok instanceof EncryptedKeyToken) {
                            // TODO was encr.setUseKeyIdentifier(true); verify
                            encr.setEncKeyIdDirectId(true);
                            encr.setCustomReferenceValue(((EncryptedKeyToken)encrTok).getSHA1());
                            encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
                        } 
                    }
 
                    SecretKey key = new SecretKeySpec(encrTok.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);                                        
    
                    if(encrTokElem != null) {
                        RampartUtil.insertSiblingAfter(rmd,
                                                    encrTokElem,
                                                    refList);
                    } else {
                        RampartUtil.insertSiblingBeforeOrPrepend(rmd,
                                this.getInsertionLocation(),
                                refList);
                    }
                    
                } catch (WSSecurityException e) {
                    throw new RampartException("errorInEncryption", e);
                }    
            }
        }
        
        if(tlog.isDebugEnabled()){
    		t2 = System.currentTimeMillis();
    		tlog.debug("Signature took :" + (t1 - t0)
    				+", Encryption took :" + (t2 - t1) );
    	}
        

    }