org.faceless.pdf2
Class SignatureHandler

java.lang.Object
  extended by org.faceless.pdf2.SignatureHandler
Direct Known Subclasses:
DSE200Handler, EGIZSignatureHandler, PKCS7SignatureHandler

public abstract class SignatureHandler
extends Object

This class is the baseline handler for all digital signatures - it could theoretically be used for any type of signature, using biometrics, public/private key and so on. Two main implementations are provided with this package, those returned by AcrobatSignatureHandlerFactory and thoe returned by the DSE200HandlerFactory. Typically an object of this type will be a PKCS7SignatureHandler.

For 99% of users, it is enough to look at the examples in the FormSignature API documentation, which details how to sign and verify documents using the standard handlers. For those wanting to write their own signature handlers however, read on.

The SignatureHandler class has several methods which need to be implemented by concrete implementations of this class. They are at a minimum getFilter(), the verify() method (if the handler is to be used to verify signatures), and/or the prepareToSign(), getMessageDigest() and sign() methods if the handler is to be used to sign signatures. In addition, when signing if the signature is to have a visible appearance on the page, something useful should be returned from getLayerNames() and getLayerAppearance().

The idea behind the handler is that when signing, first any annotations associated with the signature are created and filled using the values returned from the getLayerAppearance() method. Then the prepareToSign() method is called, which should set all the values in the "V" dictionary and generally do everything required to set up the signature in preparation for signing. Finally the sign() method is called, it's return value is stored in the "Contents" field.

The SignatureHandler works in a similar way to the EncryptionHandler class. There are a number of get...Value and put...Value methods which can be used to get/set values in the "V" dictionary of the Signature dictionary. See the discussion in the EncryptionHandler class documentation for details on how these methods work. As an example, the SelfSign handler includes the following lines in it's prepareToSign() method:

   putNameValue("Filter", "Adobe.PPKLite");
   putNameValue("SubFilter", "adbe.x509.rsa_sha1");
   putNumericValue("R", 65539);
   putStringValue("Cert", certificatebytearray);
 

As a slightly more complicated example, to add /MyArray [ 100 << /Type /MyHandler >> ] to the "V" dictionary, just do:

   putArrayValue("MyArray");
   putNumericValue("MyArray.0", 100);
   putDictionaryValue("MyArray.1");
   putNameValue("MyArray.1.Type", "MyHandler");
 

The getFilter() method should return an appropriate value - so again, the SelfSign handler will return the string "Adobe.PPKLite".

For a concrete example of a working, if somewhat brain-dead signature handler, see the DummySignatureHandler.java example, supplied with the download package.

Since:
2.0
See Also:
FormSignature, SignatureHandlerFactory

Nested Class Summary
static class SignatureHandler.Placeholder
          A Placeholder can be used to mark a point in the PDF which needs to be updated after the signature has been applied
 
Constructor Summary
SignatureHandler()
           
 
Method Summary
protected  boolean containsKey(String key)
          Return true if the V dictionary contains the specified key
protected  int getArrayValueSize(String key)
          Return the size of the specified Array from the V dictionary, or -1 if no such field exists
protected  boolean getBooleanValue(String key)
          Return a Boolean from the V dictionary as a boolean or false if no such field exists
 String getDefaultName()
          Returns an optional default value that can be used to initialize FormSignature.setName(java.lang.String), or null if no such name is available.
protected  Set getDictionaryValueKeys(String key)
          Return the Set of keys of the specified Dictionary from the V dictionary, or null if no such field exists.
 int getEstimatedContentSize(int contentsize)
          Return the estimated size of the signature object to be embedded, or <= 0 if this cannot be determined.
abstract  String getFilter()
          Return the name of the filter, eg "Adobe.PPKLite".
 FormSignature getFormSignature()
          Get the FormSignature this handler is attaached to
abstract  PDFCanvas getLayerAppearance(String layername, PDFStyle style)
          Return a PDFCanvas for the specified layer.
abstract  String[] getLayerNames()
          Return the list of appearance layer names used by this Signature Handler to create a visible appearance on the page, in the order they should be drawn.
protected abstract  MessageDigest getMessageDigest()
          Return a MessageDigest that will be used to calculate the digest of the PDF for signing.
protected  String getNameValue(String key)
          Return a Name from the V dictionary as a String or null if no such field exists
protected  float getNumericValue(String key)
          Return a Number from the V dictionary as a float or Float.NaN if no such field exists
protected  InputStream getStreamValue(String key)
          Return the contents of a Stream from the V dictionary, or false if no such field exists
protected  byte[] getStringValue(String key)
          Return a String from the V dictionary as a byte array or null if no such field exists
