rubrik 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9faab13628886a83554fb2dd75b71d7315701da037377bb70d7aba3e9769ffe
4
- data.tar.gz: 90fbf56ed6afbd1ab7b54ad4290800ad079fd4b600eb4334f2974a248b2631c9
3
+ metadata.gz: a28dfceafc9ceb57e6b2a30f82b6e8ca237c8ce3381a05d6793568154775c43a
4
+ data.tar.gz: 1a0a6f8b8079396583cdf27fae2638a9f24c16f0483c830d54a805dc707982f5
5
5
  SHA512:
6
- metadata.gz: 3a83c73ca910d0ce84298c65d7f704ed93ccd3104bb44f1d70331b82bdcdecae1355fb2b5a0b8177a9954b3c39394153cbb521cf67ec4d4a677fc98684c90f5e
7
- data.tar.gz: 0da9fd89c054a40db22642cfb4b390be64fb49c12b42f449d901c898b86bcd10d4f8e72892ecfc59618aca1678f115165209a41497315c3b2f1cde8d29882194
6
+ metadata.gz: 4b294ed919bade9e09eef834afb47a17f65928b40099a9add84f079df46102e852a7289c7fbacbb745b67929ae14098fc002ebd2b12987a921e4461b5996a406
7
+ data.tar.gz: 283e213a97967fb54d4c2b21f2ab009e96c434a93b26f3ff34ee4f75cfdcd925bd5cbc633bcb22844822ed4eb2e36efa4158f33b40f633b5ade6af7c9d97d30a
data/README.md CHANGED
@@ -52,14 +52,14 @@ input_pdf = File.open("example.pdf", "rb")
52
52
  output_pdf = File.open("signed_example.pdf", "wb+") # needs read permission
53
53
 
54
54
  # Load Certificate(s)
55
- certificate = File.open("example_cert.pem", "rb")
56
- private_key = OpenSSL::PKey::RSA.new(certificate, "")
57
- certificate.rewind
58
- public_key = OpenSSL::X509::Certificate.new(certificate)
59
- certificate.close
55
+ certificate_file = File.open("example_cert.pem", "rb")
56
+ private_key = OpenSSL::PKey::RSA.new(certificate_file, "")
57
+ certificate_file.rewind
58
+ certificate = OpenSSL::X509::Certificate.new(certificate_file)
59
+ certificate_file.close
60
60
 
61
61
  # Will write the signed document to `output_pdf`
62
- Rubrik::Sign.call(input_pdf, output_pdf, private_key:, public_key:, certificate_chain: [])
62
+ Rubrik::Sign.call(input_pdf, output_pdf, private_key:, certificate:, certificate_chain: [])
63
63
 
64
64
  # Don't forget to close the files
65
65
  input_pdf.close
@@ -46,11 +46,11 @@ module Rubrik
46
46
  io << "#{starting_id} #{length}\n"
47
47
 
48
48
  if starting_id.zero?
49
- io << "0000000000 65535 f\n"
49
+ io << "#{format("%010d", document.first_free_object_id)} 65535 f \n"
50
50
  subsection.shift
51
51
  end
52
52
 
53
- subsection.each { |entry| io << "#{format("%010d", entry[:offset])} 00000 n\n" }
53
+ subsection.each { |entry| io << "#{format("%010d", entry[:offset])} 00000 n \n" }
54
54
  end
55
55
 
56
56
  io << "trailer\n"
@@ -17,19 +17,25 @@ module Rubrik
17
17
  sig {returns(PDF::Reader::ObjectHash)}
18
18
  attr_accessor :objects
19
19
 
20
+ sig {returns(Integer)}
21
+ attr_accessor :first_free_object_id
22
+
20
23
  sig {returns(T::Array[{id: PDF::Reader::Reference, value: T.untyped}])}
21
24
  attr_accessor :modified_objects
22
25
 
23
26
  sig {returns(Integer)}
24
27
  attr_accessor :last_object_id
25
28
 
26
- private :io=, :objects=, :modified_objects=, :last_object_id=
29
+ private :io=, :objects=, :first_free_object_id=, :modified_objects=, :last_object_id=
27
30
 
28
31
  sig {params(input: T.any(File, Tempfile, StringIO)).void}
29
32
  def initialize(input)
30
33
  self.io = input
31
34
  self.objects = PDF::Reader::ObjectHash.new(input)
32
- self.last_object_id = objects.size
35
+
36
+ self.last_object_id = objects.trailer[:Size] - 1
37
+ self.first_free_object_id = find_first_free_object_id
38
+
33
39
  self.modified_objects = []
34
40
 
35
41
  fetch_or_create_interactive_form!
@@ -87,6 +93,16 @@ module Rubrik
87
93
  T.must(modified_objects.first).fetch(:value)
88
94
  end
89
95
 
