Module: HexaPDF::DigitalSignature::Signing
- Defined in:
- lib/hexapdf/digital_signature/signing.rb,
lib/hexapdf/digital_signature/signing/default_handler.rb,
lib/hexapdf/digital_signature/signing/timestamp_handler.rb,
lib/hexapdf/digital_signature/signing/signed_data_creator.rb
Overview
This module contains everything related to the signing of a PDF document, i.e. signing handlers and the actual code for signing.
-
The DefaultHandler is the standard signing handler and should be sufficient for most cases.
-
The TimestampHandler is used for timestamping purposes.
-
The SignedDataCreator provides the functionality to create custom CMS signed data objects.
Defined Under Namespace
Classes: DefaultHandler, SignedDataCreator, TimestampHandler
Class Method Summary collapse
-
.embed_signature(io, signature) ⇒ Object
Embeds the given
signature
into the /Contents value of the newest signature dictionary of the PDF document given by theio
argument. -
.locate_signature_dict(xref_section, start_xref_position, signature_oid) ⇒ Object
Uses the information in the given cross-reference section as well as the byte offset of the cross-reference section to calculate the offset and length of the signature dictionary with the given object id.
-
.replace_signature_contents(signature_data, contents) ⇒ Object
Replaces the value of the /Contents key in the serialized
signature_data
with the value ofcontents
.
Class Method Details
.embed_signature(io, signature) ⇒ Object
Embeds the given signature
into the /Contents value of the newest signature dictionary of the PDF document given by the io
argument.
This functionality can be used together with the support for external signing (see DefaultHandler and DefaultHandler#external_signing) to implement asynchronous signing.
Note: This will, most probably, only work on documents prepared for external signing by HexaPDF and not by other libraries.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/hexapdf/digital_signature/signing.rb', line 62 def self.(io, signature) doc = HexaPDF::Document.new(io: io) signature_dict = doc.signatures.find {|sig| doc.revisions.current.object(sig) == sig } signature_dict_offset, signature_dict_length = locate_signature_dict( doc.revisions.current.xref_section, doc.revisions.parser.startxref_offset, signature_dict.oid ) io.pos = signature_dict_offset signature_data = io.read(signature_dict_length) replace_signature_contents(signature_data, signature) io.pos = signature_dict_offset io.write(signature_data) end |
.locate_signature_dict(xref_section, start_xref_position, signature_oid) ⇒ Object
Uses the information in the given cross-reference section as well as the byte offset of the cross-reference section to calculate the offset and length of the signature dictionary with the given object id.
80 81 82 83 84 85 |
# File 'lib/hexapdf/digital_signature/signing.rb', line 80 def self.locate_signature_dict(xref_section, start_xref_position, signature_oid) data = xref_section.map {|oid, _gen, entry| [entry.pos, oid] if entry.in_use? }.compact.sort << [start_xref_position, nil] index = data.index {|_pos, oid| oid == signature_oid } [data[index][0], data[index + 1][0] - data[index][0]] end |
.replace_signature_contents(signature_data, contents) ⇒ Object
Replaces the value of the /Contents key in the serialized signature_data
with the value of contents
.
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/hexapdf/digital_signature/signing.rb', line 89 def self.replace_signature_contents(signature_data, contents) signature_data.sub!(/Contents(?:\(.*?\)|<.*?>)/) do |match| length = match.size result = "Contents<#{contents.unpack1('H*')}" if length < result.size raise HexaPDF::Error, "The reserved space for the signature was too small " \ "(#{(length - 10) / 2} vs #{(result.size - 10) / 2}) - use the handlers " \ "#signature_size method to increase the reserved space" end "#{result.ljust(length - 1, '0')}>" end end |