diff --git a/lib/rubrik.rb b/lib/rubrik.rb index 08105d1..54cb179 100644 --- a/lib/rubrik.rb +++ b/lib/rubrik.rb @@ -12,4 +12,5 @@ class Error < StandardError; end require_relative "rubrik/document/increment" require_relative "rubrik/document/serialize_object" require_relative "rubrik/fill_signature" +require_relative "rubrik/pkcs7_signature" require_relative "rubrik/sign" diff --git a/lib/rubrik/fill_signature.rb b/lib/rubrik/fill_signature.rb index d739ad5..dc6483e 100644 --- a/lib/rubrik/fill_signature.rb +++ b/lib/rubrik/fill_signature.rb @@ -1,8 +1,6 @@ # typed: true # frozen_string_literal: true -require "openssl" - module Rubrik module FillSignature extend T::Sig @@ -55,8 +53,7 @@ def call(io, signature_value_ref:, private_key:, public_key:, certificate_chain: io.pos = second_offset data_to_sign += T.must(io.read(second_length)) - signature = OpenSSL::PKCS7.sign(public_key, private_key, data_to_sign, certificate_chain, - OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY).to_der + signature = PKCS7Signature.call(data_to_sign, private_key:, certificate: public_key) hex_signature = T.let(signature, String).unpack1("H*") padded_contents_field = "<#{hex_signature.ljust(Document::SIGNATURE_SIZE, "0")}>" diff --git a/lib/rubrik/pkcs7_signature.rb b/lib/rubrik/pkcs7_signature.rb new file mode 100644 index 0000000..edbbb84 --- /dev/null +++ b/lib/rubrik/pkcs7_signature.rb @@ -0,0 +1,24 @@ +# typed: true +# frozen_string_literal: true + +require "openssl" + +module Rubrik + module PKCS7Signature + extend T::Sig + extend self + + OPEN_SSL_FLAGS = OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY + + sig {params( + data: String, + private_key: OpenSSL::PKey::RSA, + certificate: OpenSSL::X509::Certificate, + certificate_chain: T::Array[OpenSSL::X509::Certificate] + ).returns(String) + } + def call(data, private_key:, certificate:, certificate_chain: []) + OpenSSL::PKCS7.sign(certificate, private_key, data, certificate_chain, OPEN_SSL_FLAGS).to_der + end + end +end diff --git a/test/pkcs7_signature_test.rb b/test/pkcs7_signature_test.rb new file mode 100644 index 0000000..e7e4224 --- /dev/null +++ b/test/pkcs7_signature_test.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +# typed: true + +require "test_helper" + +class Rubrik::PKCS7SignatureTest < Rubrik::Test + def test_signature_generation + # Arrange + certificate_file = File.open("test/support/demo_cert.pem", "rb") + + private_key = OpenSSL::PKey::RSA.new(certificate_file, "") + certificate_file.rewind + certificate = OpenSSL::X509::Certificate.new(certificate_file) + + # Act + raw_result = Rubrik::PKCS7Signature.call("test", private_key:, certificate:) + + # Assert + result = OpenSSL::ASN1.decode(raw_result) + + assert_kind_of(OpenSSL::ASN1::Sequence, result) + + content_type = result.value.first + assert_equal("pkcs7-signedData", content_type.value) + + ensure + certificate_file&.close + end +end