Package org.jboss.ws.extensions.security.operation

Source Code of org.jboss.ws.extensions.security.operation.EncryptionOperation

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ws.extensions.security.operation;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.xml.namespace.QName;

import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.jboss.util.NotImplementedException;
import org.jboss.ws.extensions.security.QNameTarget;
import org.jboss.ws.extensions.security.SecurityStore;
import org.jboss.ws.extensions.security.SignatureKeysAssociation;
import org.jboss.ws.extensions.security.Target;
import org.jboss.ws.extensions.security.Util;
import org.jboss.ws.extensions.security.element.EncryptedKey;
import org.jboss.ws.extensions.security.element.Reference;
import org.jboss.ws.extensions.security.element.ReferenceList;
import org.jboss.ws.extensions.security.element.SecurityHeader;
import org.jboss.ws.extensions.security.element.X509Token;
import org.jboss.ws.extensions.security.exception.WSSecurityException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class EncryptionOperation implements EncodingOperation
{
   private List<Target> targets;
   private String alias;
   private String algorithm;
   private String wrap;
   private String tokenRefType;
   private String securityDomainAliasLabel;
  
   public EncryptionOperation(List<Target> targets, String alias, String algorithm, String wrap, String tokenRefType, String securityDomainAliasLabel)
   {
      super();
      this.targets = targets;
      this.alias = alias;
      this.algorithm = algorithm;
      this.wrap = wrap;
      this.tokenRefType = tokenRefType;
      this.securityDomainAliasLabel = securityDomainAliasLabel;
   }

   private void processTarget(XMLCipher cipher, Document message, Target target, ReferenceList list, SecretKey key) throws WSSecurityException
   {
      if (!(target instanceof QNameTarget))
         throw new NotImplementedException();

      QName name = ((QNameTarget)target).getName();

      Element element = Util.findElement(message.getDocumentElement(), name);
      if (element == null)
         throw new RuntimeException("Could not find element");

      // Ensure that the element has an id, so that encryption verification can be performed
      Util.assignWsuId(element);

      try
      {
         cipher.init(XMLCipher.ENCRYPT_MODE, key);
         EncryptedData encrypted = cipher.getEncryptedData();
         String id = Util.generateId("encrypted");
         encrypted.setId(id);
         list.add(id);
         cipher.doFinal(message, element, target.isContent());
      }
      catch (Exception e)
      {
         throw new WSSecurityException("Error encrypting target: " + name, e);
      }
   }

   private static SecretKey getSecretKey(String algorithm) throws WSSecurityException
   {
      try
      {
         KeyGenerator kgen = KeyGenerator.getInstance(EncryptionAlgorithms.getAlgorithmJceName(algorithm));
         kgen.init(EncryptionAlgorithms.getAlgorithmSize(algorithm));
         return kgen.generateKey();
      }
      catch (NoSuchAlgorithmException e)
      {
         throw new WSSecurityException(e.getMessage());
      }
   }
  
   public static SecretKey generateSecretKey(String alg) throws WSSecurityException
   {
      return getSecretKey(EncryptionAlgorithms.getAlgorithmID(alg));
   }
  
   public void process(Document message, SecurityHeader header, SecurityStore store) throws WSSecurityException
   {
      if (! EncryptionAlgorithms.hasAlgorithm(algorithm))
         algorithm = EncryptionAlgorithms.DEFAULT_ALGORITHM;

      SecretKey secretKey = getSecretKey(algorithm);
      XMLCipher cipher;
      try
      {
         cipher = XMLCipher.getInstance(EncryptionAlgorithms.getAlgorithm(algorithm));
         cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
      }
      catch (XMLSecurityException e)
      {
         throw new WSSecurityException("Error initializing xml cipher" + e.getMessage(), e);
      }

      ReferenceList list = new ReferenceList();

      if (targets == null || targets.size() == 0)
      {
         // By default we encrypt the content of the body element
         String namespace = message.getDocumentElement().getNamespaceURI();
         processTarget(cipher, message, new QNameTarget(new QName(namespace, "Body"), true), list, secretKey);
      }
      else
      {
         for (Target target : targets)
            processTarget(cipher, message, target, list, secretKey);
      }
     
      X509Certificate cert = getCertificate(store, alias, securityDomainAliasLabel);
      X509Token token = (X509Token) header.getSharedToken(cert);

      // Can we reuse an existing token?
      if (token == null)
      {
         token = new X509Token(cert, message);
         if (tokenRefType == null || Reference.DIRECT_REFERENCE.equals(tokenRefType))
            header.addToken(token);
      }

      EncryptedKey eKey = new EncryptedKey(message, secretKey, token, list, wrap, tokenRefType);
      header.addSecurityProcess(eKey);
   }
  
   @SuppressWarnings("unchecked")
   private X509Certificate getCertificate(SecurityStore store, String alias, String secDomainLabel) throws WSSecurityException
   {
      X509Certificate cert = null;
      if (alias != null || secDomainLabel != null)
      {
         cert = store.getCertificate(alias, secDomainLabel);
         if (cert == null)
            throw new WSSecurityException("Cannot load certificate from keystore; alias = " + alias);
      }
      else
      {
         List<PublicKey> publicKeys = SignatureKeysAssociation.getPublicKeys();
         if (publicKeys != null && publicKeys.size() == 1)
            cert = store.getCertificateByPublicKey(publicKeys.iterator().next());
         if (cert == null)
            throw new WSSecurityException("Cannot get the certificate for message encryption! Verify the keystore contents, " +
                "considering the certificate is obtained through the alias specified in the encrypt configuration element " +
                "or (server side only) through a single key used to sign the incoming message.");
      }
      return cert;
   }
  
  
   public static boolean probeUnlimitedCrypto() throws WSSecurityException
   {
      try
      {
         //Check AES-256
         KeyGenerator kgen = KeyGenerator.getInstance("AES");
         kgen.init(256);
         SecretKey key = kgen.generateKey();
         Cipher c = Cipher.getInstance("AES");
         c.init(Cipher.ENCRYPT_MODE, key);
        
         //Check Blowfish
         kgen = KeyGenerator.getInstance("Blowfish");
         key = kgen.generateKey();
         c = Cipher.getInstance("Blowfish");
         c.init(Cipher.ENCRYPT_MODE, key);
        
         return true;
      }
      catch (InvalidKeyException e)
      {
         return false;
      }
      catch (Exception e)
      {
         throw new WSSecurityException("Error probing cryptographic permissions", e);
      }
   }
}
TOP

Related Classes of org.jboss.ws.extensions.security.operation.EncryptionOperation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.