org.faceless.pdf2.viewer2
Class KeyStoreManager

java.lang.Object
  extended by org.faceless.pdf2.viewer2.KeyStoreManager

public class KeyStoreManager
extends Object

This class is a wrapper around a KeyStore, providing high-level management functions and the ability to load and save the KeyStore, selecting the file via a Swing dialog.

Each PDFViewer should have a KeyStoreManager if it needs to work with digital identities, which in practice means PDFs containing digital signatures (or that will have signatures added) or those encrypted with a public key. By default this class works with KeyStores stored in a file, although subclasses aren't bound by this.

File-based KeyStores - JKS, JCEKS and PKCS#12

If nothing else is specified, the default KeyStore used is a JKS KeyStore loaded from the file ${user.home}/.keystore, which is the default for the keytool supplied with the JDK. The path to the file can be changed by setting the file parameter, and the password with the "password" parameter. The KeyStore type parameter can be jks (the default, and used for jceks keystores as well) or pkcs12 if the KeyStore is in PKCS#12 format. Here's how to do this for an application

 java -Dorg.faceless.pdf2.viewer2.KeyStoreManager.params="type=pkcs12;file=/path/to/file.p12" org.faceless.pdf2.viewer2.PDFViewer
or like this for an applet:
 <applet code="org.faceless.pdf2.viewer2.PDFViewerApplet" name="pdfapplet" archive="bfopdf.jar">
  <param name="KeyStoreManager.params" value="type=jks;file='/path/to/file.jks';password='secret'" />
 </applet>

Using the OS X KeyChain as a KeyStore

Certificates and keys stored in the Apple OS X "KeyChain" can be accessed by setting the provider parameter to "Apple" and the type parameter to "KeychainStore". No other parameters are required. There are some issues with this KeyStore - in particular, at least until OS X 10.6 only the first private key in the KeyStore can be accessed. Here's an example.

java -Dorg.faceless.pdf2.viewer2.KeyStoreManager.params=type=KeychainStore\;provider=Apple org.faceless.pdf2.viewer2.PDFViewer

PKCS#11 based Keystores

Since 2.11.14 it's possible to use a PKCS#11 based Hardware Security Module (HSM) as a KeyStore. The attributes supplied to the sun.security.pkcs11.SunPKCS11 Provider (specified here) can be supplied directly as parameters, and the type parameter must be set to "pkcs11". For example, here's how to use a Safenet eToken Pro on Windows as a KeyStore: for an explanation of how to parse the parameterss see the setParameters(java.lang.String) method.

 java -Dorg.faceless.pdf2.viewer2.KeyStoreManager.params="type=pkcs11;name=eToken;library='c:\\WINDOWS\\system32\\eTPKCS11.dll';password=1234" org.faceless.pdf2.viewer2.PDFViewer

The ManageIdentities feature is a useful companion to this class and can be used to maintain the KeyStore, but it's not necessary for this class's operation.

This code is copyright the Big Faceless Organization. You're welcome to use, modify and distribute it in any form in your own projects, provided those projects continue to make use of the Big Faceless PDF library.

Since:
2.8.3, but a major rewrite in 2.11
See Also:
ManageIdentities, KeyStoreSignatureProvider, PublicKeyPromptEncryptionHandler, PDFViewer.getKeyStoreManager()

Field Summary
protected  boolean changed
           
static FileFilter FILTER_CERTIFICATE
          A FileFilter that selects any X.509 Certificate file.
static FileFilter FILTER_KEYSTORE
          A FileFilter that selects any KeyStore file
static FileFilter FILTER_KEYSTORE_JKS
          A FileFilter that selects any JKS/JCEKS format KeyStore file
static FileFilter FILTER_KEYSTORE_PKCS12
          A FileFilter that selects any PKCS#12 format KeyStore file
protected  KeyStore keystore
           
protected  Map params
           
protected  WeakPropertyChangeSupport propertyChangeSupport
           
protected  PropertyManager propertymanager
           
 
Constructor Summary
KeyStoreManager(PDFViewer viewer)
          Create a new KeyStoreManager
 
