Package net.suberic.pooka

Source Code of net.suberic.pooka.PookaEncryptionManager

package net.suberic.pooka;

import java.io.File;
import java.io.FileInputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import net.suberic.crypto.EncryptionKey;
import net.suberic.crypto.EncryptionKeyManager;
import net.suberic.crypto.EncryptionManager;
import net.suberic.crypto.EncryptionUtils;
import net.suberic.crypto.bouncycastle.BouncySMIMEEncryptionKey;
import net.suberic.crypto.bouncycastlepgp.BCPGPEncryptionKey;
import net.suberic.pooka.resource.ResourceManager;
import net.suberic.util.ValueChangeListener;
import net.suberic.util.VariableBundle;

/**
* The EncryptionManager manages Pooka's encryption facilities.  It's
* basically one-stop shopping for all of your email encryption needs.
*/
public class PookaEncryptionManager implements ValueChangeListener {
  char[] pgpPassphrase;
  char[] smimePassphrase;
 
  String key;
  VariableBundle sourceBundle;

  EncryptionKeyManager pgpKeyMgr = null;

  EncryptionKeyManager smimeKeyMgr = null;

  char[] keyMgrPasswd = null;

  Map cachedPGPPrivateKeys = new HashMap();
  Map cachedSMIMEPrivateKeys = new HashMap();

  Map cachedPGPPublicKeys = new HashMap();
  Map cachedSMIMEPublicKeys = new HashMap();

  Map addressToPGPPublicKeyMap = null;
  Map addressToSMIMEPublicKeyMap = null;

  boolean savePasswordsForSession = false;

  boolean needsReload = false;

  /**
   * Creates an EncryptionManager using the given VariableBundle and
   * key property.
   */
  public PookaEncryptionManager(VariableBundle pSourceBundle, String pKey) {
    sourceBundle = pSourceBundle;
    key = pKey;

    // register this for listening to changes to the store filenames and the
    // store passwords.
    sourceBundle.addValueChangeListener(this, key + ".pgp.keyStore.private.filename");
    sourceBundle.addValueChangeListener(this, key + ".pgp.keyStore.private.password");
    sourceBundle.addValueChangeListener(this, key + ".pgp.keyStore.public.filename");

    sourceBundle.addValueChangeListener(this, key + ".smime.keyStore.public.filename");
    sourceBundle.addValueChangeListener(this, key + ".smime.keyStore.private.filename");
    sourceBundle.addValueChangeListener(this, key + ".smime.keyStore.private.password");

    sourceBundle.addValueChangeListener(this, key + ".savePasswordsForSession");

    final VariableBundle fBundle = sourceBundle;
    final String fKey = key;
    Thread storeLoadingThread = new Thread(new Runnable() {
  public void run() {
    // load the given pgp and smime stores.
    loadStores(fBundle, fKey);
  }
      });

    storeLoadingThread.start();
  }

