Package net.suberic.pooka.gui

Source Code of net.suberic.pooka.gui.NewMessageCryptoInfo$CryptoRecipientsInfo

package net.suberic.pooka.gui;

import java.security.GeneralSecurityException;
import java.security.Key;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeMessage;

import net.suberic.crypto.EncryptionKey;
import net.suberic.crypto.EncryptionManager;
import net.suberic.crypto.EncryptionUtils;
import net.suberic.pooka.MessageCryptoInfo;
import net.suberic.pooka.NewMessageInfo;
import net.suberic.pooka.Pooka;
import net.suberic.pooka.PookaEncryptionManager;
import net.suberic.pooka.UserProfile;
import net.suberic.pooka.gui.crypto.CryptoKeySelector;
//import net.suberic.pooka.gui.crypto.NewMessageCryptoDisplay;

/**
* Encapsulates the encryption info for a new message.
*/
public class NewMessageCryptoInfo extends MessageCryptoInfo {
  int cryptoType = NO_CRYPTO;

  public static final int NO_CRYPTO       = 0;
  public static final int SMIME_SIGN      = 1;
  public static final int SMIME_ENCRYPT   = 2;
  public static final int SMIME_BOTH      = 3;
  public static final int PGP_SIGN    = 4;
  public static final int PGP_ENCRYPT = 5;
  public static final int PGP_BOTH    = 6;

  public void setCryptoType(int type){
    cryptoType = type;
  }

  List mAttachKeys = new LinkedList();

  List mRecipientMatches = new LinkedList();

  public static int CRYPTO_YES = 0;
  public static int CRYPTO_DEFAULT = 5;
  public static int CRYPTO_NO = 10;

  // whether or not we want to encrypt this message.
  int mEncryptMessage = CRYPTO_DEFAULT;

  // whether or not we want to sign this message
  int mSignMessage = CRYPTO_DEFAULT;

  // the configured list of recipients.
  CryptoRecipientsInfo mRecipientsInfo;

  /**
   * Creates a new NewMessageCryptoInfo.
   */
  public NewMessageCryptoInfo(NewMessageInfo nmi) {
    super(nmi);
  }

  // keys

  // the signature key.
  Key mSignatureKey = null;

  // the encryption key
  Key[] mEncryptionKeys = null;

  /**
   * The Signature Key for this set of recipients.
   */
  public Key getSignatureKey() {
    return mSignatureKey;
  }

  /**
   * Sets the encryption key for encrypting this message.
   */
  public void setSignatureKey(Key pSignatureKey) {
    mSignatureKey = pSignatureKey;
  }

  /**
   * Sets the encryption key for encrypting this message.
   */
  public void setEncryptionKeys(Key[] pEncryptionKeys) {
    mEncryptionKeys = pEncryptionKeys;
  }

  /**
   * Gets the encryption key we're using for this message.
   */
  public Key[] getEncryptionKeys() {
    return mEncryptionKeys;
  }

  // sign message.

  /**
   * Returns whether we're planning on signing this message or not.
   */
  public int getSignMessage() {
    return mSignMessage;
  }

  /**
   * Sets whether or not we want to sign this message.
   */
  public void setSignMessage(int pSignMessage) {
    mSignMessage = pSignMessage;
  }

  // encrypt message.

  /**
   * Returns whether we're planning on encrypting this message or not.
   */
  public int getEncryptMessage() {
    return mEncryptMessage;
  }

  /**
   * Sets whether or not we want to encrypt this message.
   */
  public void setEncryptMessage(int pEncryptMessage) {
    mEncryptMessage = pEncryptMessage;
  }

  // attach keys.

  /**
   * Attaches an encryption key to this message.
   */
  public synchronized void attachEncryptionKey(Key key) {
    if (! mAttachKeys.contains(key))
      mAttachKeys.add(key);
  }

  /**
   * Attaches an encryption key to this message.
   */
  public synchronized void removeEncryptionKey(Key key) {
    if (mAttachKeys.contains(key)) {
      mAttachKeys.remove(key);
    }

  }