Method Summary
 void addPropertyChangeListener(PropertyChangeListener listener)
          Add a Listener to changes to this KeyStore.
 void cancelKeyStore()
          Cancel any changes to the current keystore.
 boolean canCreateSelfSignedCertificate()
          Return true if this KeyStoreManager has permission to create a new self-signed certificate.
 boolean canStoreSecretKeys()
          Return true if this KeyStore can store Secret (symmetric) key information.
 boolean canStoreSecretKeysOnConversion()
          Return true if this KeyStore can store Secret (symmetric) key information, or can be converted to one that can.
 boolean contains(Certificate cert)
          Indicates whether this key store contains the specified certificate.
 void createKeyStore()
          Initialize a new KeyStore for this object to manage.
 String createSelfSignedKey(String alias, String name, String unit, String organization, String city, String state, String country, char[] password, int days)
          Create a new 2048-bit RSA PrivateKey with self-signed X509Certificate, and add it to the KeyStore.
 String createSelfSignedKey(String alias, String name, String unit, String organization, String city, String state, String country, char[] password, int days, String algorithm, int keylength)
          Create a new PrivateKey of the specified algorithm, with self-signed X509Certificate, and add it to the KeyStore.
 void deleteEntry(String alias)
          Delete the specified entry (PrivateKey or X509Certificate) from the KeyStore
 void exportCertificate(OutputStream out, String alias)
          Export a public X509Certificate from the KeyStore to a DES-encoded Certificate file.
 void exportPKCS12Certificate(OutputStream out, String alias, char[] password)
          Export a PrivateKey and associated Certificate Chain from the KeyStore to a PKCS#12 object.
 KeyStore getKeyStore()
          Get the KeyStore managed by this object - will call loadKeyStore() if it's not already been called.
 String getParameter(String key)
          Return a parameter set by setParameter(java.lang.String, java.lang.String)
 SecretKey getSecret(String alias, String type, char[] password)
          Get a secret value from the KeyStore, as set by putSecret()
 String getStoreType()
          Get the KeyStore type
 String[] importAllCertificates(File file, String alias)
          Import all the X.509 Certificates from the specified file into this KeyStore.
 String[] importAllCertificates(InputStream in, String alias, String format)
          Import all the X.509 Certificates from an InputStream into the KeyStore.
 String importCertificate(String alias, X509Certificate cert)
          Add the specified X.509 Certificate to the list of trusted root certificates.
 String importPrivateKey(KeyStore store, String alias, char[] password)
          Add a PrivateKey to the KeyStore.
 String importPrivateKey(PrivateKey key, Certificate[] certs, String alias, char[] password)
          Add a PrivateKey to the KeyStore.
 boolean isCancellable()
          Return true if changes to the KeyStore can be cancelled, or false if they're committed immediately
 boolean isChanged()
          Return true if this KeyStore is "dirty" and needs to be saved to commit any changes, or false if no changes have been made.
 boolean isFileBased()
          Return true if the KeyStore is file based, false otherwise.
 void loadKeyStore()
          Load the KeyStore this manager is supposed to work on, based on the parameters specified.
 boolean loadKeyStore(JComponent root)
          Create a Swing component prompting the user to load the KeyStore.
 void putSecret(String alias, SecretKey key, char[] password)
          Store a secret value in the KeyStore - any data which needs to be password protected.
 void removePropertyChangeListener(PropertyChangeListener listener)
          Remote a Listener form listening to changes to this KeyStore.
 void saveKeyStore()
          Save the KeyStore using the setParameter(java.lang.String, java.lang.String) parameters specified for this class - for file-based KeyStores like JKS, JCEKS and PKCS#12, this requires the file parameter and optionally the password parameter too (if no password is specified, the empty string is used).
 boolean saveKeyStore(JComponent root)
          Create a Swing compoment prompting the user to save the KeyStore.
 void setFile(File file, char[] password)
          Deprecated. call setParameter with "file" and "password" as keys
 void setParameter(String key, String value)
          Set a parameter to be used when loading or saving the KeyStore.
 void setParameters(String in)
          Set the store parameters.
 void setProvider(String provider)
          Deprecated. call setParameter with "provider" as the key
 void setStoreType(String type)
          Deprecated. call setParameter with "type" as the key
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

FILTER_KEYSTORE

public static final FileFilter FILTER_KEYSTORE
A FileFilter that selects any KeyStore file

Since:
2.11

FILTER_KEYSTORE_JKS

public static final FileFilter FILTER_KEYSTORE_JKS
A FileFilter that selects any JKS/JCEKS format KeyStore file

Since:
2.11

FILTER_KEYSTORE_PKCS12

public static final FileFilter FILTER_KEYSTORE_PKCS12
A FileFilter that selects any PKCS#12 format KeyStore file

Since:
2.11

FILTER_CERTIFICATE

public static final FileFilter FILTER_CERTIFICATE
A FileFilter that selects any X.509 Certificate file.

Since:
2.11

propertyChangeSupport

protected WeakPropertyChangeSupport propertyChangeSupport

keystore

protected KeyStore keystore

params