protected  String getTextStringValue(String key)
          Return a Text String from the V dictionary as a String or null if no such field exists
 Map getVariables()
           Return the list of "variables" which will be set by the handler after the PDF is rendered.
protected  void postDigest(long filelength, Map variables)
          Update any Variables that need to be updated after the Digest is calculated (eg Contents).
protected  void preDigest(long filelength, Map variables)
          Update any Variables that need to be updated before the Digest is calculated (eg ByteRange).
protected  void prepareToSign(KeyStore keystore, String alias, char[] password)
           This method initialized the handler using the specified values into a state where it's ready to sign.
protected  void putArrayValue(String key)
          Add (or replace) an Array to the V dictionary.
protected  void putBooleanValue(String key, boolean val)
          Add (or replace) a Boolean to the V dictionary.
protected  void putDictionaryValue(String key)
          Add (or replace) a Dictionary to the V dictionary.
protected  void putNameValue(String key, String val)
          Add (or replace) a Name to the V dictionary.
protected  void putNumericValue(String key, float val)
          Add (or replace) a Number to the V dictionary.
protected  void putStreamValue(String key, byte[] val)
          Add (or replace) the contents of a Stream in the V dictionary.
protected  void putStringValue(String key, byte[] val)
          Add (or replace) a String to the V dictionary.
protected  void putTextStringValue(String key, String val)
          Add (or replace) a Text String to the V dictionary.
protected  byte[] sign()
           Finish the digest calculation on the digest returned from getMessageDigest() and return a signature token the signs it.
protected abstract  boolean verify(InputStream in)
          Return a boolean indicating whether or not the signature handler can verify the specified InputStream.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SignatureHandler

public SignatureHandler()
Method Detail

containsKey

protected boolean containsKey(String key)
Return true if the V dictionary contains the specified key


getStringValue

protected final byte[] getStringValue(String key)
Return a String from the V dictionary as a byte array or null if no such field exists


getTextStringValue

protected final String getTextStringValue(String key)
Return a Text String from the V dictionary as a String or null if no such field exists


getNameValue

protected final String getNameValue(String key)
Return a Name from the V dictionary as a String or null if no such field exists


getNumericValue

protected final float getNumericValue(String key)
Return a Number from the V dictionary as a float or Float.NaN if no such field exists


getBooleanValue

protected final boolean getBooleanValue(String key)
Return a Boolean from the V dictionary as a boolean or false if no such field exists


getArrayValueSize

protected final int getArrayValueSize(String key)
Return the size of the specified Array from the V dictionary, or -1 if no such field exists


getDictionaryValueKeys

protected final Set getDictionaryValueKeys(String key)
Return the Set of keys of the specified Dictionary from the V dictionary, or null if no such field exists.


getStreamValue

protected final InputStream getStreamValue(String key)
Return the contents of a Stream from the V dictionary, or false if no such field exists

Since:
2.6.5

putStringValue

protected final void putStringValue(String key,
                                    byte[] val)
Add (or replace) a String to the V dictionary. A value of null removes the entry.


putTextStringValue

protected final void putTextStringValue(String key,
                                        String val)
Add (or replace) a Text String to the V dictionary. A value of null removes the entry


putNumericValue

protected final void putNumericValue(String key,
                                     float val)
Add (or replace) a Number to the V dictionary. A value of Float.NaN removes the entry.


putNameValue

protected final void putNameValue(String key,
                                  String val)
Add (or replace) a Name to the V dictionary. A value of null removes the entry.


putBooleanValue

protected final void putBooleanValue(String key,
                                     boolean val)
Add (or replace) a Boolean to the V dictionary.


putArrayValue

protected final void putArrayValue(String key)
Add (or replace) an Array to the V dictionary.


putDictionaryValue

protected final void putDictionaryValue(String key)
Add (or replace) a Dictionary to the V dictionary.


putStreamValue

protected final void putStreamValue(String key,
                                    byte[] val)
Add (or replace) the contents of a Stream in the V dictionary.

Since:
2.6.5

getVariables

public Map getVariables()
                 throws GeneralSecurityException

Return the list of "variables" which will be set by the handler after the PDF is rendered. Entries in the returned map should have a String as a key and a SignatureHandler.Placeholder as a value. These placeholders will be inserted into the PDF at the correct points.

For most SignatureHandlers, the only variables are the "ByteRange" and "Contents" array containing the signature token, which is what this method returns (it may be overridden if more variables are required).

This method was updated for a new signing architecture in release 2.11.12.

Returns:
a Map containing the variables to be substituted into the PDF during signing
Throws:
GeneralSecurityException
Since:
2.3
See Also:
AcrobatSignatureHandlerFactory.setContentSize(int)

