internetee-registry/app/models/certificate.rb

91 lines
2.6 KiB
Ruby

class Certificate < ActiveRecord::Base
include Versions
belongs_to :api_user
SIGNED = 'signed'
UNSIGNED = 'unsigned'
EXPIRED = 'expired'
REVOKED = 'revoked'
VALID = 'valid'
validates :csr, presence: true
def parsed_crt
@p_crt ||= OpenSSL::X509::Certificate.new(crt) if crt
end
def parsed_csr
@p_csr ||= OpenSSL::X509::Request.new(csr) if csr
end
def revoked?
status == REVOKED
end
def status
return UNSIGNED if crt.blank?
return @cached_status if @cached_status
@cached_status = SIGNED
if parsed_crt.not_before > Time.zone.now.utc && parsed_crt.not_after < Time.zone.now.utc
@cached_status = EXPIRED
end
crl = OpenSSL::X509::CRL.new(File.open(ENV['crl_path']).read)
return @cached_status unless crl.revoked.map(&:serial).include?(parsed_crt.serial)
@cached_status = REVOKED
end
def sign!
csr_file = Tempfile.new('client_csr')
csr_file.write(csr)
csr_file.rewind
crt_file = Tempfile.new('client_crt')
_out, err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
-cert #{ENV['ca_cert_path']} \
-extensions usr_cert -notext -md sha256 \
-in #{csr_file.path} -out #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
if err.match(/Data Base Updated/)
crt_file.rewind
self.crt = crt_file.read
save!
else
errors.add(:base, I18n.t('failed_to_create_certificate'))
logger.error('FAILED TO CREATE CLIENT CERTIFICATE')
logger.error(err)
# rubocop:disable Rails/Output
puts "Certificate sign issue: #{err.inspect}" if Rails.env.test?
# rubocop:enable Rails/Output
return false
end
end
def revoke!
crt_file = Tempfile.new('client_crt')
crt_file.write(crt)
crt_file.rewind
_out, err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
-cert #{ENV['ca_cert_path']} \
-revoke #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
if err.match(/Data Base Updated/) || err.match(/ERROR:Already revoked/)
save!
@cached_status = REVOKED
else
errors.add(:base, I18n.t('failed_to_revoke_certificate'))
logger.error('FAILED TO REVOKE CLIENT CERTIFICATE')
logger.error(err)
return false
end
_out, _err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
-cert #{ENV['ca_cert_path']} \
-gencrl -out #{ENV['crl_path']} -key '#{ENV['ca_key_password']}' -batch")
end
end