Class: HexaPDF::Document::Signatures::DefaultHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/hexapdf/document/signatures.rb

Overview

This is the default signing handler which provides the ability to sign a document with a provided certificate using the adb.pkcs7.detached algorithm.

Additional functionality:

  • Optionally setting the reason, location and contact information.

  • Making the signature a certification signature by applying the DocMDP transform method.

Implementing a Signing Handler

This class also serves as an example on how to create a custom handler: The public methods #filter_name, #sub_filter_name, #signature_size, #finalize_objects and #sign are used by the digital signature algorithm.

Once a custom signing handler has been created, it can be registered under the 'signature.signing_handler' configuration option for easy use. It has to take keyword arguments in its initialize method to be compatible with the Signatures#handler method.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**arguments) ⇒ DefaultHandler

Creates a new DefaultHandler with the given attributes.



90
91
92
# File 'lib/hexapdf/document/signatures.rb', line 90

def initialize(**arguments)
  arguments.each {|name, value| send("#{name}=", value) }
end

Instance Attribute Details

#certificateObject

The certificate with which to sign the PDF.



66
67
68
# File 'lib/hexapdf/document/signatures.rb', line 66

def certificate
  @certificate
end

#certificate_chainObject

The certificate chain that should be embedded in the PDF; normally contains all certificates up to the root certificate.



73
74
75
# File 'lib/hexapdf/document/signatures.rb', line 73

def certificate_chain
  @certificate_chain
end

#contact_infoObject

The contact information. If used, will be set on the signature object.



82
83
84
# File 'lib/hexapdf/document/signatures.rb', line 82

def contact_info
  @contact_info
end

#doc_mdp_permissionsObject

The DocMDP permissions that should be set on the document.

See #doc_mdp_permissions=



87
88
89
# File 'lib/hexapdf/document/signatures.rb', line 87

def doc_mdp_permissions
  @doc_mdp_permissions
end

#keyObject

The private key for the #certificate.



69
70
71
# File 'lib/hexapdf/document/signatures.rb', line 69

def key
  @key
end

#locationObject

The signing location. If used, will be set on the signature object.



79
80
81
# File 'lib/hexapdf/document/signatures.rb', line 79

def location
  @location
end

#reasonObject

The reason for signing. If used, will be set on the signature object.



76
77
78
# File 'lib/hexapdf/document/signatures.rb', line 76

def reason
  @reason
end

Instance Method Details

#filter_nameObject

Returns the name to be set on the /Filter key when using this signing handler.



95
96
97
# File 'lib/hexapdf/document/signatures.rb', line 95

def filter_name
  :'Adobe.PPKLite'
end

#finalize_objects(_signature_field, signature) ⇒ Object

Finalizes the signature field as well as the signature dictionary before writing.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/hexapdf/document/signatures.rb', line 137

def finalize_objects(_signature_field, signature)
  signature[:Reason] = reason if reason
  signature[:Location] = location if location
  signature[:ContactInfo] = contact_info if contact_info

  if doc_mdp_permissions
    doc = signature.document
    if doc.signatures.count > 1
      raise HexaPDF::Error, "Can set DocMDP access permissions only on first signature"
    end
    params = doc.add({Type: :TransformParams, V: :'1.2', P: doc_mdp_permissions})
    sigref = doc.add({Type: :SigRef, TransformMethod: :DocMDP, DigestMethod: :SHA1,
                      TransformParams: params})
    signature[:Reference] = [sigref]
    (doc.catalog[:Perms] ||= {})[:DocMDP] = signature
  end
end

#sign(data) ⇒ Object

Returns the DER serialized OpenSSL::PKCS7 structure containing the signature for the given data.



157
158
159
160
# File 'lib/hexapdf/document/signatures.rb', line 157

def sign(data)
  OpenSSL::PKCS7.sign(@certificate, @key, data, @certificate_chain,
                      OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY).to_der
end

#signature_sizeObject

Returns the size of the signature that would be created.



132
133
134
# File 'lib/hexapdf/document/signatures.rb', line 132

def signature_size
  sign("").size
end

#sub_filter_nameObject

Returns the name to be set on the /SubFilter key when using this signing handler.



100
101
102
# File 'lib/hexapdf/document/signatures.rb', line 100

def sub_filter_name
  :'adbe.pkcs7.detached'
end