From 2979c7a38c37d5b918b6d428b725b56e8de28875 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 14 Sep 2019 02:28:55 +0500 Subject: [PATCH] Allow to set password --- app/interactors/create_rsa_keys.rb | 45 ++++++++++--- .../create_x509_self_signed_certificate.rb | 12 ++-- ...s_and_x509_self_signed_certificate_spec.rb | 22 +++++++ spec/interactors/create_rsa_keys_spec.rb | 64 +++++++++++++++++-- 4 files changed, 123 insertions(+), 20 deletions(-) diff --git a/app/interactors/create_rsa_keys.rb b/app/interactors/create_rsa_keys.rb index 71fc835..44b2dd3 100644 --- a/app/interactors/create_rsa_keys.rb +++ b/app/interactors/create_rsa_keys.rb @@ -16,20 +16,47 @@ class CreateRSAKeys private - def attributes - pkey = OpenSSL::PKey::RSA.new BITS + def pkey + @pkey ||= OpenSSL::PKey::RSA.new BITS + end + def attributes { account: context.account, + public_key_pem: public_key_pem, + public_key_der: public_key_der, + private_key_pem: private_key_pem, + + has_password: context.password.present?, bits: BITS, - - sha1: Digest::SHA1.hexdigest(pkey.public_key.to_der), - sha256: Digest::SHA256.hexdigest(pkey.public_key.to_der), - - public_key_pem: pkey.public_key.to_pem.freeze, - public_key_der: pkey.public_key.to_der.freeze, - private_key_pem: pkey.to_pem.freeze, + sha1: sha1, + sha256: sha256, } end + + def sha1 + @sha1 ||= Digest::SHA1.hexdigest(pkey.public_key.to_der).freeze + end + + def sha256 + @sha256 ||= Digest::SHA256.hexdigest(pkey.public_key.to_der).freeze + end + + def public_key_pem + @public_key_pem ||= pkey.public_key.to_pem.freeze + end + + def public_key_der + @public_key_der ||= pkey.public_key.to_der.freeze + end + + def private_key_pem + @private_key_pem ||= + if context.password.present? + pkey.to_pem(OpenSSL::Cipher::AES256.new, context.password).freeze + else + pkey.to_pem.freeze + end + end end diff --git a/app/interactors/create_x509_self_signed_certificate.rb b/app/interactors/create_x509_self_signed_certificate.rb index 642b92f..8c603fe 100644 --- a/app/interactors/create_x509_self_signed_certificate.rb +++ b/app/interactors/create_x509_self_signed_certificate.rb @@ -22,13 +22,17 @@ class CreateX509SelfSignedCertificate private def private_key_pkey - @private_key_pkey ||= - OpenSSL::PKey::RSA.new context.asymmetric_key.private_key_pem + @private_key_pkey ||= OpenSSL::PKey::RSA.new( + context.asymmetric_key.private_key_pem, + String(context.password), + ) end def public_key_pkey - @public_key_pkey ||= - OpenSSL::PKey::RSA.new context.asymmetric_key.public_key_pem + @public_key_pkey ||= OpenSSL::PKey::RSA.new( + context.asymmetric_key.public_key_pem, + String(context.password), + ) end def subject diff --git a/spec/interactors/create_rsa_keys_and_x509_self_signed_certificate_spec.rb b/spec/interactors/create_rsa_keys_and_x509_self_signed_certificate_spec.rb index 05556f1..5724d60 100644 --- a/spec/interactors/create_rsa_keys_and_x509_self_signed_certificate_spec.rb +++ b/spec/interactors/create_rsa_keys_and_x509_self_signed_certificate_spec.rb @@ -6,6 +6,7 @@ RSpec.describe CreateRSAKeysAndX509SelfSignedCertificate do subject do described_class.call( account: account, + password: password, distinguished_name: distinguished_name, not_before: not_before, not_after: not_after, @@ -13,6 +14,7 @@ RSpec.describe CreateRSAKeysAndX509SelfSignedCertificate do end let(:account) { create :initial_account } + let(:password) { Faker::Internet.password } let(:distinguished_name) { "CN=#{Faker::Internet.domain_name}" } let(:not_before) { Faker::Time.backward.utc } let(:not_after) { Faker::Time.forward.utc } @@ -42,6 +44,10 @@ RSpec.describe CreateRSAKeysAndX509SelfSignedCertificate do expect(subject.asymmetric_key).to be_instance_of RSAKey end + specify do + expect(subject.asymmetric_key.has_password).to equal true + end + specify do expect(subject.certificate).to be_instance_of X509Certificate end @@ -65,4 +71,20 @@ RSpec.describe CreateRSAKeysAndX509SelfSignedCertificate do expect(subject.asymmetric_key.account).to equal nil end end + + context 'when password is nil' do + let(:password) { nil } + + specify do + expect(subject.asymmetric_key.has_password).to equal false + end + end + + context 'when password is blank' do + let(:password) { ' ' * rand(1..3) } + + specify do + expect(subject.asymmetric_key.has_password).to equal false + end + end end diff --git a/spec/interactors/create_rsa_keys_spec.rb b/spec/interactors/create_rsa_keys_spec.rb index 38e0ebe..409a7af 100644 --- a/spec/interactors/create_rsa_keys_spec.rb +++ b/spec/interactors/create_rsa_keys_spec.rb @@ -3,9 +3,10 @@ require 'rails_helper' RSpec.describe CreateRSAKeys do - subject { described_class.call account: account } + subject { described_class.call account: account, password: password } let(:account) { create :initial_account } + let(:password) { Faker::Internet.password } specify do expect { subject }.to change(AsymmetricKey, :count).by(1) @@ -28,6 +29,10 @@ RSpec.describe CreateRSAKeys do expect(subject.asymmetric_key).to be_instance_of RSAKey end + specify do + expect(subject.asymmetric_key.has_password).to equal true + end + specify do expect(subject.asymmetric_key.sha1).not_to be_blank end @@ -50,13 +55,19 @@ RSpec.describe CreateRSAKeys do specify do expect do - OpenSSL::PKey::RSA.new subject.asymmetric_key.private_key_pem + OpenSSL::PKey::RSA.new( + subject.asymmetric_key.private_key_pem, + String(password), + ) end.not_to raise_error end specify do expect do - OpenSSL::PKey::RSA.new subject.asymmetric_key.public_key_pem + OpenSSL::PKey::RSA.new( + subject.asymmetric_key.public_key_pem, + String(password), + ) end.not_to \ raise_error end @@ -64,7 +75,10 @@ RSpec.describe CreateRSAKeys do specify do expect(subject.asymmetric_key.sha1).to eq( Digest::SHA1.hexdigest( - OpenSSL::PKey::RSA.new(subject.asymmetric_key.public_key_pem).to_der, + OpenSSL::PKey::RSA.new( + subject.asymmetric_key.public_key_pem, + String(password), + ).to_der, ), ) end @@ -72,15 +86,21 @@ RSpec.describe CreateRSAKeys do specify do expect(subject.asymmetric_key.sha256).to eq( Digest::SHA256.hexdigest( - OpenSSL::PKey::RSA.new(subject.asymmetric_key.public_key_pem).to_der, + OpenSSL::PKey::RSA.new( + subject.asymmetric_key.public_key_pem, + String(password), + ).to_der, ), ) end specify do expect(subject.asymmetric_key.public_key_pem).to eq( - OpenSSL::PKey::RSA.new(subject.asymmetric_key.private_key_pem) - .public_key.to_pem, + OpenSSL::PKey::RSA.new( + subject.asymmetric_key.private_key_pem, + String(password), + ) + .public_key.to_pem, ) end @@ -113,4 +133,34 @@ RSpec.describe CreateRSAKeys do expect(subject.asymmetric_key.account).to equal nil end end + + context 'when password is nil' do + let(:password) { nil } + + specify do + expect(subject.asymmetric_key.has_password).to equal false + end + end + + context 'when password is blank' do + let(:password) { ' ' * rand(1..3) } + + specify do + expect(subject.asymmetric_key.has_password).to equal false + end + end + + context 'when password.to_s returns nil' do + let :password do + Class.new do + def to_s + nil + end + end.new + end + + specify do + expect { subject }.to raise_error TypeError + end + end end