  /**
   * Returns the keys to be attached.
   */
  public List getAttachKeys() {
    return new LinkedList(mAttachKeys);
  }

  // methods.

  /**
   * Creates the attached key parts for this message.
   */
  public List createAttachedKeyParts() {
    LinkedList keyParts = new LinkedList();
    List attachKeys = getAttachKeys();
    if (attachKeys != null) {
      for (int i = 0; i < attachKeys.size(); i++) {
        EncryptionKey currentKey = (EncryptionKey)attachKeys.get(i);
        try {
          EncryptionUtils utils = currentKey.getEncryptionUtils();
          keyParts.add(utils.createPublicKeyPart(new Key[] { currentKey }));
        } catch (Exception e) {
          // FIXME ignore for now.
          System.out.println("caught exception adding key to message:  " + e);
          e.printStackTrace();
        }
      }
    }

    return keyParts;
  }

  /**
   * Returns the encrypted and/or signed message(s), as appropriate.
   */
  public MimeMessage createEncryptedMessage(UserProfile profile, MimeMessage mm) throws MessagingException, java.io.IOException, java.security.GeneralSecurityException {
    if (cryptoType == NO_CRYPTO)
      return mm;

    Key signKey = null;

    signKey = getSignatureKey();
    if (signKey == null){
      switch (cryptoType) {
      case SMIME_SIGN:
      case SMIME_BOTH:
        signKey = profile.getEncryptionKey(EncryptionManager.SMIME, true);
        break;
      case PGP_SIGN:
      case PGP_BOTH:
        signKey = profile.getEncryptionKey(EncryptionManager.PGP, true);
        break;
      }
    }

    PookaEncryptionManager cryptoManager = Pooka.getCryptoManager();

    InternetAddress from = (InternetAddress) mm.getFrom()[0];

    // Find the keys to sign and encrypt the messages
    if(signKey == null && (cryptoType == SMIME_SIGN || cryptoType == SMIME_BOTH)){
      Key[] keys = cryptoManager.getPrivateKeysForAddress(from.getAddress(), EncryptionManager.SMIME,  true);
      if (keys == null || keys.length == 0) {
        // show dialog
        signKey = CryptoKeySelector.selectPrivateKey(Pooka.getProperty("Pooka.crypto.privateKey.forSign", "Select key to sign this message."), EncryptionManager.SMIME, true);
      } else {
        signKey = keys[0];
      }

      if (signKey == null) {
        throw new GeneralSecurityException("No signature key selected.");
      }
    }

    if(signKey == null &&  (cryptoType == PGP_SIGN || cryptoType == PGP_BOTH)){
      Key[] keys = cryptoManager.getPrivateKeysForAddress(from.getAddress(), EncryptionManager.PGP,  true);
      if (keys == null || keys.length == 0) {
        // show dialog
        signKey = CryptoKeySelector.selectPrivateKey(Pooka.getProperty("Pooka.crypto.privateKey.forSign", "Select key to sign this message."), EncryptionManager.PGP, true);

      } else {
        signKey = keys[0];
      }

      if (signKey == null) {
        throw new GeneralSecurityException("No signature key selected.");
      }
    }

    List encKeys = new LinkedList();

    //TODO: get the encKey from the available public keys
    if (cryptoType == SMIME_ENCRYPT || cryptoType == SMIME_BOTH || cryptoType == PGP_ENCRYPT || cryptoType == PGP_BOTH) {
      String type = (cryptoType == SMIME_ENCRYPT || cryptoType == SMIME_BOTH) ? EncryptionManager.SMIME : EncryptionManager.PGP;
      // Get the public key of the senders
      Address[] froms = mm.getFrom();
      for (int i = 0; i < froms.length; i++) {
        from = (InternetAddress) froms[i];
        Key[] keys = cryptoManager.getPublicKeys(from.getAddress(), type, false);
        if (keys != null && keys.length > 0) {
          encKeys.add(keys[0]);
        }
      }

      // Get the public key of the receivers
      Address[] receivers = mm.getAllRecipients();
      for (int i = 0; i < receivers.length; i++) {
        InternetAddress rec = (InternetAddress) receivers[i];
        Key[] keys = cryptoManager.getPublicKeys(rec.getAddress(), type, false);
        if (keys != null && keys.length > 0) {
          encKeys.add(keys[0]);
        } else {
          Key key = CryptoKeySelector.selectPublicKey(Pooka.getProperty("Pooka.crypto.publicKey.forEncrypt", "Select key to encrypt this message."), EncryptionManager.PGP, false);
          if (key != null)
            encKeys.add(key);
          else
            throw new GeneralSecurityException("found no certificate for " + rec.getAddress());
        }
      }
      /*Key encKey = CryptoKeySelector.selectPublicKey(
        Pooka.getProperty("Pooka.crypto.publicKey.forEncrypt",
        "Select key to encrypt this message."),
        EncryptionManager.SMIME, false);
      */
    }

    if (encKeys.size() > 0) {
      Key[] encKeysArray = (Key[]) encKeys.toArray(new Key[0]);
      mRecipientsInfo.setEncryptionKeys(encKeysArray);
    }


    if (signKey != null) {
      mRecipientsInfo.setSignatureKey(signKey);
    }

    return mRecipientsInfo.handleMessage(mm);

  }

