20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/rubrik/fill_signature.rb', line 20
def call(io, signature_value_ref:, private_key:, certificate:, certificate_chain: [])
io.rewind
signature_value_offset = PDF::Reader::XRef.new(io)[signature_value_ref]
io.pos = signature_value_offset
io.gets("/Contents")
io.gets("<")
first_length = io.pos - 1
second_offset = first_length + Document::SIGNATURE_SIZE + 2
second_length = io.size - second_offset
byte_range_array = [FIRST_OFFSET, first_length, second_offset, second_length]
io.pos = signature_value_offset
io.gets("/ByteRange")
byte_range_start = io.pos - "/ByteRange".size
io.gets("]")
byte_range_end = io.pos
byte_range_size = byte_range_end - byte_range_start + 1
actual_byte_range = " /ByteRange [#{byte_range_array.join(" ")}]".ljust(byte_range_size, " ")
io.seek(-byte_range_size, IO::SEEK_CUR)
io.write(actual_byte_range)
io.pos = FIRST_OFFSET
data_to_sign = T.must(io.read(first_length))
io.pos = second_offset
data_to_sign += T.must(io.read(second_length))
signature = PKCS7Signature.call(data_to_sign, private_key:, certificate:)
hex_signature = T.let(signature, String).unpack1("H*")
padded_contents_field = "<#{hex_signature.ljust(Document::SIGNATURE_SIZE, "0")}>"
io.pos = first_length
io.write(padded_contents_field)
io.rewind
io
end
|