96
+ sig{returns(Integer)}
97
+ def find_first_free_object_id
98
+ return 0 if last_object_id == objects.size
99
+
100
+ xref = objects.send(:xref).instance_variable_get(:@xref)
101
+ missing_ids = (1..last_object_id).to_a - xref.keys
102
+
103
+ T.must(missing_ids.min)
104
+ end
105
+
90
106
  sig {void}
91
107
  def fetch_or_create_interactive_form!
92
108
  root_ref = objects.trailer[:Root]
@@ -1,8 +1,6 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- require "openssl"
5
-
6
4
  module Rubrik
7
5
  module FillSignature
8
6
  extend T::Sig
@@ -13,13 +11,13 @@ module Rubrik
13
11
  io: T.any(File, StringIO, Tempfile),
14
12
  signature_value_ref: PDF::Reader::Reference,
15
13
  private_key: OpenSSL::PKey::RSA,
16
- public_key: OpenSSL::X509::Certificate,
14
+ certificate: OpenSSL::X509::Certificate,
17
15
  certificate_chain: T::Array[OpenSSL::X509::Certificate])
18
16
  .void}
19
17
 
20
18
  FIRST_OFFSET = 0
21
19
 
22
- def call(io, signature_value_ref:, private_key:, public_key:, certificate_chain: [])
20
+ def call(io, signature_value_ref:, private_key:, certificate:, certificate_chain: [])
23
21
  io.rewind
24
22
 
25
23
  signature_value_offset = PDF::Reader::XRef.new(io)[signature_value_ref]
@@ -55,8 +53,7 @@ module Rubrik
55
53
  io.pos = second_offset
56
54
  data_to_sign += T.must(io.read(second_length))
57
55
 
58
- signature = OpenSSL::PKCS7.sign(public_key, private_key, data_to_sign, certificate_chain,
59
- OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY).to_der
56
+ signature = PKCS7Signature.call(data_to_sign, private_key:, certificate:)
60
57
  hex_signature = T.let(signature, String).unpack1("H*")
61
58
 
62
59
  padded_contents_field = "<#{hex_signature.ljust(Document::SIGNATURE_SIZE, "0")}>"
@@ -0,0 +1,24 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "openssl"
5
+
6
+ module Rubrik
7
+ module PKCS7Signature
8
+ extend T::Sig
9
+ extend self
10
+
11
+ OPEN_SSL_FLAGS = OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY
12
+
13
+ sig {params(
14
+ data: String,
15
+ private_key: OpenSSL::PKey::RSA,
16
+ certificate: OpenSSL::X509::Certificate,
17
+ certificate_chain: T::Array[OpenSSL::X509::Certificate]
18
+ ).returns(String)
19
+ }
20
+ def call(data, private_key:, certificate:, certificate_chain: [])
21
+ OpenSSL::PKCS7.sign(certificate, private_key, data, certificate_chain, OPEN_SSL_FLAGS).to_der
22
+ end
23
+ end
24
+ end
data/lib/rubrik/sign.rb CHANGED
@@ -9,10 +9,10 @@ module Rubrik
9
9
  input: T.any(File, Tempfile, StringIO),
10
10
  output: T.any(File, Tempfile, StringIO),
11
11
  private_key: OpenSSL::PKey::RSA,
12
- public_key: OpenSSL::X509::Certificate,
12
+ certificate: OpenSSL::X509::Certificate,
13
13
  certificate_chain: T::Array[OpenSSL::X509::Certificate])
14
14
  .void}
15
- def self.call(input, output, private_key:, public_key:, certificate_chain: [])
15
+ def self.call(input, output, private_key:, certificate:, certificate_chain: [])
16
16
  input.binmode
17
17
  output.reopen(T.unsafe(output), "wb+") if !output.is_a?(StringIO)
18
18
 
@@ -22,7 +22,7 @@ module Rubrik
22
22
 
23
23
  Document::Increment.call(document, io: output)
24
24
 
25
- FillSignature.call(output, signature_value_ref:, private_key:, public_key:, certificate_chain:)
25
+ FillSignature.call(output, signature_value_ref:, private_key:, certificate:, certificate_chain:)
26
26
  end
27
27
  end
28
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubrik
4
- VERSION = "0.2.1"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/rubrik.rb CHANGED
@@ -12,4 +12,5 @@ require_relative "rubrik/document"
12
12
  require_relative "rubrik/document/increment"
13
13
  require_relative "rubrik/document/serialize_object"
14
14
  require_relative "rubrik/fill_signature"
15
+ require_relative "rubrik/pkcs7_signature"
15
16
  require_relative "rubrik/sign"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubrik
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Coêlho
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-20 00:00:00.000000000 Z
11
+ date: 2023-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pdf-reader
@@ -66,6 +66,7 @@ files:
66
66
  - lib/rubrik/document/increment.rb
67
67
  - lib/rubrik/document/serialize_object.rb
68
68
  - lib/rubrik/fill_signature.rb
69
+ - lib/rubrik/pkcs7_signature.rb
69
70
  - lib/rubrik/sign.rb
70
71
  - lib/rubrik/version.rb
71
72
  homepage: https://github.com/tomascco/rubrik