  /**
   * Returns the configured CryptoRecipientInfos.
   */
  public CryptoRecipientsInfo getCryptoRecipientsInfo() {
    return mRecipientsInfo;
  }

  /**
   * Updates the CryptoRecipientInfos with information from the
   * MessageUI.
   */
  public boolean updateRecipientInfos(UserProfile profile, InternetHeaders headers) throws javax.mail.internet.AddressException, javax.mail.MessagingException {
    // just use the defaults for now.

    String toHeader = headers.getHeader("To", ",");
    if (toHeader == null) {
      throw new MessagingException(Pooka.getProperty("error.NewMessage.noTo", "No To: recipient"));
    }
    InternetAddress[] toAddresses = InternetAddress.parse(headers.getHeader("To", ","), false);
    if (toAddresses == null || toAddresses.length == 0) {
      throw new MessagingException(Pooka.getProperty("error.NewMessage.noTo", "No To: recipient"));
    }

    String ccHeaderLine = headers.getHeader("CC", ",");
    InternetAddress[] ccAddresses;
    if (ccHeaderLine != null && ccHeaderLine.length() > 0) {
      ccAddresses = InternetAddress.parse(ccHeaderLine, false);
    } else {
      ccAddresses = new InternetAddress[0];
    }

    String bccHeaderLine = headers.getHeader("BCC", ",");
    InternetAddress[] bccAddresses;
    if (bccHeaderLine != null && bccHeaderLine.length() > 0) {
      bccAddresses = InternetAddress.parse(bccHeaderLine, false);
    } else {
      bccAddresses = new InternetAddress[0];
    }

    Key[] cryptKeys = null;

    if (getEncryptMessage() != CRYPTO_NO)
      cryptKeys = getEncryptionKeys();

    Key sigKey = null;
    if (getSignMessage() != CRYPTO_NO)
      sigKey = getSignatureKey();

    mRecipientsInfo = new CryptoRecipientsInfo(sigKey, cryptKeys, toAddresses, ccAddresses, bccAddresses);

    return true;
  }

  // Recipient/encryption key matches.
  /**
   * This represents a match between a recipient set and an encryption
   * configuration.  The assumption is that all of the following recipients
   * can receive the same message.
   */
  public class CryptoRecipientsInfo {
    // the signature key.
    Key mSignatureKey = null;

    // the encryption key
    Key[] mEncryptionKeys = null;

    // the recipients
    Address[] toList = null;
    Address[] ccList = null;
    Address[] bccList = null;

    /**
     * Creteas a new CryptoRecipieintInfo.
     */
    public CryptoRecipientsInfo() {

    }

    /**
     * Creates a new CryptoRecipieintInfo with the given signatureKey,
     * encryptionKey, toList, ccList, and bccList.
     */
    public CryptoRecipientsInfo(Key pSignatureKey, Key[] pEncryptionKeys,
                                Address[] pToList, Address[] pCcList, Address[] pBccList) {

      setEncryptionKeys(pEncryptionKeys);
      setSignatureKey(pSignatureKey);

      setRecipients(pToList, Message.RecipientType.TO);
      setRecipients(pCcList, Message.RecipientType.CC);
      setRecipients(pBccList, Message.RecipientType.BCC);
    }


