Add CreateX509SelfSignedCertificate
This commit is contained in:
parent
c8921d8562
commit
b45e21cbe7
2 changed files with 125 additions and 0 deletions
99
app/interactors/create_x509_self_signed_certificate.rb
Normal file
99
app/interactors/create_x509_self_signed_certificate.rb
Normal file
|
@ -0,0 +1,99 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateX509SelfSignedCertificate
|
||||
include Interactor
|
||||
|
||||
def call
|
||||
context.cert = cert
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def private_key_pkey
|
||||
@private_key_pkey ||= OpenSSL::PKey::RSA.new context.private_key_pem
|
||||
end
|
||||
|
||||
def public_key_pkey
|
||||
@public_key_pkey ||= OpenSSL::PKey::RSA.new context.public_key.pem
|
||||
end
|
||||
|
||||
def subject
|
||||
@subject ||= OpenSSL::X509::Name.parse context.distinguished_name
|
||||
end
|
||||
|
||||
def cert
|
||||
@cert ||= OpenSSL::X509::Certificate.new.tap do |cert|
|
||||
cert.version = 2
|
||||
cert.serial = 0
|
||||
cert.subject = subject
|
||||
cert.issuer = cert.subject
|
||||
cert.public_key = public_key_pkey
|
||||
cert.not_before = context.not_before
|
||||
cert.not_after = context.not_after
|
||||
|
||||
AddExtensions.call cert
|
||||
|
||||
cert.sign private_key_pkey, OpenSSL::Digest::SHA256.new
|
||||
end
|
||||
end
|
||||
|
||||
class AddExtensions
|
||||
def self.call(cert)
|
||||
new(cert).call
|
||||
end
|
||||
|
||||
def initialize(cert)
|
||||
@cert = cert
|
||||
end
|
||||
|
||||
def call
|
||||
cert.add_extension basic_constraints
|
||||
cert.add_extension key_usage
|
||||
cert.add_extension subject_key_ident
|
||||
cert.add_extension authority_key_ident
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :cert
|
||||
|
||||
def ext_factory
|
||||
@ext_factory ||= OpenSSL::X509::ExtensionFactory.new.tap do |ext_factory|
|
||||
ext_factory.subject_certificate = cert
|
||||
ext_factory.issuer_certificate = cert
|
||||
end
|
||||
end
|
||||
|
||||
def basic_constraints
|
||||
@basic_constraints ||= ext_factory.create_extension(
|
||||
'basicConstraints',
|
||||
'CA:TRUE',
|
||||
true,
|
||||
)
|
||||
end
|
||||
|
||||
def key_usage
|
||||
@key_usage ||= ext_factory.create_extension(
|
||||
'keyUsage',
|
||||
'keyCertSign, cRLSign',
|
||||
true,
|
||||
)
|
||||
end
|
||||
|
||||
def subject_key_ident
|
||||
@subject_key_ident ||= ext_factory.create_extension(
|
||||
'subjectKeyIdentifier',
|
||||
'hash',
|
||||
false,
|
||||
)
|
||||
end
|
||||
|
||||
def authority_key_ident
|
||||
@authority_key_ident ||= ext_factory.create_extension(
|
||||
'authorityKeyIdentifier',
|
||||
'keyid:always,issuer:always',
|
||||
false,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
26
spec/interactors/create_x509_self_signed_certificate_spec.rb
Normal file
26
spec/interactors/create_x509_self_signed_certificate_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CreateX509SelfSignedCertificate do
|
||||
subject do
|
||||
described_class.call(
|
||||
private_key_pem: private_key_pem,
|
||||
public_key: public_key,
|
||||
distinguished_name: distinguished_name,
|
||||
not_before: not_before,
|
||||
not_after: not_after,
|
||||
)
|
||||
end
|
||||
|
||||
let(:rsa_keys) { CreateRSAKeys.call }
|
||||
let(:private_key_pem) { rsa_keys.private_key_pem }
|
||||
let(:public_key) { rsa_keys.public_key }
|
||||
let(:distinguished_name) { "CN=#{Faker::Internet.domain_name}" }
|
||||
let(:not_before) { Faker::Time.backward.utc }
|
||||
let(:not_after) { Faker::Time.forward.utc }
|
||||
|
||||
specify do
|
||||
expect { subject }.not_to raise_error
|
||||
end
|
||||
end
|
Reference in a new issue