getEstimatedContentSize

public int getEstimatedContentSize(int contentsize)
Return the estimated size of the signature object to be embedded, or <= 0 if this cannot be determined. The default implementation returns 0.

Parameters:
contentsize - the negation of any value previously passed into setContentSize(int)
Since:
2.11.21

getFilter

public abstract String getFilter()
Return the name of the filter, eg "Adobe.PPKLite".


preDigest

protected void preDigest(long filelength,
                         Map variables)
                  throws Exception
Update any Variables that need to be updated before the Digest is calculated (eg ByteRange).

Parameters:
filelength - the length of the PDF file, in bytes
variables - the Map of variables, ordered by their position in the file.
Throws:
Exception
Since:
2.11.12

postDigest

protected void postDigest(long filelength,
                          Map variables)
                   throws Exception
Update any Variables that need to be updated after the Digest is calculated (eg Contents).

Parameters:
filelength - the length of the PDF file, in bytes
variables - the Map of variables, ordered by their position in the file.
Throws:
Exception
Since:
2.11.12

sign

protected byte[] sign()
               throws GeneralSecurityException,
                      IOException

Finish the digest calculation on the digest returned from getMessageDigest() and return a signature token the signs it. The returned byte array will be stored as the "Contents" value of the Signature dictionary.

As well as being called to perform the actual signing, the default behaviour of the getVariables() method is also to call this method with an empty digest, to determine the size of the token to store in the PDF (the getMessageDigest() method is called twice as well). This can be overridden, by calling AcrobatSignatureHandlerFactory.setContentSize(int) for handlers created by that factory or, if you're implementing a custom signature handler, by writing your own getVariables() method.

Returns:
a byte array representing the signature token
Throws:
GeneralSecurityException - if the signature cannot be applied for some cryptographic reason
IOException - if the InputStream cannot be read
Since:
2.10 (this method existed earlier but took an InputStream as a parameter, and was required to create the digest now returned from getMessageDigest() internally)

getMessageDigest

protected abstract MessageDigest getMessageDigest()
Return a MessageDigest that will be used to calculate the digest of the PDF for signing. This message will be called before sign() - see the API docs for that method for more details.

Since:
2.10

verify

protected abstract boolean verify(InputStream in)
                           throws GeneralSecurityException,
                                  IOException
Return a boolean indicating whether or not the signature handler can verify the specified InputStream.

Returns:
true if the signature matches the specified InputStream
Throws:
GeneralSecurityException - if the signature cannot be verified for some cryptographic reason
IOException - if the InputStream cannot be read

prepareToSign

protected void prepareToSign(KeyStore keystore,
                             String alias,
                             char[] password)
                      throws GeneralSecurityException

This method initialized the handler using the specified values into a state where it's ready to sign. This method should be used to set any additional fields in the Signature dictionary, for example "Certs" for the Self-Sign handler.

Those overriding this method must call super.prepareToSign() before doing anything else.

Parameters:
keystore - the KeyStore
alias - which key to use
password - the password to use to decode the key
Throws:
GeneralSecurityException

getLayerNames

public abstract String[] getLayerNames()
Return the list of appearance layer names used by this Signature Handler to create a visible appearance on the page, in the order they should be drawn. This method is called internally by the FormSignature class when drawing the signature annotations on the page. For more information see the document "Digital Signature Appearances for Public-Key Interoperability", from Adobes website.

As an example, both the Verisign and the SelfSign handlers return the array [ "n0", "n1", "n2", "n3" ].

Returns:
the ordered list of layer names that should to used to create a visible representation of this signature on a page.
See Also:
getLayerAppearance(java.lang.String, org.faceless.pdf2.PDFStyle)

getLayerAppearance

public abstract PDFCanvas getLayerAppearance(String layername,
                                             PDFStyle style)
Return a PDFCanvas for the specified layer. This method is called internally by the FormSignature class when drawing the signature annotations on the page. For more information see the document "Digital Signature Appearances for Public-Key Interoperability", from Adobes website.

Parameters:
layername - the layer to create (from the list returned by getLayerNames())
style - the style in which to draw the text, if any
Returns:
a new PDFCanvas of any size containing the specified layer.
See Also:
getLayerNames()

getDefaultName

public String getDefaultName()
Returns an optional default value that can be used to initialize FormSignature.setName(java.lang.String), or null if no such name is available.

Since:
2.11

getFormSignature

public FormSignature getFormSignature()
Get the FormSignature this handler is attaached to

Since:
2.11.12


Copyright © 2001-2010 Big Faceless Organization