main
 1# frozen_string_literal: true
 2
 3module Xml
 4  module Kit
 5    class SelfSignedCertificate
 6      SUBJECT = '/C=CA/ST=AB/L=Calgary/O=XmlKit/OU=XmlKit/CN=XmlKit'
 7
 8      def create(algorithm: 'AES-256-CBC',
 9                 passphrase: nil,
10                 key_pair: OpenSSL::PKey::RSA.new(2048))
11        certificate = certificate_for(key_pair.public_key)
12        certificate.sign(key_pair, OpenSSL::Digest::SHA256.new)
13        [certificate.to_pem, export(key_pair, algorithm, passphrase)]
14      end
15
16      private
17
18      def export(key_pair, algorithm, passphrase)
19        if passphrase.present?
20          cipher = OpenSSL::Cipher.new(algorithm)
21          key_pair.export(cipher, passphrase)
22        else
23          key_pair.export
24        end
25      end
26
27      def certificate_for(public_key)
28        certificate = OpenSSL::X509::Certificate.new
29        certificate.subject =
30          certificate.issuer = OpenSSL::X509::Name.parse(SUBJECT)
31        certificate.not_before = Time.now
32        certificate.not_after = certificate.not_before + 30 * 24 * 60 * 60 # 30 days
33        certificate.public_key = public_key
34        certificate.serial = 0x0
35        certificate.version = 2
36        apply_ski_extension_to(certificate)
37        certificate
38      end
39
40      def apply_ski_extension_to(certificate)
41        extensions = OpenSSL::X509::ExtensionFactory.new
42        extensions.subject_certificate = certificate
43        extensions.issuer_certificate = certificate
44        certificate.add_extension(
45          extensions.create_extension('subjectKeyIdentifier', 'hash', false)
46        )
47      end
48    end
49  end
50end