  /**
   * Loads the stores.
   */
  public void loadStores(VariableBundle sourceBundle, String key) {
  ResourceManager rm = Pooka.getPookaManager().getResourceManager();
   
    String pgpPublicFilename = sourceBundle.getProperty(key + ".pgp.keyStore.public.filename", "");
    if(!pgpPublicFilename.equals(""))
      pgpPublicFilename = rm.translateName(pgpPublicFilename);
   
    String pgpPrivateFilename = sourceBundle.getProperty(key + ".pgp.keyStore.private.filename", "");
    if(!pgpPrivateFilename.equals(""))
      pgpPrivateFilename = rm.translateName(pgpPrivateFilename);
   
    String pgpPrivatePwString = sourceBundle.getProperty(key + ".pgp.keyStore.private.password", "");
    if (!pgpPrivatePwString.equals("")){
      pgpPrivatePwString = net.suberic.util.gui.propedit.PasswordEditorPane.descrambleString(pgpPrivatePwString);
      pgpPassphrase = pgpPrivatePwString.toCharArray();
    }

    // if either store is configured, try loading.
    if (! (pgpPrivateFilename.equals("") && pgpPublicFilename.equals(""))) {
      try {
    EncryptionUtils pgpUtils = EncryptionManager.getEncryptionUtils(EncryptionManager.PGP);
    if (pgpUtils != null) {
      pgpKeyMgr = pgpUtils.createKeyManager();
      try {
          pgpKeyMgr.loadPrivateKeystore(new FileInputStream(new File(pgpPrivateFilename)), null);
      } catch (java.io.IOException fnfe) {
          System.out.println("Error loading PGP private keystore from file " + pgpPrivateFilename + ":  " + fnfe.getMessage());
      } catch (java.security.GeneralSecurityException gse) {
          System.out.println("Error loading PGP private keystore from file " + pgpPrivateFilename + ":  " + gse.getMessage());
      }
      try {
        pgpKeyMgr.loadPublicKeystore(new FileInputStream(new File(pgpPublicFilename)), null);
      } catch (java.io.IOException fnfe) {
        System.out.println("Error loading PGP public keystore from file " + pgpPublicFilename + ":  " + fnfe.getMessage());
      } catch (java.security.GeneralSecurityException gse) {
        System.out.println("Error loading PGP public keystore from file " + pgpPublicFilename + ":  " + gse.getMessage());
      }
    }
      } catch (java.security.NoSuchProviderException nspe) {
        System.out.println("Error loading PGP key store:  " + nspe.getMessage());
      } catch (Exception e) {
        System.out.println("Error loading PGP key store:  " + e.getMessage());
      }
    }

    String smimePublicFilename = sourceBundle.getProperty(key + ".smime.keyStore.public.filename", "");
    if(!smimePublicFilename.equals(""))
      smimePublicFilename = rm.translateName(smimePublicFilename);

    String smimePrivateFilename = sourceBundle.getProperty(key + ".smime.keyStore.private.filename", "");
    if(!smimePrivateFilename.equals(""))
      smimePrivateFilename = rm.translateName(smimePrivateFilename);
   
    String smimePrivatePwString = sourceBundle.getProperty(key + ".smime.keyStore.private.password", "");
    if (!smimePrivatePwString.equals("")){
      smimePrivatePwString = net.suberic.util.gui.propedit.PasswordEditorPane.descrambleString(smimePrivatePwString);
      smimePassphrase = smimePrivatePwString.toCharArray();
    }

    // if either store is configured, try loading.
    if (! (smimePrivateFilename.equals("") && smimePublicFilename.equals(""))) {
      try {
  EncryptionUtils smimeUtils = EncryptionManager.getEncryptionUtils(EncryptionManager.SMIME);
  if (smimeUtils != null) {
    smimeKeyMgr = smimeUtils.createKeyManager();
    try {
      smimeKeyMgr.loadPrivateKeystore(new FileInputStream(new File(smimePrivateFilename)), smimePrivatePwString.toCharArray());
    } catch (java.security.GeneralSecurityException gse) {
      System.out.println("Error loading S/MIME private keystore from file " + smimePrivateFilename + ":  " + gse.getMessage());
    } catch (java.io.IOException fnfe) {
      System.out.println("Error loading S/MIME private keystore from file " + smimePrivateFilename + ":  " + fnfe.getMessage());
    }
   
    try {
      smimeKeyMgr.loadPublicKeystore(new FileInputStream(new File(smimePublicFilename)), smimePrivatePwString.toCharArray());
    } catch (java.io.IOException fnfe) {
      System.out.println("Error loading S/MIME public keystore from file " + smimePublicFilename + ":  " + fnfe.getMessage());
    } catch (java.security.GeneralSecurityException gse) {
      System.out.println("Error loading S/MIME private keystore from file " + smimePublicFilename + ":  " + gse.getMessage());
    }     
  }
      } catch (java.security.NoSuchProviderException nspe) {
  System.out.println("Error loading S/MIME key store:  " + nspe.getMessage());
      } catch (Exception e) {
  System.out.println("Error loading S/MIME key store:  " + e.getMessage());
      }
    }

    savePasswordsForSession = Pooka.getProperty(key + ".savePasswordsForSession", "false").equalsIgnoreCase("true");
   
    cachedPGPPrivateKeys = new HashMap();
    cachedSMIMEPrivateKeys = new HashMap();

    cachedPGPPublicKeys = new HashMap();
    cachedSMIMEPublicKeys = new HashMap();

    addressToPGPPublicKeyMap = null;
    addressToSMIMEPublicKeyMap = null;

  }