protected Map params

propertymanager

protected final PropertyManager propertymanager

changed

protected boolean changed
Constructor Detail

KeyStoreManager

public KeyStoreManager(PDFViewer viewer)
Create a new KeyStoreManager

Parameters:
viewer - the Viewer
Method Detail

loadKeyStore

public void loadKeyStore()
                  throws IOException,
                         GeneralSecurityException
Load the KeyStore this manager is supposed to work on, based on the parameters specified. These will typically include the file and password parameters. If the KeyStore cannot be loaded, this method will throw an Exception Subclasses that need to manage their own KeyStore will typically override this method and saveKeyStore().

Throws:
IOException - if the KeyStore file cannot be accessed
GeneralSecurityException - if the KeyStore cannot be parsed or decoded

saveKeyStore

public void saveKeyStore()
                  throws IOException,
                         GeneralSecurityException
Save the KeyStore using the setParameter(java.lang.String, java.lang.String) parameters specified for this class - for file-based KeyStores like JKS, JCEKS and PKCS#12, this requires the file parameter and optionally the password parameter too (if no password is specified, the empty string is used).

Throws:
IOException - if the KeyStore file cannot be saved.
GeneralSecurityException - if the KeyStore cannot be saved for a cryptographic-related reason.

setParameters

public void setParameters(String in)
Set the store parameters. The supplied string is a semi-colon delimitered String which contains the parameters that could also be specified individually in calls to setParameter(java.lang.String, java.lang.String). For instance, the following method calls are the same:
 setParameters("type=pkcs11;name=eToken;library='/usr/lib/libeTPkcs11.so';enabledMechanisms='{CKM_RSA_PKCS CKM_RSA_PKCS_KEY_PAIR_GEN};attributes(*,CKO_PRIVATE_KEY,*)='{\\nCKA_SIGN=true\\nCKA_DECRYPT=true\\n}'");
 
 setParameter("type", "pkcs11");
 setParameter("name", "eToken");
 setParameter("library", "/usr/lib/libeTPkcs11.so");
 setParameter("enabledMechanisms", "{CKM_RSA_PKCS CKM_RSA_PKCS_KEY_PAIR_GEN}");
 setParameter("attribute(*,CKO_PRIVATE_KEY,*)", "{\nCKA_SIGN=true\nCKA_DECRYPT=true\n}");
 
Characters can be quoted or preceded with a backslash to treat them as literals.

Since:
2.11.14

setParameter

public void setParameter(String key,
                         String value)
Set a parameter to be used when loading or saving the KeyStore. Typical parameters include
typeThe KeyStore type: one of "jks", "jceks", "pkcs12", "pkcs11" or "keychainstore"
providerThe KeyStore provider
fileFor jks, jceks and pkcs12 KeyStores, the file to save the KeyStore in
passwordThe store password for the KeyStore
keylengthWhen creating new key pairs, the number of bits to use for the key (default is 2048)
sigalgWhen creating new key pairs, the algorith, to use (default is SHA1withRSA)
For PKCS#11 KeyStores, any of the attributes specified in the Java PKCS#11 Reference Guide may be specified as well.

Since:
2.11.14

getParameter

public String getParameter(String key)
Return a parameter set by setParameter(java.lang.String, java.lang.String)

Since:
2.11.14

setStoreType

public void setStoreType(String type)
Deprecated. call setParameter with "type" as the key

Set the KeyStore type.

Parameters:
type - the KeyStore type

getStoreType

public String getStoreType()
Get the KeyStore type

Since:
2.11.21

setProvider

public void setProvider(String provider)
Deprecated. call setParameter with "provider" as the key

Set the KeyStore provider

Parameters:
provider - the KeyStore provider

setFile

public void setFile(File file,
                    char[] password)
Deprecated. call setParameter with "file" and "password" as keys

Set the KeyStore file and password

Parameters:
file - the KeyStore file
password - the KeyStore password

cancelKeyStore

public void cancelKeyStore()
Cancel any changes to the current keystore.


createKeyStore

public void createKeyStore()
                    throws GeneralSecurityException
Initialize a new KeyStore for this object to manage. The KeyStore will use the values set by setType() and setProvider() or the system defaults.

Throws:
GeneralSecurityExeption - if the KeyStore cannot be created.
GeneralSecurityException

isFileBased

public boolean isFileBased()
Return true if the KeyStore is file based, false otherwise.

Since:
2.11.14

isCancellable

public boolean isCancellable()
Return true if changes to the KeyStore can be cancelled, or false if they're committed immediately

Since:
2.11.14

loadKeyStore