    /**
     * The recipients for this crypto configuration.
     */
    public Address[] getRecipients(Message.RecipientType type) {
      if (type == Message.RecipientType.TO)
        return toList;
      else if (type == Message.RecipientType.CC)
        return ccList;
      else if (type == Message.RecipientType.BCC)
        return bccList;
      else
        return null;
    }

    /**
     * The recipients for this crypto configuration.
     */
    public Address[] getAllRecipients() {
      Address[] returnValue = new Address[0];
      returnValue = appendToArray(returnValue, toList);
      returnValue = appendToArray(returnValue, ccList);
      returnValue = appendToArray(returnValue, bccList);

      return returnValue;
    }

    /**
     * Appends to an array of Addresses.
     */
    private Address[] appendToArray(Address[] original, Address[] toAdd) {
      if (toAdd != null && toAdd.length > 0) {
        int oldSize = original.length;
        Address[] newReturnValue = new Address[original.length + toAdd.length];
        System.arraycopy(original, 0, newReturnValue, 0, original.length);
        System.arraycopy(toAdd, 0, newReturnValue, original.length, toAdd.length);
        return newReturnValue;
      } else {
        return original;
      }
    }

    /**
     * Sets the recipients for the particular type.
     */
    public void setRecipients(Address[] pRecipients, Message.RecipientType type) {
      if (type == Message.RecipientType.TO)
        toList = pRecipients;
      else if (type == Message.RecipientType.CC)
        ccList = pRecipients;
      else if (type == Message.RecipientType.BCC)
        bccList = pRecipients;

    }

    /**
     * The Signature Key for this set of recipients.
     */
    public Key getSignatureKey() {
      return mSignatureKey;
    }

    /**
     * Sets the encryption key for encrypting this message.
     */
    public void setSignatureKey(Key pSignatureKey) {
      mSignatureKey = pSignatureKey;
    }

    /**
     * Sets the encryption key for encrypting this message.
     */
    public void setEncryptionKeys(Key[] pEncryptionKeys) {
      mEncryptionKeys = pEncryptionKeys;
    }

    /**
     * Gets the encryption key we're using for this message.
     */
    public Key[] getEncryptionKeys() {
      return mEncryptionKeys;
    }

    /**
     * Creates a new MimeMessage using the given recipients and encryption.
     */
    public MimeMessage handleMessage(MimeMessage mm)
      throws MessagingException, java.io.IOException, java.security.GeneralSecurityException  {
      //MimeMessage returnValue = new MimeMessage(mm);

      /*
        returnValue.setRecipients(Message.RecipientType.TO, getRecipients(Message.RecipientType.TO));
        returnValue.setRecipients(Message.RecipientType.CC, getRecipients(Message.RecipientType.CC));
        returnValue.setRecipients(Message.RecipientType.BCC, getRecipients(Message.RecipientType.BCC));
      */

      Key sigKey = getSignatureKey();
      Key[] cryptoKeys = getEncryptionKeys();

      /*      if (sigKey instanceof EncryptionKey && cryptoKey instanceof EncryptionKey) {
              if (((EncryptionKey)sigKey).getType() != ((EncryptionKey)cryptoKey).getType()) {
              throw new MessagingException(Pooka.getProperty("error.NewMessage.differentEncryption", "Encryption and Signature Keys must be of same type (PGP or S/MIME)"));
              }
              }
      */
      PookaEncryptionManager cryptoManager = Pooka.getCryptoManager();

      if (getSignatureKey() != null) {
        mm = cryptoManager.signMessage(mm, null, sigKey);
      }

      if (cryptoKeys != null) {
        mm = cryptoManager.encryptMessage(mm,
                                          cryptoKeys);
      }

      return mm;
    }
  }

}
TOP

Related Classes of net.suberic.pooka.gui.NewMessageCryptoInfo$CryptoRecipientsInfo

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.