title: SOAP handlers using java keystore
body: <p>I am working on web services security, trying to encrypt and sign SOAP messages between the server and the client. I used BouncyCastle, WSS4j and SOAP handlers.</p>
  
  <p>To test my work at first I used the same keystore file on both the server and the client sides.I followed some tutorials on the net and it worked: the messages sent by one side were encrypted and signed and then decrypted successfully on the other side.</p>
  
  <p>But now that I generated different certificates for the server and the client, and imported the client's cert into the servers jks file and vice-versa, I can't seem to figure out how to finish the task. It is still crypting and signing as if it only had a jks file without an imported cert in it. below is the code:</p>
  
  <pre><code>Crypt_handler.java
  public class Crypt_handler implements SOAPHandler&lt;SOAPMessageContext&gt; , CallbackHandler{
  
  public Properties prop;
  
  public InputStream input= null;
  
  
  
  public Crypt_handler ()  {
  
  
      try {
          prop=new Properties();
          input = new FileInputStream("config.properties");
          if(input==null){
              System.out.println("Sorry, unable to find " );
          return;}
          prop.load(input);
  
      } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  
  
  }
  
  public boolean handleMessage(SOAPMessageContext messageContext) {
  
     try {
         // got the message from the context
         SOAPMessage msg = messageContext.getMessage();
  
        // is outgoing?
       Boolean isOutGoing = (Boolean) messageContext
                 .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
  
         if (isOutGoing) {
  
             // if it is outgoing code and sign
  
  
             crypt.EncryptUtil.EncryptSOAPEnvelope(msg, prop);
             crypt.EncryptUtil.SignSOAPEnvelope(msg, prop);
  
  
         } else {
  
             // if it is incooming decode and check signature.
             crypt.EncryptUtil.CheckSignatureAndDecode(msg, this , prop);
  
         }
  
     } catch (Exception ex) {
         ex.printStackTrace();
  
         throw new RuntimeException(ex.getMessage());
     }
  
     return true;
  
  
  
  
  }
  
    public boolean handleFault(SOAPMessageContext context) {
  
      System.out.println("Server : handleFault()......");
  
      return true;
     }
  
   public void close(MessageContext context) {
      System.out.println("Server : close()......");
    }
  
  
   public Set&lt;QName&gt; getHeaders() {
  
  Set&lt;QName&gt; HEADERS = new HashSet&lt;QName&gt;();
  
  HEADERS.add(new QName(WSConstants.WSSE_NS, "Security"));
  HEADERS.add(new QName(WSConstants.WSSE11_NS, "Security"));
  HEADERS.add(new QName(WSConstants.ENC_NS, "EncryptedData"));
  
  return HEADERS;
  
  }
  
   private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
     try {
        SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
        SOAPFault soapFault = soapBody.addFault();
        soapFault.setFaultString(reason);
        throw new SOAPFaultException(soapFault); 
     }
     catch(SOAPException e) { }
    }
  
   @SuppressWarnings("deprecation")
   public void handle(Callback[] callbacks) throws IOException,
  
          UnsupportedCallbackException {
  
       String password;
  
       for (Callback cb : callbacks) {
  
           if (cb instanceof WSPasswordCallback) {
  
                WSPasswordCallback pc = (WSPasswordCallback) cb;
  
               try {
  
                   password = /*prop.getProperty("password")*/"password";
  
               } catch (Exception e) {
  
  
                   throw new UnsupportedCallbackException(pc,  "failure recovering the key in the properties");
  
               }
  
              if (pc.getIdentifer() != null) {
  
                   pc.setPassword(password);
  
               }
  
          }
  
         }
  
      }
  
   }
  </code></pre>
  
  <p>EncryptUtil.java:</p>
  
  <pre><code>public class EncryptUtil{
  
  @SuppressWarnings( { "unchecked", "deprecation" })
  public
  static void CheckSignatureAndDecode(SOAPMessage msg,   CallbackHandler cb,Properties prop) throws WSSecurityException,            TransformerConfigurationException, TransformerException,  SOAPException, IOException, Exception {
  
      WSSecurityEngine secEngine = new WSSecurityEngine();
  
      WSSignEnvelope signer = new WSSignEnvelope();
  
      String alias = prop.getProperty("alias");// login of jks file
      String password = prop.getProperty("password");// password of jks file
  
  
      signer.setUserInfo("client", password);
  
  
      Crypto crypto = CryptoFactory.getInstance(prop);
      Document doc = toDocument(msg);
  
    //after we set the encrypt stuff the processsecurity does all the work
  
      Vector v = secEngine.processSecurityHeader(doc, null, cb, crypto);
  
      if (v == null) {
  
          throw new Exception("Access not granted.");
  
      }
  
      //put the decoded message into the object
      updateSOAPMessage(doc, msg);
    }
  
  
  
    /**
    * Updates the message with the unencrypt form
    */
  
  
     private static SOAPMessage updateSOAPMessage(Document doc, SOAPMessage message) throws SOAPException {
  
      DOMSource domSource = new DOMSource(doc);
      message.getSOAPPart().setContent(domSource);
  
      return message;
  
     } 
  
  
  
     /**
     * Changes the SOAPMessage to a dom.Document.
     */
  
  
     public static org.w3c.dom.Document toDocument(SOAPMessage soapMsg)             throws SOAPException, TransformerException {
  
      Source src = soapMsg.getSOAPPart().getContent();
  
      TransformerFactory tf = TransformerFactory.newInstance();
  
      Transformer transformer = tf.newTransformer();
  
      DOMResult result = new DOMResult();
      transformer.transform(src, result);
      return (Document) result.getNode();
  
     }
  
    /**
     * Signs  a SOAPMessage
     * 
     * @param mensaje
     * @throws Exception
    */
     @SuppressWarnings("deprecation")
     public
     static void SignSOAPEnvelope(SOAPMessage mensaje, Properties prop) throws Exception {
  
      // WSSignEnvelope signs a SOAP envelope according to the
      // WS Specification (X509 profile) and adds the signature data
      // to the envelope.
      WSSignEnvelope signer = new WSSignEnvelope();
  
      String alias = prop.getProperty("alias");// "autentiaserver";
      String password = prop.getProperty("password");// "changeit";
  
      signer.setUserInfo(alias, password);
  
      Crypto crypto = CryptoFactory.getInstance(prop);
  
      Document doc =  toDocument(mensaje);
      signer.setMustUnderstand(false);
  
      Document signedDoc =  signer.build( doc, crypto);
      DOMSource domSource = new DOMSource( signedDoc);
      mensaje.getSOAPPart().setContent(domSource);
  
     }
  
  
     /**
      * Codes a SOAPMessage.
     */
  
    @SuppressWarnings("deprecation")
    public
    static void EncryptSOAPEnvelope(SOAPMessage mensaje,Properties prop) throws Exception   {
  
  
      // WSSignEnvelope signs a SOAP envelope according to the
      // WS Specification (X509 profile) and adds the signature data
      // to the envelope.
      WSEncryptBody encriptador = new WSEncryptBody();
  
  
      String alias = prop.getProperty("alias");
      String password = prop.getProperty("password");
  
  
      encriptador.setUserInfo(alias, password);
  
     Crypto crypto = CryptoFactory.getInstance(prop);
  
  
  
      Document doc =  toDocument(mensaje);
  
      encriptador.setMustUnderstand(false);
  
      Document signedDoc =  encriptador.build( doc, crypto);
  
      DOMSource domSource = new DOMSource( signedDoc);
      mensaje.getSOAPPart().setContent(domSource);
  }
  }
  </code></pre>
  
  <p>And here's my config.properties file:</p>
  
  <pre><code>org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
  org.apache.ws.security.crypto.merlin.keystore.type=jks
  org.apache.ws.security.crypto.merlin.keystore.password=password
  org.apache.ws.security.crypto.merlin.keystore.alias=first
  org.apache.ws.security.crypto.merlin.file=/home/user/workspace/crypt_server/keystore.jks
  alias=first
  password=password
  </code></pre>
  
  <p>Any help would be appreciated. Thanks in advance.</p>