  /**
   * As defined in net.suberic.util.ValueChangeListener.
   *
   */
  public void valueChanged(String changedValue) {
    if (changedValue.equals(key + ".savePasswordsForSession")) {
      savePasswordsForSession = Pooka.getProperty(key + ".savePasswordsForSession", "false").equalsIgnoreCase("true");
    } else {
      // this is crazy.
      needsReload = true;
      javax.swing.SwingUtilities.invokeLater(new Runnable() {

    public void run() {
      if (needsReload) {
        needsReload = false;
       
        Thread updateThread = new Thread(new Runnable() {
      public void run() {
        loadStores(sourceBundle, key);
      }
    });
       
        updateThread.start();
      }
    }
  });
    }
  }
 
 
  /**
   * Adds the private key to the store.
   */
  public void addPrivateKey(String alias, Key privateKey, char[] passphrase, String type) throws GeneralSecurityException {
    EncryptionKeyManager currentMgr = getKeyMgr(type);
    if (currentMgr != null) {
      currentMgr.setPrivateKeyEntry(alias, privateKey, passphrase);
    } else {
      throw new KeyStoreException(type + " KeyStore not initialized.");
    }
  }

  /**
   * Adds the public key to the store.
   */
  public void addPublicKey(String alias, Key publicKey, String type)
  throws GeneralSecurityException {
   
    EncryptionKeyManager currentMgr = getKeyMgr(type);
    if (currentMgr != null) {
      currentMgr.setPublicKeyEntry(alias, publicKey);
    } else {
      throw new KeyStoreException(type + " KeyStore not initialized.");
    }
  }

  /**
   * Returns the private key(s) for the given email address and
   * the given encryption type, or all matching keys if type == null.
   */
  public Key[] getPrivateKeysForAddress(String address, String type, boolean forSignature) {
    //return null;
    //Liao-
    ArrayList keys = new ArrayList();
    Set aliases;
    Iterator it;
    String alias;
   
    try {
    aliases = privateKeyAliases(type, forSignature);
      } catch (KeyStoreException e) {
        return null;
    }
     
    it = aliases.iterator();
    while(it.hasNext()){
     alias = (String) it.next();
     Key key = null;
    try {
      key = this.getPrivateKey(alias, type);
    } catch (Exception e) {
      continue;
    }
   
     if(key != null){
       String[] addresses = ((EncryptionKey) key).getAssociatedAddresses();
      
       if(addresses != null){
         for (int i = 0; i < addresses.length; i++) {          
          if(addresses[i].length() > 0 && address.equalsIgnoreCase(addresses[i])){
            keys.add(key);
          }
        }
       }
     }
    }

    Key[] _keys = new Key[keys.size()];
    for (int i = 0; i < _keys.length; i++) {
    _keys[i] = (Key) keys.get(i);
  }
   
    return _keys;
    //Liao+
  }
 

  /**
   * Returns all private keys that have been cached.
   */
  public Key[] getCachedPrivateKeys(String type) {
    if(EncryptionManager.PGP.equalsIgnoreCase(type))
      return (Key[])cachedPGPPrivateKeys.values().toArray(new Key[0]);
    else if(EncryptionManager.SMIME.equalsIgnoreCase(type))
      return (Key[])cachedSMIMEPrivateKeys.values().toArray(new Key[0]);
    else
        return null;
  }

  /**
   * Returns all available private key aliases for the give EncryptionType,
   * or all available aliases if type is null.
   */
  public Set privateKeyAliases(String encryptionType, boolean forSignature)
  throws java.security.KeyStoreException {
    if (EncryptionManager.PGP.equalsIgnoreCase(encryptionType)) {
      if (pgpKeyMgr != null)
    return new HashSet(pgpKeyMgr.privateKeyAliases(forSignature));
      }
      else if (EncryptionManager.SMIME.equalsIgnoreCase(encryptionType)) {
        if (smimeKeyMgr != null) {
        return new HashSet(smimeKeyMgr.privateKeyAliases(forSignature));
          }
      }

    return new HashSet();
  }

