rubrik 0.2.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -6
- data/lib/rubrik/document/increment.rb +2 -2
- data/lib/rubrik/document.rb +18 -2
- data/lib/rubrik/fill_signature.rb +3 -6
- data/lib/rubrik/pkcs7_signature.rb +24 -0
- data/lib/rubrik/sign.rb +3 -3
- data/lib/rubrik/version.rb +1 -1
- data/lib/rubrik.rb +1 -0
- metadata +3 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a28dfceafc9ceb57e6b2a30f82b6e8ca237c8ce3381a05d6793568154775c43a
         | 
| 4 | 
            +
              data.tar.gz: 1a0a6f8b8079396583cdf27fae2638a9f24c16f0483c830d54a805dc707982f5
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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 | 
            -
             | 
| 56 | 
            -
            private_key = OpenSSL::PKey::RSA.new( | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 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:,  | 
| 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 << " | 
| 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"
         | 
    
        data/lib/rubrik/document.rb
    CHANGED
    
    | @@ -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 | 
            -
             | 
| 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 | 
            -
                       | 
| 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:,  | 
| 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 =  | 
| 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 | 
            -
                        | 
| 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:,  | 
| 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:,  | 
| 25 | 
            +
                  FillSignature.call(output, signature_value_ref:, private_key:, certificate:, certificate_chain:)
         | 
| 26 26 | 
             
                end
         | 
| 27 27 | 
             
              end
         | 
| 28 28 | 
             
            end
         | 
    
        data/lib/rubrik/version.rb
    CHANGED
    
    
    
        data/lib/rubrik.rb
    CHANGED
    
    
    
        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. | 
| 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- | 
| 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
         |