public boolean loadKeyStore(JComponent root)
Create a Swing component prompting the user to load the KeyStore. The initially selected file is the KeyStore managed by this object, if specified.

Parameters:
root - the JComponent to position the dialog relative too.
Returns:
true if a KeyStore was loaded, false otherwise

saveKeyStore

public boolean saveKeyStore(JComponent root)
Create a Swing compoment prompting the user to save the KeyStore. The initially selected file is the KeyStore managed by this object, if specified.

Parameters:
root - the JComponent to position the dialog relative too.
Returns:
true if the KeyStore was saved, false otherwise

getKeyStore

public KeyStore getKeyStore()
                     throws GeneralSecurityException,
                            IOException
Get the KeyStore managed by this object - will call loadKeyStore() if it's not already been called.

Throws:
GeneralSecurityException
IOException

isChanged

public boolean isChanged()
Return true if this KeyStore is "dirty" and needs to be saved to commit any changes, or false if no changes have been made.


importCertificate

public String importCertificate(String alias,
                                X509Certificate cert)
                         throws GeneralSecurityException
Add the specified X.509 Certificate to the list of trusted root certificates.

Parameters:
alias - the alias to store it under, or null to choose one
cert - the X.509 Certificate to store
Returns:
the name the Certificate was stored under, or null if the certificate already existed
Throws:
GeneralSecurityException - if the Certificate can not be imported

importAllCertificates

public String[] importAllCertificates(File file,
                                      String alias)
                               throws GeneralSecurityException,
                                      IOException
Import all the X.509 Certificates from the specified file into this KeyStore. The File may be a KeyStore file or a file that can be parsed by an X.509 CertificateFactory.

Parameters:
file - the File containing the X.509 Certificates
alias - the initial alias for the imports (may be null)
Returns:
a list of the aliases the Certificates were stored under
Throws:
IOException - if the Certificates can not be read due to File I/O reasons
GeneralSecurityException - if the Certificates can not be read for a cryptographic reason

importAllCertificates

public String[] importAllCertificates(InputStream in,
                                      String alias,
                                      String format)
                               throws GeneralSecurityException,
                                      IOException
Import all the X.509 Certificates from an InputStream into the KeyStore. The InputStream is closed on completion.

Parameters:
in - the InputStream to read the X.509 Certificates from
alias - if importing from a list of X.509 Certificates the alias to store the Certificate against, or null to pick one
format - one of "X.509", "JKS" or "pkcs12" to specify the format of in - a list of X.509 certificates, a JKS/JCEKS KeyStore or a PKCS#12 KeyStore
Returns:
a list of aliases added to the KeyStore
Throws:
IOException - if the Certificates can not be read due to File I/O reasons
GeneralSecurityException - if the Certificates can not be read for a cryptographic reason

importPrivateKey

public String importPrivateKey(KeyStore store,
                               String alias,
                               char[] password)
                        throws GeneralSecurityException
Add a PrivateKey to the KeyStore. The Key is loaded from the specified KeyStore

Parameters:
store - the KeyStore to load the private key from
alias - the name the private key is stored under
password - the password to access the private key
Throws:
GeneralSecurityException - if the Key could not be extracted or stored

importPrivateKey

public String importPrivateKey(PrivateKey key,
                               Certificate[] certs,
                               String alias,
                               char[] password)
                        throws GeneralSecurityException
Add a PrivateKey to the KeyStore.

Parameters:
key - the Key
certs - the Certificate chain
alias - a suggestion for the name the private key should be stored under
password - the password to encrypt the private key with
Throws:
GeneralSecurityException - if the Key could not be stored

exportPKCS12Certificate

public void exportPKCS12Certificate(OutputStream out,
                                    String alias,
                                    char[] password)
                             throws GeneralSecurityException,
                                    IOException
Export a PrivateKey and associated Certificate Chain from the KeyStore to a PKCS#12 object. The PKCS#12 object is written to the OutputStream, and the stream is left open on completion of this method.

Parameters:
out - the OutputStream
alias - the alias of the entry to export
password - the password used to access the private key
Throws:
IOException - if an I/O exception occurs while writing
GeneralSecurityException - if the PrivateKey cannot be extracted from the KeyStore

contains

public boolean contains(Certificate cert)
                 throws GeneralSecurityException,
                        IOException
Indicates whether this key store contains the specified certificate.

Parameters:
cert - the certificate to test
Throws:
GeneralSecurityException
IOException

exportCertificate

public void exportCertificate(OutputStream out,
                              String alias)
                       throws GeneralSecurityException,
                              IOException