  public Key getPrivateKey(String alias, String type)
  throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException {
    if(EncryptionManager.SMIME.equalsIgnoreCase(type)){
      return getPrivateKey(alias, type, smimePassphrase);
    } else if(EncryptionManager.PGP.equalsIgnoreCase(type)){
      return getPrivateKey(alias, type, pgpPassphrase);
    } else{
     return null;
   
  }
  /**
   * Returns the Private key for the given alias.
   */
  public Key getPrivateKey(String alias, String type, char[] passphrase)
  throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException {
   Map cachedPrivateKeys = null;
   if(EncryptionManager.PGP.equalsIgnoreCase(type)){
     cachedPrivateKeys = cachedPGPPrivateKeys;
   }else if(EncryptionManager.SMIME.equalsIgnoreCase(type)){
     cachedPrivateKeys = cachedSMIMEPrivateKeys;
   }else{
     return null;
   }
  
    // first check to see if this is in the cache.
    Key cachedKey = (Key) cachedPrivateKeys.get(alias);
    if (cachedKey != null){
      return cachedKey;
  }
   
    KeyStoreException caughtException = null;
    if (pgpKeyMgr != null || smimeKeyMgr != null) {
      // check to see if this exists anywhere.
      if (pgpKeyMgr != null && EncryptionManager.PGP.equalsIgnoreCase(type)) {
    try {
      if (pgpKeyMgr.containsPrivateKeyAlias(alias)) {
        Key returnValue = pgpKeyMgr.getPrivateKey(alias, passphrase);

        cachedPrivateKeys.put(alias, returnValue);
        return returnValue;
      }
    } catch (KeyStoreException kse) {
      caughtException = kse;
    }
      }
     
      if (smimeKeyMgr!= null && EncryptionManager.SMIME.equalsIgnoreCase(type)) {
    try {
      if (smimeKeyMgr.containsPrivateKeyAlias(alias)) {
        Key returnValue = smimeKeyMgr.getPrivateKey(alias, passphrase);
        cachedPrivateKeys.put(alias, returnValue);
        return returnValue;
      }
    } catch (KeyStoreException kse) {
      if (caughtException == null)
        caughtException = kse;
    }
      }
    }
   
    if (caughtException != null)
      throw caughtException;
   
    return null;
  }
  //Liao+

  /**
   * Returns the Public key for the given alias.
   */
  public Key getPublicKey(String alias, String type)
  throws java.security.KeyStoreException,
         java.security.NoSuchAlgorithmException,
         java.security.UnrecoverableKeyException
  {
    EncryptionKeyManager keymanager;
    if(EncryptionManager.PGP.equalsIgnoreCase(type)){
     keymanager = pgpKeyMgr;
    } else if(EncryptionManager.SMIME.equalsIgnoreCase(type)){
     keymanager = smimeKeyMgr;
    } else{
      return null;
    }
   
      try {
       return keymanager.getPublicKey(alias);
      } catch (KeyStoreException kse) {
        return null;
      }
  }
 
  /**
   * Returns the public key(s) for the given email address that match
   * the given encryption type, or all matching keys if type == null.
   */
  public Key[] getPublicKeys(String address, String type, boolean forSignature)
  throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException
  {  
    sortPublicKeys(type);

    Map addressToPublicKeyMap;
   if(EncryptionManager.PGP.equalsIgnoreCase(type)){
     addressToPublicKeyMap = addressToPGPPublicKeyMap;
   }else if(EncryptionManager.SMIME.equalsIgnoreCase(type)){
     addressToPublicKeyMap = addressToSMIMEPublicKeyMap;
   }else{
     return new Key[0];
   }

    ArrayList list = (ArrayList) addressToPublicKeyMap.get(address.toLowerCase());
    if (list == null)
      return new Key[0];
    else if (type == null) {
      return (Key[]) list.toArray(new Key[0]);
    } else {
      ArrayList sortedList = new ArrayList();
      java.util.Iterator iter = list.iterator();     
     
      while (iter.hasNext()) {
    EncryptionKey current = (EncryptionKey) iter.next();
    try {
      if (current.getEncryptionUtils().getType().equalsIgnoreCase(type))
      {
        if(forSignature && current.isForSignature()){
          sortedList.add(current);
        }else if(!forSignature && current.isForEncryption()){
          sortedList.add(current);
        }
      }
    } catch (Exception e) {
    }
      }

      return (Key[]) sortedList.toArray(new Key[0]);
    }
  }

  /**
   * Sorts all available public keys by associated address.
   */
  private synchronized void sortPublicKeys(String type)
  throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException
  {
  if(! (EncryptionManager.PGP.equalsIgnoreCase(type) || EncryptionManager.SMIME.equalsIgnoreCase(type))){
    return;
  }
 
  Map addressToPublicKeyMap;
 
  if(EncryptionManager.PGP.equalsIgnoreCase(type)){
    if(addressToPGPPublicKeyMap == null){
      addressToPGPPublicKeyMap = new HashMap();
      addressToPublicKeyMap = addressToPGPPublicKeyMap;
    }
    else
      return;
  }else if(EncryptionManager.SMIME.equalsIgnoreCase(type)){
    if(addressToSMIMEPublicKeyMap == null){
      addressToSMIMEPublicKeyMap = new HashMap();
      addressToPublicKeyMap = addressToSMIMEPublicKeyMap;
    }
    else
      return;
  }else{
    return;
  }
 

      Set aliases1 = publicKeyAliases(type, true);
      Set aliases2 = publicKeyAliases(type, false);
      Set aliases3 = privateKeyAliases(type, true);
      Set aliases4 = privateKeyAliases(type, false);

      java.util.Iterator iter2 = aliases2.iterator();
      while(iter2.hasNext()){
      String s = (String) iter2.next();
      if(!aliases1.contains(s)){
        aliases1.add(s);
      }
      }
     
      iter2 = aliases4.iterator();
      while(iter2.hasNext()){
      String s = (String) iter2.next();
      if(!aliases3.contains(s)){
        aliases3.add(s);
      }
      }
     
      java.util.Iterator iter = aliases1.iterator();
      java.util.Iterator iter3 = aliases3.iterator();
      while (iter.hasNext() || iter3.hasNext()) {
        Key current = null;
       
        if(iter.hasNext()){
          String alias = (String) iter.next();
          current = getPublicKey(alias, type);
        }else{
          String alias = (String) iter3.next();
          try{
            current = getPrivateKey(alias, type);
          }catch(UnrecoverableKeyException uke){
            ;
          }
        }
 
    if (current instanceof EncryptionKey) {
      String[] assocAddresses = ((EncryptionKey) current).getAssociatedAddresses();
      for (int i = 0; assocAddresses != null && i < assocAddresses.length; i++) {
        String address = assocAddresses[i];
        ArrayList matches = (ArrayList) addressToPublicKeyMap.get(address);
        if (matches != null) {
          if (! matches.contains(current))
          matches.add(current);
        } else {
          matches = new ArrayList();
          matches.add(current);
          addressToPublicKeyMap.put(address.toLowerCase(), matches);
        }
      }
    }
      }   
  }

  /**
   * Returns available public key aliases for the given encryption type, or
   * all available aliases if null.
   */
  public Set publicKeyAliases(String encryptionType, boolean forSignature) throws java.security.KeyStoreException {

    if (EncryptionManager.PGP.equalsIgnoreCase(encryptionType)) {
      if (pgpKeyMgr != null)
      return new HashSet(pgpKeyMgr.publicKeyAliases(forSignature));
    } else if (EncryptionManager.SMIME.equalsIgnoreCase(encryptionType)) {
      if (smimeKeyMgr != null) {
      return new HashSet(smimeKeyMgr.publicKeyAliases(forSignature));
      }
    }

    return new HashSet();

  }

 
  /**
   * Encrypts the given message.  If there's no key, return null.
   */
  public MimeMessage encryptMessage(MimeMessage mMsg, Key[] keys)
    throws MessagingException, java.security.GeneralSecurityException, java.io.IOException {
    if (keys != null && keys.length > 0) {
       return ((EncryptionKey) keys[0]).getEncryptionUtils().encryptMessage(
    Pooka.getDefaultSession(), mMsg, keys);     
    }
   
    return mMsg;
  }

  /**
   * Signs the given message.
   */
  public MimeMessage signMessage(MimeMessage mMsg, UserProfile profile, Key key)
    throws MessagingException, java.io.IOException, java.security.GeneralSecurityException  {
    boolean forSignature = true;
    if (key == null && profile != null) {
      key = profile.getEncryptionKey(forSignature);
    }
   
    if (key == null) {
      // get user input
    }

    if (key != null) {
      if (key instanceof net.suberic.crypto.EncryptionKey) {
      return ((EncryptionKey) key).getEncryptionUtils().signMessage(
      Pooka.getDefaultSession(), mMsg, key);
      } else {
      return EncryptionManager.getEncryptionUtils(EncryptionManager.PGP).signMessage(
      Pooka.getDefaultSession(), mMsg, key);
      }
    } else {
      return mMsg;
    }
  }

  /**
   * Returns the EncryptionKeyManager for this type.
   */
  EncryptionKeyManager getKeyMgr(String type) {
    if (EncryptionManager.PGP.equalsIgnoreCase(type))
      return pgpKeyMgr;
    else if (EncryptionManager.SMIME.equalsIgnoreCase(type))
      return smimeKeyMgr;
    else
      return null;
  }
}
TOP

Related Classes of net.suberic.pooka.PookaEncryptionManager

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.