1 package net.suberic.pooka; 2 3 import java.util.Map ; 4 import java.util.HashMap ; 5 import java.util.Set ; 6 7 import java.io.File ; 8 import java.io.FileInputStream ; 9 import java.security.Key ; 10 import java.security.KeyStoreException ; 11 import java.security.GeneralSecurityException ; 12 import java.util.HashSet ; 13 import java.util.ArrayList ; 14 15 import javax.mail.internet.*; 16 import javax.mail.*; 17 18 import net.suberic.crypto.*; 19 import net.suberic.util.VariableBundle; 20 import net.suberic.util.ValueChangeListener; 21 22 26 public class PookaEncryptionManager implements ValueChangeListener { 27 28 String key; 29 VariableBundle sourceBundle; 30 31 EncryptionKeyManager pgpKeyMgr = null; 32 33 EncryptionKeyManager smimeKeyMgr = null; 34 35 char[] keyMgrPasswd = null; 36 37 Map cachedPrivateKeys = new HashMap (); 38 39 Map cachedPublicKeys = new HashMap (); 40 41 Map addressToPublicKeyMap = null; 42 43 boolean savePasswordsForSession = false; 44 45 boolean needsReload = false; 46 47 51 public PookaEncryptionManager(VariableBundle pSourceBundle, String pKey) { 52 sourceBundle = pSourceBundle; 53 key = pKey; 54 55 sourceBundle.addValueChangeListener(this, key + ".pgp.keyStore.private.filename"); 58 sourceBundle.addValueChangeListener(this, key + ".pgp.keyStore.private.password"); 59 sourceBundle.addValueChangeListener(this, key + ".pgp.keyStore.public.filename"); 60 61 sourceBundle.addValueChangeListener(this, key + ".smime.keyStore.public.filename"); 62 sourceBundle.addValueChangeListener(this, key + ".smime.keyStore.private.filename"); 63 sourceBundle.addValueChangeListener(this, key + ".smime.keyStore.private.password"); 64 65 sourceBundle.addValueChangeListener(this, key + ".savePasswordsForSession"); 66 67 final VariableBundle fBundle = sourceBundle; 68 final String fKey = key; 69 Thread storeLoadingThread = new Thread (new Runnable () { 70 public void run() { 71 loadStores(fBundle, fKey); 73 } 74 }); 75 76 storeLoadingThread.start(); 77 } 78 79 82 public void loadStores(VariableBundle sourceBundle, String key) { 83 String pgpPublicFilename = sourceBundle.getProperty(key + ".pgp.keyStore.public.filename", ""); 84 85 String pgpPrivateFilename = sourceBundle.getProperty(key + ".pgp.keyStore.private.filename", ""); 86 String pgpPrivatePwString = sourceBundle.getProperty(key + ".pgp.keyStore.private.password", ""); 87 if (!pgpPrivatePwString.equals("")) 88 pgpPrivatePwString = net.suberic.util.gui.propedit.PasswordEditorPane.descrambleString(pgpPrivatePwString); 89 90 if (! (pgpPrivateFilename.equals("") && pgpPublicFilename.equals(""))) { 92 try { 93 EncryptionUtils pgpUtils = EncryptionManager.getEncryptionUtils("PGP"); 94 if (pgpUtils != null) { 95 pgpKeyMgr = pgpUtils.createKeyManager(); 96 try { 97 pgpKeyMgr.loadPrivateKeystore(new FileInputStream (new File (pgpPrivateFilename)), pgpPrivatePwString.toCharArray()); 98 } catch (java.io.IOException fnfe) { 99 System.out.println("Error loading PGP private keystore from file " + pgpPrivateFilename + ": " + fnfe.getMessage()); 100 } catch (java.security.GeneralSecurityException gse) { 101 System.out.println("Error loading PGP private keystore from file " + pgpPrivateFilename + ": " + gse.getMessage()); 102 } 103 try { 104 pgpKeyMgr.loadPublicKeystore(new FileInputStream (new File (pgpPublicFilename)), null); 105 } catch (java.io.IOException fnfe) { 106 System.out.println("Error loading PGP public keystore from file " + pgpPublicFilename + ": " + fnfe.getMessage()); 107 } catch (java.security.GeneralSecurityException gse) { 108 System.out.println("Error loading PGP private keystore from file " + pgpPublicFilename + ": " + gse.getMessage()); 109 } 110 } 111 } catch (java.security.NoSuchProviderException nspe) { 112 System.out.println("Error loading PGP key store: " + nspe.getMessage()); 113 } catch (Exception e) { 114 System.out.println("Error loading PGP key store: " + e.getMessage()); 115 } 116 } 117 118 String smimePublicFilename = sourceBundle.getProperty(key + ".smime.keyStore.public.filename", ""); 119 120 String smimePrivateFilename = sourceBundle.getProperty(key + ".smime.keyStore.private.filename", ""); 121 String smimePrivatePwString = sourceBundle.getProperty(key + ".smime.keyStore.private.password", ""); 122 if (!smimePrivatePwString.equals("")) 123 smimePrivatePwString = net.suberic.util.gui.propedit.PasswordEditorPane.descrambleString(smimePrivatePwString); 124 125 if (! (smimePrivateFilename.equals("") && smimePublicFilename.equals(""))) { 127 try { 128 EncryptionUtils smimeUtils = EncryptionManager.getEncryptionUtils("S/MIME"); 129 if (smimeUtils != null) { 130 smimeKeyMgr = smimeUtils.createKeyManager(); 131 try { 132 smimeKeyMgr.loadPrivateKeystore(new FileInputStream (new File (smimePrivateFilename)), smimePrivatePwString.toCharArray()); 133 } catch (java.security.GeneralSecurityException gse) { 134 System.out.println("Error loading S/MIME private keystore from file " + smimePrivateFilename + ": " + gse.getMessage()); 135 } catch (java.io.IOException fnfe) { 136 System.out.println("Error loading S/MIME private keystore from file " + smimePrivateFilename + ": " + fnfe.getMessage()); 137 } 138 139 try { 140 smimeKeyMgr.loadPublicKeystore(new FileInputStream (new File (smimePublicFilename)), smimePrivatePwString.toCharArray()); 141 } catch (java.io.IOException fnfe) { 142 System.out.println("Error loading S/MIME public keystore from file " + smimePublicFilename + ": " + fnfe.getMessage()); 143 } catch (java.security.GeneralSecurityException gse) { 144 System.out.println("Error loading S/MIME private keystore from file " + smimePublicFilename + ": " + gse.getMessage()); 145 } 146 } 147 } catch (java.security.NoSuchProviderException nspe) { 148 System.out.println("Error loading S/MIME key store: " + nspe.getMessage()); 149 } catch (Exception e) { 150 System.out.println("Error loading S/MIME key store: " + e.getMessage()); 151 } 152 } 153 154 savePasswordsForSession = Pooka.getProperty(key + ".savePasswordsForSession", "false").equalsIgnoreCase("true"); 155 156 cachedPrivateKeys = new HashMap (); 157 158 cachedPublicKeys = new HashMap (); 159 160 addressToPublicKeyMap = null; 161 162 } 163 164 168 public void valueChanged(String changedValue) { 169 if (changedValue.equals(key + ".savePasswordsForSession")) { 170 savePasswordsForSession = Pooka.getProperty(key + ".savePasswordsForSession", "false").equalsIgnoreCase("true"); 171 } else { 172 needsReload = true; 174 javax.swing.SwingUtilities.invokeLater(new Runnable () { 175 176 public void run() { 177 if (needsReload) { 178 needsReload = false; 179 180 Thread updateThread = new Thread (new Runnable () { 181 public void run() { 182 loadStores(sourceBundle, key); 183 } 184 }); 185 186 updateThread.start(); 187 } 188 } 189 }); 190 } 191 } 192 193 194 197 public void addPrivateKey(String alias, Key privateKey, char[] passphrase, String type) throws GeneralSecurityException { 198 EncryptionKeyManager currentMgr = getKeyMgr(type); 199 if (currentMgr != null) { 200 currentMgr.setPrivateKeyEntry(alias, privateKey, passphrase); 201 } else { 202 throw new KeyStoreException (type + " KeyStore not initialized."); 203 } 204 } 205 206 209 public void addPublicKey(String alias, Key publicKey, String type) 210 throws GeneralSecurityException { 211 212 EncryptionKeyManager currentMgr = getKeyMgr(type); 213 if (currentMgr != null) { 214 currentMgr.setPublicKeyEntry(alias, publicKey); 215 } else { 216 throw new KeyStoreException (type + " KeyStore not initialized."); 217 } 218 } 219 220 223 public Key [] getPrivateKeys(String address) { 224 return getPrivateKeys(address, null); 225 } 226 227 231 public Key [] getPrivateKeys(String address, String type) { 232 return null; 233 } 234 235 238 public Key [] getCachedPrivateKeys() { 239 return (Key []) cachedPrivateKeys.values().toArray(new Key [0]); 240 } 241 242 245 public Set privateKeyAliases() throws java.security.KeyStoreException { 246 return privateKeyAliases(null); 247 } 248 249 253 public Set privateKeyAliases(String encryptionType) throws java.security.KeyStoreException { 254 if (encryptionType != null && encryptionType.equalsIgnoreCase(EncryptionManager.PGP)) { 255 if (pgpKeyMgr != null) 256 return new HashSet (pgpKeyMgr.privateKeyAliases()); 257 } else if (encryptionType != null && encryptionType.equalsIgnoreCase(EncryptionManager.SMIME)) { 258 if (smimeKeyMgr != null) { 259 return new HashSet (smimeKeyMgr.privateKeyAliases()); 260 } 261 } else { 262 Set returnValue = new java.util.HashSet (); 264 if (pgpKeyMgr != null) { 265 try { 266 returnValue.addAll(pgpKeyMgr.privateKeyAliases()); 267 } catch (KeyStoreException kse) { 268 } 270 } 271 if (smimeKeyMgr != null) { 272 try { 273 returnValue.addAll(smimeKeyMgr.privateKeyAliases()); 274 } catch (KeyStoreException kse) { 275 } 277 } 278 279 return returnValue; 280 } 281 282 return new HashSet (); 283 } 284 285 288 public Key getPrivateKey(String alias) throws java.security.KeyStoreException , java.security.NoSuchAlgorithmException , java.security.UnrecoverableKeyException { 289 KeyStoreException caughtException = null; 290 291 Key cachedKey = (Key ) cachedPrivateKeys.get(alias); 293 if (cachedKey != null) 294 return cachedKey; 295 296 if (pgpKeyMgr != null || smimeKeyMgr != null) { 297 298 if (pgpKeyMgr != null) { 300 try { 301 if (pgpKeyMgr.containsPrivateKeyAlias(alias)) { 302 Key returnValue = pgpKeyMgr.getPrivateKey(alias, null); 303 cachedPrivateKeys.put(alias, returnValue); 304 return returnValue; 305 } 306 } catch (KeyStoreException kse) { 307 caughtException = kse; 308 } 309 310 } 311 312 if (smimeKeyMgr!= null) { 313 try { 314 if (smimeKeyMgr.containsPrivateKeyAlias(alias)) { 315 Key returnValue = smimeKeyMgr.getPrivateKey(alias, null); 316 cachedPrivateKeys.put(alias, returnValue); 317 return returnValue; 318 } 319 } catch (KeyStoreException kse) { 320 if (caughtException == null) 321 caughtException = kse; 322 } 323 324 } 325 } 326 327 if (caughtException != null) 328 throw caughtException; 329 330 return null; 331 } 332 333 336 public Key getPrivateKey(String alias, char[] password) throws java.security.KeyStoreException , java.security.NoSuchAlgorithmException , java.security.UnrecoverableKeyException { 337 338 KeyStoreException caughtException = null; 339 340 Key cachedKey = (Key ) cachedPrivateKeys.get(alias); 342 if (cachedKey != null) 343 return cachedKey; 344 345 Key returnValue = null; 346 if (pgpKeyMgr != null) { 347 try { 348 returnValue = pgpKeyMgr.getPrivateKey(alias, password); 349 } catch (KeyStoreException kse) { 350 caughtException = kse; 351 } 352 } 353 354 if (returnValue == null && smimeKeyMgr != null) { 355 try { 356 returnValue = smimeKeyMgr.getPrivateKey(alias, password); 357 } catch (KeyStoreException kse) { 358 if (caughtException == null) 359 caughtException = kse; 360 } 361 } 362 363 if (returnValue != null) { 364 cachedPrivateKeys.put(alias, returnValue); 365 } 366 367 if (returnValue == null && caughtException != null) 368 throw caughtException; 369 370 return returnValue; 371 } 372 373 376 public Key getPublicKey(String alias) throws java.security.KeyStoreException , java.security.NoSuchAlgorithmException , java.security.UnrecoverableKeyException { 377 Key returnValue = null; 378 if (pgpKeyMgr != null) { 379 try { 380 returnValue = pgpKeyMgr.getPublicKey(alias); 381 } catch (KeyStoreException kse) { 382 } 384 } 385 386 if (returnValue == null && smimeKeyMgr != null) { 387 try { 388 returnValue = smimeKeyMgr.getPublicKey(alias); 389 } catch (KeyStoreException kse) { 390 } 392 } 393 394 return returnValue; 395 } 396 397 400 public Key [] getPublicKeys(String address) throws java.security.KeyStoreException , java.security.NoSuchAlgorithmException , java.security.UnrecoverableKeyException { 401 return getPublicKeys(address, null); 402 } 403 404 408 public Key [] getPublicKeys(String address, String type) throws java.security.KeyStoreException , java.security.NoSuchAlgorithmException , java.security.UnrecoverableKeyException { 409 if (addressToPublicKeyMap == null) { 410 sortPublicKeys(); 411 } 412 413 ArrayList list = (ArrayList ) addressToPublicKeyMap.get(address); 414 if (list == null) 415 return new Key [0]; 416 else if (type == null) { 417 return (Key []) list.toArray(new Key [0]); 418 } else { 419 ArrayList sortedList = new ArrayList (); 420 java.util.Iterator iter = list.iterator(); 421 while (iter.hasNext()) { 422 EncryptionKey current = (EncryptionKey) iter.next(); 423 try { 424 if (current.getEncryptionUtils().getType() == type) { 425 sortedList.add(current); 426 } 427 } catch (Exception e) { 428 } 429 } 430 431 return (Key []) sortedList.toArray(new Key [0]); 432 } 433 } 434 435 438 private synchronized void sortPublicKeys() throws java.security.KeyStoreException , java.security.NoSuchAlgorithmException , java.security.UnrecoverableKeyException { 439 if (addressToPublicKeyMap == null) { 440 addressToPublicKeyMap = new HashMap (); 441 Set aliases = publicKeyAliases(); 442 java.util.Iterator iter = aliases.iterator(); 443 while (iter.hasNext()) { 444 Key current = getPublicKey((String ) iter.next()); 445 446 if (current instanceof EncryptionKey) { 447 String [] assocAddresses = ((EncryptionKey) current).getAssociatedAddresses(); 448 for (int i = 0; assocAddresses != null && i < assocAddresses.length; i++) { 449 String address = assocAddresses[i]; 450 ArrayList matches = (ArrayList ) addressToPublicKeyMap.get(address); 451 if (matches != null) { 452 if (! matches.contains(current)) 453 matches.add(current); 454 } else { 455 matches = new ArrayList (); 456 matches.add(current); 457 addressToPublicKeyMap.put(address, matches); 458 } 459 } 460 } 461 } 462 } 463 } 464 465 468 public Set publicKeyAliases() throws java.security.KeyStoreException { 469 return publicKeyAliases(null); 470 } 471 472 476 public Set publicKeyAliases(String encryptionType) throws java.security.KeyStoreException { 477 478 if (encryptionType != null && encryptionType.equalsIgnoreCase(EncryptionManager.PGP)) { 479 if (pgpKeyMgr != null) 480 return new HashSet (pgpKeyMgr.publicKeyAliases()); 481 } else if (encryptionType != null && encryptionType.equalsIgnoreCase(EncryptionManager.SMIME)) { 482 if (smimeKeyMgr != null) { 483 return new HashSet (smimeKeyMgr.publicKeyAliases()); 484 } 485 } else { 486 Set returnValue = new java.util.HashSet (); 488 if (pgpKeyMgr != null) { 489 try { 490 returnValue.addAll(pgpKeyMgr.publicKeyAliases()); 491 } catch (KeyStoreException kse) { 492 } 494 } 495 if (smimeKeyMgr != null) { 496 try { 497 returnValue.addAll(smimeKeyMgr.publicKeyAliases()); 498 } catch (KeyStoreException kse) { 499 } 501 } 502 503 return returnValue; 504 } 505 506 return new HashSet (); 507 508 } 509 510 514 public MimeMessage encryptMessage(MimeMessage mMsg) throws MessagingException, java.security.GeneralSecurityException , java.io.IOException { 515 516 Key key = null; 518 Address[] recipients = mMsg.getRecipients(Message.RecipientType.TO); 519 for (int i = 0; key == null && i < recipients.length; i++) { 520 if (recipients[i] instanceof InternetAddress) { 521 String inetAddr = ((InternetAddress) recipients[i]).getAddress(); 522 Key [] matchingKeys = getPublicKeys(inetAddr); 523 if (matchingKeys != null) { 524 for (int j = 0; key != null && j < matchingKeys.length; j++) { 525 key = matchingKeys[j]; 526 } 527 } 528 } 529 } 530 531 return encryptMessage(mMsg, key); 532 } 533 534 537 public MimeMessage encryptMessage(MimeMessage mMsg, Key key) 538 throws MessagingException, java.security.GeneralSecurityException , java.io.IOException { 539 if (key != null) { 540 if (key instanceof EncryptionKey) { 541 return ((EncryptionKey) key).getEncryptionUtils().encryptMessage(Pooka.getDefaultSession(), mMsg, key); 542 } else { 543 return EncryptionManager.getEncryptionUtils("PGP").encryptMessage(Pooka.getDefaultSession(), mMsg, key); 544 } 545 546 } 547 return mMsg; 548 } 549 550 553 public MimeMessage signMessage(MimeMessage mMsg, UserProfile profile, Key key) 554 throws MessagingException, java.io.IOException , java.security.GeneralSecurityException { 555 if (key == null && profile != null) { 556 key = profile.getEncryptionKey(); 557 } 558 559 if (key == null) { 560 } 562 563 if (key != null) { 564 if (key instanceof net.suberic.crypto.EncryptionKey) { 565 return ((EncryptionKey) key).getEncryptionUtils().signMessage(Pooka.getDefaultSession(), mMsg, key); 566 } else { 567 return EncryptionManager.getEncryptionUtils("PGP").signMessage(Pooka.getDefaultSession(), mMsg, key); 568 } 569 } else { 570 return mMsg; 571 } 572 } 573 574 577 EncryptionKeyManager getKeyMgr(String type) { 578 if (type == EncryptionManager.PGP) 579 return pgpKeyMgr; 580 else if (type == EncryptionManager.SMIME) 581 return smimeKeyMgr; 582 else 583 return null; 584 } 585 } 586 | Popular Tags |