org.faceless.pdf2

## Class SignatureHandler

- java.lang.Object
- - org.faceless.pdf2.SignatureHandler

- Direct Known Subclasses:
    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. The main implementation is the one returned by `AcrobatSignatureHandlerFactory`. 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

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `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

    Constructors
    Constructor and Description
    `SignatureHandler()`

  - ### Method Summary

    All Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `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
    `int` | `getCertificationType()` Return the type of "Certification" the previously-signed signature this handler is attached to (see `getFormSignature()` attests to.
    `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<String>` | `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<String,SignatureHandler.Placeholder>` | `getVariables()` Return the list of "variables" which will be set by the handler after the PDF is rendered.
    `protected void` | `postDigest(long filelength, Map<String,SignatureHandler.Placeholder> variables)` Update any Variables that need to be updated after the Digest is calculated (eg Contents).
    `protected void` | `preDigest(long filelength, Map<String,SignatureHandler.Placeholder> 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<String> 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<String,SignatureHandler.Placeholder> 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<String,SignatureHandler.Placeholder> 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<String,SignatureHandler.Placeholder> 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

    - #### getCertificationType

          public int getCertificationType()

      Return the type of "Certification" the previously-signed signature this handler is attached to (see `getFormSignature()` attests to. One of `FormSignature.CERTIFICATION_UNCERTIFIED`, `FormSignature.CERTIFICATION_NOCHANGES`, `FormSignature.CERTIFICATION_ALLOWFORMS` or `FormSignature.CERTIFICATION_ALLOWCOMMENTS`. By default this method returns the certification from the standard PDF Signature certification dictionary, but subclasses can return their own restriction if necessary by overriding this method.
      Since:
        2.13
      See Also:
        `FormSignature.getCertificationType()`, `FormSignature.setCertificationType(int, java.lang.String)`

Copyright © 2001-2015 Big Faceless Organization