Export a public X509Certificate from the KeyStore to a DES-encoded Certificate file. The file is written to the specified OutputStream, and the stream is left open on completion of this method.

Parameters:
out - the OutputStream
alias - the alias of the entry to export
Throws:
IOException - if an I/O exception occurs while writing
GeneralSecurityException - if the Certificate cannot be extracted from the KeyStore

deleteEntry

public void deleteEntry(String alias)
                 throws GeneralSecurityException
Delete the specified entry (PrivateKey or X509Certificate) from the KeyStore

Parameters:
alias - the entry to delete
Throws:
GeneralSecurityException - if the entry cannot be deleted from the KeyStore

canStoreSecretKeysOnConversion

public boolean canStoreSecretKeysOnConversion()
Return true if this KeyStore can store Secret (symmetric) key information, or can be converted to one that can.

Since:
2.11.22
See Also:
canStoreSecretKeys()

canStoreSecretKeys

public boolean canStoreSecretKeys()
Return true if this KeyStore can store Secret (symmetric) key information.

Since:
2.11.21
See Also:
canStoreSecretKeysOnConversion()

putSecret

public void putSecret(String alias,
                      SecretKey key,
                      char[] password)
               throws GeneralSecurityException,
                      IOException
Store a secret value in the KeyStore - any data which needs to be password protected.

Parameters:
alias - the alias
key - the key to store, or null to delete any secret key with this alias
password - the password that will be used to encrypt this data. if null, the KeyStore password is tried.
Throws:
GeneralSecurityException
IOException
Since:
2.11.21

getSecret

public SecretKey getSecret(String alias,
                           String type,
                           char[] password)
                    throws GeneralSecurityException
Get a secret value from the KeyStore, as set by putSecret()

Parameters:
alias - the alias
password - the password - if null, the KeyStore password is tried.
Throws:
GeneralSecurityException
Since:
2.11.21

createSelfSignedKey

public String createSelfSignedKey(String alias,
                                  String name,
                                  String unit,
                                  String organization,
                                  String city,
                                  String state,
                                  String country,
                                  char[] password,
                                  int days)
                           throws GeneralSecurityException
Create a new 2048-bit RSA PrivateKey with self-signed X509Certificate, and add it to the KeyStore.

Parameters:
alias - the alias to store it as
name - the CN of the X.509 certificate DN
unit - the OU of the X.509 certificate DN
organization - the O of the X.509 certificate DN
city - the L of the X.509 certificate DN
country - the C of the X.509 certificate DN
password - the password to store the key with
days - the number of days the Key is valid for from now.
Returns:
the alias the new Key is stored under in the KeyStore
Throws:
GeneralSecurityException - if something goes wrong

createSelfSignedKey

public String createSelfSignedKey(String alias,
                                  String name,
                                  String unit,
                                  String organization,
                                  String city,
                                  String state,
                                  String country,
                                  char[] password,
                                  int days,
                                  String algorithm,
                                  int keylength)
                           throws GeneralSecurityException
Create a new PrivateKey of the specified algorithm, with self-signed X509Certificate, and add it to the KeyStore.

Parameters:
alias - the alias to store it as
name - the CN of the X.509 certificate DN
unit - the OU of the X.509 certificate DN
organization - the O of the X.509 certificate DN
city - the L of the X.509 certificate DN
country - the C of the X.509 certificate DN
password - the password to store the key with
days - the number of days the Key is valid for from now.
algorithm - the Signature algorithm, eg "SHA1withRSA", "SHA256withRSA", "SHA256withDSA"
keylength - the length of the key in bits, eg 1024, 2048, 4096
Returns:
the alias the new Key is stored under in the KeyStore
Throws:
GeneralSecurityException - if something goes wrong
Since:
2.11.14

canCreateSelfSignedCertificate

public boolean canCreateSelfSignedCertificate()
Return true if this KeyStoreManager has permission to create a new self-signed certificate. This is only possible in a trusted environment.


addPropertyChangeListener

public void addPropertyChangeListener(PropertyChangeListener listener)
Add a Listener to changes to this KeyStore. A PropertyChangeEvent occurs when a new entry is added or removed from the KeyStore managed by this KeyStoreManager. Duplicate PropertyChangeListeners are ignored and listeners are held in this class with a weak-reference and so will be removed automatically on garbage collection.

Parameters:
listener - the Listener.

removePropertyChangeListener

public void removePropertyChangeListener(PropertyChangeListener listener)
Remote a Listener form listening to changes to this KeyStore.

Parameters:
listener - a listener previously added in addPropertyChangeListener().


Copyright © 2001-2010 Big Faceless Organization