Home » rampart-dist-1.4-src » org.apache » rampart » builder » [javadoc | source]

    1   /*
    2    * Copyright 2004,2005 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   
   17   package org.apache.rampart.builder;
   18   
   19   import org.apache.axiom.om.OMElement;
   20   import org.apache.axis2.context.MessageContext;
   21   import org.apache.commons.logging.Log;
   22   import org.apache.commons.logging.LogFactory;
   23   import org.apache.rahas.EncryptedKeyToken;
   24   import org.apache.rahas.RahasConstants;
   25   import org.apache.rahas.TrustException;
   26   import org.apache.rampart.RampartConstants;
   27   import org.apache.rampart.RampartException;
   28   import org.apache.rampart.RampartMessageData;
   29   import org.apache.rampart.policy.RampartPolicyData;
   30   import org.apache.rampart.util.RampartUtil;
   31   import org.apache.ws.secpolicy.SPConstants;
   32   import org.apache.ws.secpolicy.model.AlgorithmSuite;
   33   import org.apache.ws.secpolicy.model.IssuedToken;
   34   import org.apache.ws.secpolicy.model.SecureConversationToken;
   35   import org.apache.ws.secpolicy.model.SupportingToken;
   36   import org.apache.ws.secpolicy.model.Token;
   37   import org.apache.ws.secpolicy.model.X509Token;
   38   import org.apache.ws.security.WSConstants;
   39   import org.apache.ws.security.WSEncryptionPart;
   40   import org.apache.ws.security.WSSecurityEngineResult;
   41   import org.apache.ws.security.WSSecurityException;
   42   import org.apache.ws.security.conversation.ConversationException;
   43   import org.apache.ws.security.handler.WSHandlerConstants;
   44   import org.apache.ws.security.handler.WSHandlerResult;
   45   import org.apache.ws.security.message.WSSecDKEncrypt;
   46   import org.apache.ws.security.message.WSSecEncrypt;
   47   import org.apache.ws.security.message.WSSecEncryptedKey;
   48   import org.apache.ws.security.message.token.SecurityTokenReference;
   49   import org.apache.ws.security.util.Base64;
   50   import org.w3c.dom.Document;
   51   import org.w3c.dom.Element;
   52   
   53   import java.security.MessageDigest;
   54   import java.security.NoSuchAlgorithmException;
   55   import java.util.Date;
   56   import java.util.HashMap;
   57   import java.util.Iterator;
   58   import java.util.Vector;
   59   
   60   
   61   public class SymmetricBindingBuilder extends BindingBuilder {
   62   
   63       private static Log log = LogFactory.getLog(SymmetricBindingBuilder.class);
   64       private static Log tlog = LogFactory.getLog(RampartConstants.TIME_LOG);	
   65       private boolean dotDebug = false;
   66       
   67       
   68       public SymmetricBindingBuilder(){
   69       	dotDebug = tlog.isDebugEnabled();
   70       }
   71       
   72       public void build(RampartMessageData rmd) throws RampartException {
   73           
   74           log.debug("SymmetricBindingBuilder build invoked");
   75           
   76           RampartPolicyData rpd = rmd.getPolicyData();
   77           if(rpd.isIncludeTimestamp()) {
   78               this.addTimestamp(rmd);
   79           }
   80           
   81           if(rmd.isInitiator()) {
   82               //Setup required tokens
   83               initializeTokens(rmd);
   84           }
   85           
   86               
   87           if(SPConstants.ENCRYPT_BEFORE_SIGNING.equals(rpd.getProtectionOrder())) {
   88               this.doEncryptBeforeSig(rmd);
   89           } else {
   90               this.doSignBeforeEncrypt(rmd);
   91           }
   92   
   93       
   94           log.debug("SymmetricBindingBuilder build invoked : DONE");
   95           
   96       }
   97       
   98       private void doEncryptBeforeSig(RampartMessageData rmd) throws RampartException {
   99           
  100       	long t0 = 0, t1 = 0, t2 = 0;
  101       	       	
  102           RampartPolicyData rpd = rmd.getPolicyData();
  103           
  104           Vector signatureValues = new Vector();
  105           
  106       	if(dotDebug){
  107       		t0 = System.currentTimeMillis();
  108       	}
  109           
  110           Token encryptionToken = rpd.getEncryptionToken();
  111           Vector encrParts = RampartUtil.getEncryptedParts(rmd);
  112   
  113           Vector sigParts = RampartUtil.getSignedParts(rmd);
  114           
  115           if(encryptionToken == null && encrParts.size() > 0) {
  116               throw new RampartException("encryptionTokenMissing");
  117           }
  118           
  119           if(encryptionToken != null && encrParts.size() > 0) {
  120               //The encryption token can be an IssuedToken or a 
  121                //SecureConversationToken
  122               String tokenId = null;
  123               org.apache.rahas.Token tok = null;
  124               
  125               if(encryptionToken instanceof IssuedToken) {
  126                   tokenId = rmd.getIssuedEncryptionTokenId();
  127                   log.debug("Issued EncryptionToken Id : " + tokenId);
  128               } else if(encryptionToken instanceof SecureConversationToken) {
  129                   tokenId = rmd.getSecConvTokenId();
  130                   log.debug("SCT Id : " + tokenId);
  131               } else if (encryptionToken instanceof X509Token) {
  132               	if (rmd.isInitiator()) {
  133               		tokenId = setupEncryptedKey(rmd, encryptionToken);
  134               	} else {
  135               		tokenId = getEncryptedKey(rmd);
  136               	}
  137               } //TODO SAMLToken
  138               
  139               if(tokenId == null || tokenId.length() == 0) {
  140                   throw new RampartException("noSecurityToken");
  141               }
  142               
  143               //Hack to handle reference id issues
  144               //TODO Need a better fix
  145               if(tokenId.startsWith("#")) {
  146                   tokenId = tokenId.substring(1);
  147               }
  148               
  149               /*
  150                * Get hold of the token from the token storage
  151                */
  152               tok = this.getToken(rmd, tokenId);
  153   
  154               /*
  155                * Attach the token into the message based on token inclusion 
  156                * values
  157                */
  158               boolean attached = false;
  159               Element encrTokenElement = null;
  160               Element refList = null;
  161               WSSecDKEncrypt dkEncr = null;
  162               WSSecEncrypt encr = null;
  163               Element encrDKTokenElem = null;
  164               
  165               if(SPConstants.INCLUDE_TOEKN_ALWAYS == encryptionToken.getInclusion() ||
  166                       SPConstants.INCLUDE_TOKEN_ONCE == encryptionToken.getInclusion() ||
  167                       (rmd.isInitiator() && SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == encryptionToken.getInclusion())) {
  168                   encrTokenElement = RampartUtil.appendChildToSecHeader(rmd, tok.getToken());
  169                   attached = true;
  170               } else if(encryptionToken instanceof X509Token && rmd.isInitiator()) {
  171               	encrTokenElement = RampartUtil.appendChildToSecHeader(rmd, tok.getToken());
  172               }
  173               
  174               Document doc = rmd.getDocument();
  175   
  176               AlgorithmSuite algorithmSuite = rpd.getAlgorithmSuite();
  177               if(encryptionToken.isDerivedKeys()) {
  178                   log.debug("Use drived keys");
  179                   
  180                   dkEncr = new WSSecDKEncrypt();
  181                   
  182                   if(attached && tok.getAttachedReference() != null) {
  183                       
  184                       dkEncr.setExternalKey(tok.getSecret(), (Element) doc
  185                               .importNode((Element) tok.getAttachedReference(),
  186                                       true));
  187                       
  188                   } else if(tok.getUnattachedReference() != null) {
  189                       dkEncr.setExternalKey(tok.getSecret(), (Element) doc
  190                               .importNode((Element) tok.getUnattachedReference(),
  191                                       true));
  192                   } else {
  193                       dkEncr.setExternalKey(tok.getSecret(), tok.getId());
  194                   }
  195                   try {
  196                       dkEncr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
  197                       dkEncr.setDerivedKeyLength(algorithmSuite.getEncryptionDerivedKeyLength()/8);
  198                       dkEncr.prepare(doc);
  199                       encrDKTokenElem = dkEncr.getdktElement();
  200                       RampartUtil.appendChildToSecHeader(rmd, encrDKTokenElem);
  201                       
  202                       refList = dkEncr.encryptForExternalRef(null, encrParts);
  203                       
  204                   } catch (WSSecurityException e) {
  205                       throw new RampartException("errorInDKEncr");
  206                   } catch (ConversationException e) {
  207                       throw new RampartException("errorInDKEncr");
  208                   }
  209               } else {
  210                   log.debug("NO derived keys, use the shared secret");
  211                   encr = new WSSecEncrypt();
  212                   
  213                   encr.setWsConfig(rmd.getConfig());
  214                   encr.setEncKeyId(tokenId);
  215                   RampartUtil.setEncryptionUser(rmd, encr);
  216                   encr.setEphemeralKey(tok.getSecret());
  217                   encr.setDocument(doc);
  218                   encr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
  219                   // SymmKey is already encrypted, no need to do it again
  220                   encr.setEncryptSymmKey(false);
  221                   if (!rmd.isInitiator() && tok instanceof EncryptedKeyToken) {
  222                       encr.setUseKeyIdentifier(true);
  223                       encr.setCustomReferenceValue(((EncryptedKeyToken)tok).getSHA1());
  224                       encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
  225                   }
  226                   
  227                   try {
  228                   	
  229                       encr.prepare(doc, RampartUtil.getEncryptionCrypto(rpd
  230                               .getRampartConfig(), rmd.getCustomClassLoader()));
  231                       //Encrypt, get hold of the ref list and add it
  232                       refList = encr.encryptForExternalRef(null, encrParts);
  233                   } catch (WSSecurityException e) {
  234                       throw new RampartException("errorInEncryption", e);
  235                   }
  236               }
  237               
  238               this.mainRefListElement = RampartUtil.appendChildToSecHeader(rmd, refList);
  239               
  240               if(dotDebug){
  241               	t1 = System.currentTimeMillis();
  242               }
  243               
  244               // Sometimes encryption token is not included in the the message
  245               if (encrTokenElement != null) {
  246                   this.setInsertionLocation(encrTokenElement);
  247               } else if (timestampElement != null) {
  248               	this.setInsertionLocation(timestampElement);
  249               } 
  250               
  251               RampartUtil.handleEncryptedSignedHeaders(encrParts, sigParts, doc);
  252               
  253               HashMap sigSuppTokMap = null;
  254               HashMap endSuppTokMap = null;
  255               HashMap sgndEndSuppTokMap = null;
  256               HashMap sgndEncSuppTokMap = null;
  257               HashMap endEncSuppTokMap = null;
  258               HashMap sgndEndEncSuppTokMap = null;
  259               
  260               
  261               if(this.timestampElement != null){
  262               	sigParts.add(new WSEncryptionPart(RampartUtil
  263                       .addWsuIdToElement((OMElement) this.timestampElement)));
  264               }
  265               
  266               if(rmd.isInitiator()) {
  267               
  268                   // Now add the supporting tokens
  269                   SupportingToken sgndSuppTokens = rpd.getSignedSupportingTokens();
  270                   sigSuppTokMap = this.handleSupportingTokens(rmd, sgndSuppTokens);           
  271                   
  272                   SupportingToken endSuppTokens = rpd.getEndorsingSupportingTokens();
  273                   endSuppTokMap = this.handleSupportingTokens(rmd, endSuppTokens);
  274                   
  275                   SupportingToken sgndEndSuppTokens = rpd.getSignedEndorsingSupportingTokens();           
  276                   sgndEndSuppTokMap = this.handleSupportingTokens(rmd, sgndEndSuppTokens);
  277                   
  278                   SupportingToken sgndEncryptedSuppTokens = rpd.getSignedEncryptedSupportingTokens();
  279                   sgndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEncryptedSuppTokens);
  280                   
  281                   SupportingToken endorsingEncryptedSuppTokens = rpd.getEndorsingEncryptedSupportingTokens();
  282                   endEncSuppTokMap = this.handleSupportingTokens(rmd, endorsingEncryptedSuppTokens);
  283                   
  284                   SupportingToken sgndEndEncSuppTokens = rpd.getSignedEndorsingEncryptedSupportingTokens();           
  285                   sgndEndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEndEncSuppTokens);
  286                   
  287                   SupportingToken supportingToks = rpd.getSupportingTokens();
  288                   this.handleSupportingTokens(rmd, supportingToks);
  289                   
  290                   SupportingToken encryptedSupportingToks = rpd.getEncryptedSupportingTokens();
  291                   this.handleSupportingTokens(rmd, encryptedSupportingToks);
  292           
  293                   //Setup signature parts
  294                   sigParts = addSignatureParts(sigSuppTokMap, sigParts);
  295                   sigParts = addSignatureParts(sgndEncSuppTokMap, sigParts);
  296                   sigParts = addSignatureParts(sgndEndSuppTokMap, sigParts);
  297                   sigParts = addSignatureParts(sgndEndEncSuppTokMap, sigParts);
  298                   
  299               } else {
  300                   addSignatureConfirmation(rmd, sigParts);
  301               }
  302   		
  303               
  304               //Sign the message
  305               //We should use the same key in the case of EncryptBeforeSig
  306               if ( sigParts.size() > 0) {
  307                   signatureValues.add(this.doSymmSignature(rmd, encryptionToken, tok, sigParts));
  308                   this.mainSigId = RampartUtil.addWsuIdToElement((OMElement)this.getInsertionLocation());         
  309               }
  310               
  311               if(rmd.isInitiator()) {
  312                   
  313                   endSuppTokMap.putAll(endEncSuppTokMap);
  314                   //Do endorsed signatures
  315                   Vector endSigVals = this.doEndorsedSignatures(rmd, endSuppTokMap);
  316                   for (Iterator iter = endSigVals.iterator(); iter.hasNext();) {
  317                       signatureValues.add(iter.next());
  318                   }
  319                   
  320                   sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
  321                   //Do signed endorsing signatures
  322                   Vector sigEndSigVals = this.doEndorsedSignatures(rmd, sgndEndSuppTokMap);
  323                   for (Iterator iter = sigEndSigVals.iterator(); iter.hasNext();) {
  324                       signatureValues.add(iter.next());
  325                   }
  326               }
  327               
  328               if(dotDebug){
  329               	t2 = System.currentTimeMillis();
  330               	tlog.debug("Encryption took :" + (t1 - t0)
  331               				+", Signature tool :" + (t2 - t1) );
  332               }
  333               
  334               //Check for signature protection and encryption of UsernameToken
  335               if(rpd.isSignatureProtection() && this.mainSigId != null || 
  336                       encryptedTokensIdList.size() > 0 && rmd.isInitiator()) {
  337               	long t3 = 0, t4 = 0;
  338               	if(dotDebug){
  339               		t3 = System.currentTimeMillis();
  340               	}
  341               	log.debug("Signature protection");
  342                   Vector secondEncrParts = new Vector();
  343                   
  344                   //Now encrypt the signature using the above token
  345                   if(rpd.isSignatureProtection()) {
  346                       secondEncrParts.add(new WSEncryptionPart(this.mainSigId, "Element"));
  347                   }
  348                   
  349                   if(rmd.isInitiator()) {
  350                       for (int i = 0 ; i < encryptedTokensIdList.size(); i++) {
  351                           secondEncrParts.add(new WSEncryptionPart((String)encryptedTokensIdList.get(i),"Element"));
  352                       }
  353                   }
  354                   
  355                   Element secondRefList = null;
  356                   
  357                   if(encryptionToken.isDerivedKeys()) {
  358                       try {
  359                           secondRefList = dkEncr.encryptForExternalRef(null, 
  360                                   secondEncrParts);
  361                           RampartUtil.insertSiblingAfter(
  362                                   rmd, 
  363                                   encrDKTokenElem, 
  364                                   secondRefList);
  365                       } catch (WSSecurityException e) {
  366                           throw new RampartException("errorInDKEncr");
  367                       }
  368                   } else {
  369                       try {
  370                           //Encrypt, get hold of the ref list and add it
  371                           secondRefList = encr.encryptForExternalRef(null,
  372                                   encrParts);
  373                           RampartUtil.insertSiblingAfter(
  374                                   rmd, 
  375                                   encrTokenElement,
  376                                   secondRefList);
  377                       } catch (WSSecurityException e) {
  378                           throw new RampartException("errorInEncryption", e);
  379                       }    
  380                   }
  381                   if(dotDebug){
  382               		t4 = System.currentTimeMillis();
  383               		tlog.debug("Signature protection took :" + (t4 - t3));
  384               	}
  385               }
  386              
  387           } else {
  388               throw new RampartException("encryptionTokenMissing");
  389           }
  390       }
  391   
  392   
  393       private void doSignBeforeEncrypt(RampartMessageData rmd) throws RampartException {
  394       	
  395       	long t0 = 0, t1 = 0, t2 = 0;
  396       	    	  	
  397           RampartPolicyData rpd = rmd.getPolicyData();
  398           Document doc = rmd.getDocument();
  399           
  400           if(dotDebug){
  401       		t0 = System.currentTimeMillis();
  402       	}
  403           Token sigToken = rpd.getSignatureToken();
  404           
  405           String encrTokId = null;
  406           String sigTokId = null;
  407           
  408           org.apache.rahas.Token encrTok = null;
  409           org.apache.rahas.Token sigTok = null;
  410           
  411           Element sigTokElem = null;
  412           
  413           Vector signatureValues = new Vector();
  414           
  415           if(sigToken != null) {
  416               if(sigToken instanceof SecureConversationToken) {
  417                   sigTokId = rmd.getSecConvTokenId();
  418               } else if(sigToken instanceof IssuedToken) {
  419                   sigTokId = rmd.getIssuedSignatureTokenId();
  420               } else if(sigToken instanceof X509Token) {
  421               	if (rmd.isInitiator()) {
  422               		sigTokId = setupEncryptedKey(rmd, sigToken);
  423               	} else {
  424               		sigTokId = getEncryptedKey(rmd);
  425               	}
  426               }
  427           } else {
  428               throw new RampartException("signatureTokenMissing");
  429           }
  430           
  431           if(sigTokId == null || sigTokId.length() == 0) {
  432               throw new RampartException("noSecurityToken");
  433           }
  434           
  435           sigTok = this.getToken(rmd, sigTokId);
  436   
  437           if(SPConstants.INCLUDE_TOEKN_ALWAYS == sigToken.getInclusion() ||
  438                   SPConstants.INCLUDE_TOKEN_ONCE == sigToken.getInclusion() ||
  439                   (rmd.isInitiator() && 
  440                           SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == sigToken.getInclusion())) {
  441               sigTokElem = RampartUtil.appendChildToSecHeader(rmd, 
  442                                                               sigTok.getToken());
  443               this.setInsertionLocation(sigTokElem);
  444           } else if ( rmd.isInitiator() && sigToken instanceof X509Token) {
  445           	sigTokElem = RampartUtil.appendChildToSecHeader(rmd, sigTok.getToken());
  446               
  447               //Set the insertion location
  448               this.setInsertionLocation(sigTokElem);
  449           }
  450           
  451   
  452           HashMap sigSuppTokMap = null;
  453           HashMap endSuppTokMap = null;
  454           HashMap sgndEndSuppTokMap = null;
  455           HashMap sgndEncSuppTokMap = null;
  456           HashMap endEncSuppTokMap = null;
  457           HashMap sgndEndEncSuppTokMap = null;
  458           
  459           Vector sigParts = RampartUtil.getSignedParts(rmd);
  460           
  461           if(this.timestampElement != null){
  462           	sigParts.add(new WSEncryptionPart(RampartUtil
  463                   .addWsuIdToElement((OMElement) this.timestampElement)));
  464           }
  465           
  466           if(rmd.isInitiator()) {
  467       //      Now add the supporting tokens
  468               SupportingToken sgndSuppTokens = rpd.getSignedSupportingTokens();
  469               sigSuppTokMap = this.handleSupportingTokens(rmd, sgndSuppTokens);           
  470               
  471               SupportingToken endSuppTokens = rpd.getEndorsingSupportingTokens();
  472               endSuppTokMap = this.handleSupportingTokens(rmd, endSuppTokens);
  473               
  474               SupportingToken sgndEndSuppTokens = rpd.getSignedEndorsingSupportingTokens();           
  475               sgndEndSuppTokMap = this.handleSupportingTokens(rmd, sgndEndSuppTokens);
  476               
  477               SupportingToken sgndEncryptedSuppTokens = rpd.getSignedEncryptedSupportingTokens();
  478               sgndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEncryptedSuppTokens);
  479               
  480               SupportingToken endorsingEncryptedSuppTokens = rpd.getEndorsingEncryptedSupportingTokens();
  481               endEncSuppTokMap = this.handleSupportingTokens(rmd, endorsingEncryptedSuppTokens);
  482               
  483               SupportingToken sgndEndEncSuppTokens = rpd.getSignedEndorsingEncryptedSupportingTokens();           
  484               sgndEndEncSuppTokMap = this.handleSupportingTokens(rmd, sgndEndEncSuppTokens);
  485               
  486               SupportingToken supportingToks = rpd.getSupportingTokens();
  487               this.handleSupportingTokens(rmd, supportingToks);
  488               
  489               SupportingToken encryptedSupportingToks = rpd.getEncryptedSupportingTokens();
  490               this.handleSupportingTokens(rmd, encryptedSupportingToks);
  491       
  492               //Setup signature parts
  493               sigParts = addSignatureParts(sigSuppTokMap, sigParts);
  494               sigParts = addSignatureParts(sgndEncSuppTokMap, sigParts);
  495               sigParts = addSignatureParts(sgndEndSuppTokMap, sigParts);
  496               sigParts = addSignatureParts(sgndEndEncSuppTokMap, sigParts);
  497               
  498           } else {
  499               addSignatureConfirmation(rmd, sigParts);
  500           }
  501           
  502           if (sigParts.size() > 0 ) {
  503               //Sign the message
  504               signatureValues.add(this.doSymmSignature(rmd, sigToken, sigTok, sigParts));
  505       
  506               this.mainSigId = RampartUtil.addWsuIdToElement((OMElement)this.getInsertionLocation());
  507   
  508           }
  509           
  510           if(rmd.isInitiator()) {
  511               // Adding the endorsing encrypted supporting tokens to endorsing supporting tokens
  512               endSuppTokMap.putAll(endEncSuppTokMap);
  513               //Do endorsed signatures
  514               Vector endSigVals = this.doEndorsedSignatures(rmd, endSuppTokMap);
  515               
  516               for (Iterator iter = endSigVals.iterator(); iter.hasNext();) {
  517                   signatureValues.add(iter.next());
  518               }
  519                
  520               //Adding the signed endorsed encrypted tokens to signed endorsed supporting tokens
  521               sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
  522               //Do signed endorsing signatures
  523               Vector sigEndSigVals = this.doEndorsedSignatures(rmd, sgndEndSuppTokMap);
  524               for (Iterator iter = sigEndSigVals.iterator(); iter.hasNext();) {
  525                   signatureValues.add(iter.next());
  526               }
  527           }
  528           
  529           if(dotDebug){
  530       		t1 = System.currentTimeMillis();
  531       	}
  532           
  533           //Encryption
  534           Token encrToken = rpd.getEncryptionToken();
  535           Element encrTokElem = null;
  536           if(sigToken.equals(encrToken)) {
  537               //Use the same token
  538               encrTokId = sigTokId;
  539               encrTok = sigTok;
  540               encrTokElem = sigTokElem;
  541           } else {
  542               encrTokId = rmd.getIssuedEncryptionTokenId();
  543               encrTok = this.getToken(rmd, encrTokId);
  544               
  545               if(SPConstants.INCLUDE_TOEKN_ALWAYS == encrToken.getInclusion() ||
  546                       SPConstants.INCLUDE_TOKEN_ONCE == encrToken.getInclusion() ||
  547                       (rmd.isInitiator() && SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == encrToken.getInclusion())) {
  548                   encrTokElem = (Element)encrTok.getToken();
  549                   
  550                   //Add the encrToken element before the sigToken element
  551                   RampartUtil.insertSiblingBefore(rmd, sigTokElem, encrTokElem);
  552               }
  553               
  554           }
  555       
  556           Vector encrParts = RampartUtil.getEncryptedParts(rmd);
  557           
  558           //Check for signature protection
  559           if(rpd.isSignatureProtection() && this.mainSigId != null) {
  560               //Now encrypt the signature using the above token
  561               encrParts.add(new WSEncryptionPart(this.mainSigId, "Element"));
  562           }
  563           
  564           if(rmd.isInitiator()) {
  565               for (int i = 0 ; i < encryptedTokensIdList.size(); i++) {
  566                   encrParts.add(new WSEncryptionPart((String)encryptedTokensIdList.get(i),"Element"));
  567               }
  568           }
  569           
  570           Element refList = null;
  571           if(encrParts.size() > 0) {
  572               //The sec conv token can be used without derived keys
  573               if(encrToken.isDerivedKeys()) {
  574                   
  575                   try {
  576                       WSSecDKEncrypt dkEncr = new WSSecDKEncrypt();
  577                       
  578                       if(encrTokElem != null && encrTok.getAttachedReference() != null) {
  579                           
  580                           dkEncr.setExternalKey(encrTok.getSecret(), (Element) doc
  581                                   .importNode((Element) encrTok.getAttachedReference(),
  582                                           true));
  583                       } else if(encrTok.getUnattachedReference() != null) {
  584                           dkEncr.setExternalKey(encrTok.getSecret(), (Element) doc
  585                                   .importNode((Element) encrTok.getUnattachedReference(),
  586                                           true));
  587                       } else if (!rmd.isInitiator() && encrToken.isDerivedKeys()) { 
  588                       	
  589                       	// If the Encrypted key used to create the derived key is not
  590                       	// attached use key identifier as defined in WSS1.1 section
  591                       	// 7.7 Encrypted Key reference
  592                       	SecurityTokenReference tokenRef = new SecurityTokenReference(doc);
  593                       	if(encrTok instanceof EncryptedKeyToken) {
  594                       	    tokenRef.setKeyIdentifierEncKeySHA1(((EncryptedKeyToken)encrTok).getSHA1());
  595                       	}
  596                       	dkEncr.setExternalKey(encrTok.getSecret(), tokenRef.getElement());
  597                       	
  598                       } else {
  599                           dkEncr.setExternalKey(encrTok.getSecret(), encrTok.getId());
  600                       }
  601                       
  602                       if(encrTok instanceof EncryptedKeyToken) {
  603                           dkEncr.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
  604                                   + WSConstants.ENC_KEY_VALUE_TYPE);
  605                       }
  606                       
  607                       dkEncr.setSymmetricEncAlgorithm(rpd.getAlgorithmSuite().getEncryption());
  608                       dkEncr.setDerivedKeyLength(rpd.getAlgorithmSuite().getEncryptionDerivedKeyLength()/8);
  609                       dkEncr.prepare(doc);
  610                       Element encrDKTokenElem = null;
  611                       encrDKTokenElem = dkEncr.getdktElement();
  612                       if(encrTokElem != null) {
  613                           RampartUtil.insertSiblingAfter(rmd, encrTokElem, encrDKTokenElem);
  614                       } else if (timestampElement != null){
  615                           RampartUtil.insertSiblingAfter(rmd, this.timestampElement, encrDKTokenElem);
  616                       } else {
  617                           RampartUtil.insertSiblingBefore(rmd, this.getInsertionLocation(), encrDKTokenElem);
  618                       }
  619                       
  620                       refList = dkEncr.encryptForExternalRef(null, encrParts);
  621                       
  622                       RampartUtil.insertSiblingAfter(rmd, 
  623                                                       encrDKTokenElem, 
  624                                                       refList);
  625       
  626                   } catch (WSSecurityException e) {
  627                       throw new RampartException("errorInDKEncr");
  628                   } catch (ConversationException e) {
  629                       throw new RampartException("errorInDKEncr");
  630                   }                
  631               } else {
  632                   try {
  633                       
  634                       WSSecEncrypt encr = new WSSecEncrypt();
  635                       
  636                       encr.setWsConfig(rmd.getConfig());
  637                       //Hack to handle reference id issues
  638                       //TODO Need a better fix
  639                       if(encrTokId.startsWith("#")) {
  640                           encrTokId = encrTokId.substring(1);
  641                       }
  642                       encr.setEncKeyId(encrTokId);
  643                       
  644                       encr.setEphemeralKey(encrTok.getSecret());
  645                       RampartUtil.setEncryptionUser(rmd, encr);
  646                       encr.setDocument(doc);
  647                       encr.setEncryptSymmKey(false);
  648                       encr.setSymmetricEncAlgorithm(rpd.getAlgorithmSuite().getEncryption());
  649                       // Use key identifier in the KeyInfo in server side
  650                       if (!rmd.isInitiator()) {
  651                           if(encrTok instanceof EncryptedKeyToken) {
  652                               encr.setUseKeyIdentifier(true);
  653                               encr.setCustomReferenceValue(((EncryptedKeyToken)encrTok).getSHA1());
  654                               encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
  655                           } 
  656                       }
  657                       encr.prepare(doc, RampartUtil.getEncryptionCrypto(rpd
  658                               .getRampartConfig(), rmd.getCustomClassLoader()));
  659                                          
  660                       //Encrypt, get hold of the ref list and add it
  661                       refList = encr.encryptForExternalRef(null, encrParts);                                        
  662       
  663                       if(encrTokElem != null) {
  664                           RampartUtil.insertSiblingAfter(rmd,
  665                                                       encrTokElem,
  666                                                       refList);
  667                       } else {
  668                           RampartUtil.insertSiblingBeforeOrPrepend(rmd,
  669                                   this.getInsertionLocation(),
  670                                   refList);
  671                       }
  672                       
  673                   } catch (WSSecurityException e) {
  674                       throw new RampartException("errorInEncryption", e);
  675                   }    
  676               }
  677           }
  678           
  679           if(dotDebug){
  680       		t2 = System.currentTimeMillis();
  681       		tlog.debug("Signature took :" + (t1 - t0)
  682       				+", Encryption took :" + (t2 - t1) );
  683       	}
  684           
  685   
  686       }
  687   
  688       /**
  689        * @param rmd
  690        * @param sigToken
  691        * @return 
  692        * @throws RampartException
  693        */
  694       private String setupEncryptedKey(RampartMessageData rmd, Token sigToken) 
  695       throws RampartException {
  696           try {
  697               WSSecEncryptedKey encrKey = this.getEncryptedKeyBuilder(rmd, 
  698                                                                   sigToken);
  699               String id = encrKey.getId();
  700               byte[] secret = encrKey.getEphemeralKey();
  701               //Create a rahas token from this info and store it so we can use
  702               //it in the next steps
  703       
  704               Date created = new Date();
  705               Date expires = new Date();
  706               //TODO make this lifetime configurable ???
  707               expires.setTime(System.currentTimeMillis() + 300000);
  708               org.apache.rahas.EncryptedKeyToken tempTok = new org.apache.rahas.EncryptedKeyToken(
  709                               id, 
  710                               (OMElement) encrKey.getEncryptedKeyElement(),
  711                               created, 
  712                               expires);
  713               
  714               
  715               tempTok.setSecret(secret);
  716               
  717               // Set the SHA1 value of the encrypted key, this is used when the encrypted
  718               // key is referenced via a key identifier of type EncryptedKeySHA1
  719               tempTok.setSHA1(getSHA1(encrKey.getEncryptedEphemeralKey()));
  720               
  721               rmd.getTokenStorage().add(tempTok);
  722               
  723               String bstTokenId = encrKey.getBSTTokenId();
  724               //If direct ref is used to refer to the cert
  725               //then add the cert to the sec header now
  726               if(bstTokenId != null && bstTokenId.length() > 0) {
  727                   RampartUtil.appendChildToSecHeader(rmd, 
  728                           encrKey.getBinarySecurityTokenElement());
  729               }
  730               
  731               return id;
  732               
  733           } catch (TrustException e) {
  734               throw new RampartException("errorInAddingTokenIntoStore");
  735           }
  736       }
  737       
  738       private String getSHA1(byte[] input) throws RampartException{
  739           
  740       	MessageDigest sha = null;
  741           try {
  742               sha = MessageDigest.getInstance("SHA-1");
  743           } catch (NoSuchAlgorithmException e1) {
  744               throw new RampartException("noSHA1availabe", e1);
  745           }
  746           sha.reset();
  747           sha.update(input);
  748           byte[] data = sha.digest();
  749           
  750           return Base64.encode(data);
  751       }
  752       
  753       private String getEncryptedKey(RampartMessageData rmd ) throws RampartException {
  754       	
  755       	Vector results = (Vector)rmd.getMsgContext().getProperty(WSHandlerConstants.RECV_RESULTS);
  756       	
  757           for (int i = 0; i < results.size(); i++) {
  758               WSHandlerResult rResult =
  759                       (WSHandlerResult) results.get(i);
  760   
  761               Vector wsSecEngineResults = rResult.getResults();
  762               
  763               for (int j = 0; j < wsSecEngineResults.size(); j++) {
  764                   WSSecurityEngineResult wser =
  765                           (WSSecurityEngineResult) wsSecEngineResults.get(j);
  766                   Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
  767                   if (actInt.intValue() == WSConstants.ENCR) {
  768                       
  769                   	if (wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID) != null &&
  770                   	        ((String)wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID)).length() != 0) {
  771                   		
  772                   		try {
  773                   			
  774   	                		String encryptedKeyID = (String)wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID);
  775   	                		
  776   	                        Date created = new Date();
  777   	                        Date expires = new Date();
  778   	                        expires.setTime(System.currentTimeMillis() + 300000);
  779   	                        EncryptedKeyToken tempTok = new EncryptedKeyToken(encryptedKeyID,created,expires);
  780   	                        tempTok.setSecret((byte[])wser.get(WSSecurityEngineResult.TAG_DECRYPTED_KEY));
  781   	                        tempTok.setSHA1(getSHA1((byte[])wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_EPHEMERAL_KEY)));
  782   	                        rmd.getTokenStorage().add(tempTok);
  783   	                        
  784   	                        return encryptedKeyID;
  785                           
  786                   		} catch (TrustException e) {
  787                   			throw new RampartException("errorInAddingTokenIntoStore");
  788                   		}
  789                   		
  790                   	}
  791                   }
  792               }
  793           }
  794       	return null;
  795       }
  796       
  797       
  798       /**
  799        * Setup the required tokens
  800        * @param rmd
  801        * @param rpd
  802        * @throws RampartException
  803        */
  804       private void initializeTokens(RampartMessageData rmd) throws RampartException {
  805           
  806           RampartPolicyData rpd = rmd.getPolicyData();
  807           
  808           MessageContext msgContext = rmd.getMsgContext();
  809           if(rpd.isSymmetricBinding() && !msgContext.isServerSide()) {
  810               log.debug("Processing symmetric binding: " +
  811                       "Setting up encryption token and signature token");
  812               //Setting up encryption token and signature token
  813               
  814               Token sigTok = rpd.getSignatureToken();
  815               Token encrTok = rpd.getEncryptionToken();
  816               if(sigTok instanceof IssuedToken) {
  817                   
  818                   log.debug("SignatureToken is an IssuedToken");
  819                   
  820                   if(rmd.getIssuedSignatureTokenId() == null) {
  821                       log.debug("No Issuedtoken found, requesting a new token");
  822                       
  823                       IssuedToken issuedToken = (IssuedToken)sigTok;
  824                       
  825                       String id = RampartUtil.getIssuedToken(rmd, 
  826                               issuedToken);
  827                       rmd.setIssuedSignatureTokenId(id);
  828                       
  829                   }
  830                   
  831               } else if(sigTok instanceof SecureConversationToken) {
  832                   
  833                   log.debug("SignatureToken is a SecureConversationToken");
  834                   
  835                   //TODO check for an existing token and use it 
  836                   
  837                   String secConvTokenId = rmd.getSecConvTokenId();
  838                   
  839                   //The RSTR has to be secured with the cancelled token
  840                   String action = msgContext.getOptions().getAction();
  841                   boolean cancelReqResp = action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RSTR_ACTION_CANCEL_SCT) || 
  842                                              action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RSTR_ACTION_CANCEL_SCT) ||
  843                                              action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RST_ACTION_CANCEL_SCT) || 
  844                                              action.equals(RahasConstants.WST_NS_05_02 + RahasConstants.RST_ACTION_CANCEL_SCT);
  845                   
  846                   //In the case of the cancel req or resp we should mark the token as cancelled
  847                   if(secConvTokenId != null && cancelReqResp) {
  848                       try {
  849                           rmd.getTokenStorage().getToken(secConvTokenId).setState(org.apache.rahas.Token.CANCELLED);
  850                           msgContext.setProperty(RampartMessageData.SCT_ID, secConvTokenId);
  851                           
  852                           //remove from the local map of contexts
  853                           String contextIdentifierKey = RampartUtil.getContextIdentifierKey(msgContext);
  854                           RampartUtil.getContextMap(msgContext).remove(contextIdentifierKey);
  855                       } catch (TrustException e) {
  856                           throw new RampartException("errorExtractingToken");
  857                       }
  858                   }
  859                   
  860                   if (secConvTokenId == null
  861                           || (secConvTokenId != null && 
  862                                   (!RampartUtil.isTokenValid(rmd, secConvTokenId) && !cancelReqResp))) {
  863                   
  864                       log.debug("No SecureConversationToken found, " +
  865                               "requesting a new token");
  866                       
  867                       SecureConversationToken secConvTok = 
  868                                           (SecureConversationToken) sigTok;
  869                       
  870                       try {
  871   
  872                           String id = RampartUtil.getSecConvToken(rmd, secConvTok);
  873                           rmd.setSecConvTokenId(id);
  874                           
  875                       } catch (TrustException e) {
  876                           throw new RampartException("errorInObtainingSct", e);
  877                       }
  878                   }
  879               }
  880               
  881               //If it was the ProtectionToken assertion then sigTok is the
  882               //same as encrTok
  883               if(sigTok.equals(encrTok) && sigTok instanceof IssuedToken) {
  884                   
  885                   log.debug("Symmetric binding uses a ProtectionToken, both" +
  886                           " SignatureToken and EncryptionToken are the same");
  887                   
  888                   rmd.setIssuedEncryptionTokenId(rmd.getIssuedEncryptionTokenId());
  889               } else {
  890                   //Now we'll have to obtain the encryption token as well :-)
  891                   //ASSUMPTION: SecureConversationToken is used as a 
  892                   //ProtectionToken therefore we only have to process a issued 
  893                   //token here
  894                   
  895                   log.debug("Obtaining the Encryption Token");
  896                   if(rmd.getIssuedEncryptionTokenId() != null) {
  897                       
  898                       log.debug("EncrytionToken not alredy set");
  899   
  900                       IssuedToken issuedToken = (IssuedToken)encrTok;
  901                           
  902                       String id = RampartUtil.getIssuedToken(rmd, 
  903                               issuedToken);
  904                       rmd.setIssuedEncryptionTokenId(id);
  905   
  906                   }
  907                   
  908               }
  909           }
  910           
  911           //TODO : Support processing IssuedToken and SecConvToken assertoins
  912           //in supporting tokens, right now we only support UsernameTokens and 
  913           //X.509 Tokens
  914       }
  915   
  916   
  917       
  918   }

Home » rampart-dist-1.4-src » org.apache » rampart » builder » [javadoc | source]