119 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
include OpenSSLCookbook::Helpers
 | 
						|
 | 
						|
property :name,             String, name_property: true
 | 
						|
property :owner,            String
 | 
						|
property :group,            String
 | 
						|
property :expire,           Integer
 | 
						|
property :mode,             [Integer, String]
 | 
						|
property :org,              String, required: true
 | 
						|
property :org_unit,         String, required: true
 | 
						|
property :country,          String, required: true
 | 
						|
property :common_name,      String, required: true
 | 
						|
property :subject_alt_name, Array, default: []
 | 
						|
property :key_file,         String
 | 
						|
property :key_pass,         String
 | 
						|
property :key_length,       equal_to: [1024, 2048, 4096, 8192], default: 2048
 | 
						|
 | 
						|
action :create do
 | 
						|
  unless ::File.exist? new_resource.name
 | 
						|
    converge_by("Create #{@new_resource}") do
 | 
						|
      create_keys
 | 
						|
      cert_content = cert.to_pem
 | 
						|
      key_content = key.to_pem
 | 
						|
 | 
						|
      file new_resource.name do
 | 
						|
        action :create_if_missing
 | 
						|
        mode new_resource.mode
 | 
						|
        owner new_resource.owner
 | 
						|
        group new_resource.group
 | 
						|
        sensitive true
 | 
						|
        content cert_content
 | 
						|
      end
 | 
						|
 | 
						|
      file new_resource.key_file do
 | 
						|
        action :create_if_missing
 | 
						|
        mode new_resource.mode
 | 
						|
        owner new_resource.owner
 | 
						|
        group new_resource.group
 | 
						|
        sensitive true
 | 
						|
        content key_content
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
action_class do
 | 
						|
  def generate_key_file
 | 
						|
    unless new_resource.key_file
 | 
						|
      path, file = ::File.split(new_resource.name)
 | 
						|
      filename = ::File.basename(file, ::File.extname(file))
 | 
						|
      new_resource.key_file path + '/' + filename + '.key'
 | 
						|
    end
 | 
						|
    new_resource.key_file
 | 
						|
  end
 | 
						|
 | 
						|
  def key
 | 
						|
    @key ||= if key_file_valid?(generate_key_file, new_resource.key_pass)
 | 
						|
               OpenSSL::PKey::RSA.new ::File.read(generate_key_file), new_resource.key_pass
 | 
						|
             else
 | 
						|
               OpenSSL::PKey::RSA.new(new_resource.key_length)
 | 
						|
             end
 | 
						|
    @key
 | 
						|
  end
 | 
						|
 | 
						|
  def cert
 | 
						|
    @cert ||= OpenSSL::X509::Certificate.new
 | 
						|
  end
 | 
						|
 | 
						|
  def gen_cert
 | 
						|
    cert
 | 
						|
    cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject)
 | 
						|
    cert.not_before = Time.now
 | 
						|
    cert.not_after = Time.now + (new_resource.expire.to_i * 24 * 60 * 60)
 | 
						|
    cert.public_key = key.public_key
 | 
						|
    cert.serial = 0x0
 | 
						|
    cert.version = 2
 | 
						|
  end
 | 
						|
 | 
						|
  def subject
 | 
						|
    @subject ||= '/C=' + new_resource.country +
 | 
						|
                 '/O=' + new_resource.org +
 | 
						|
                 '/OU=' + new_resource.org_unit +
 | 
						|
                 '/CN=' + new_resource.common_name
 | 
						|
  end
 | 
						|
 | 
						|
  def extensions
 | 
						|
    exts = []
 | 
						|
    exts << @ef.create_extension('basicConstraints', 'CA:TRUE', true)
 | 
						|
    exts << @ef.create_extension('subjectKeyIdentifier', 'hash')
 | 
						|
 | 
						|
    unless new_resource.subject_alt_name.empty?
 | 
						|
      san = {}
 | 
						|
      counters = {}
 | 
						|
      new_resource.subject_alt_name.each do |an|
 | 
						|
        kind, value = an.split(':', 2)
 | 
						|
        counters[kind] ||= 0
 | 
						|
        counters[kind] += 1
 | 
						|
        san["#{kind}.#{counters[kind]}"] = value
 | 
						|
      end
 | 
						|
      @ef.config['alt_names'] = san
 | 
						|
      exts << @ef.create_extension('subjectAltName', '@alt_names')
 | 
						|
    end
 | 
						|
 | 
						|
    exts
 | 
						|
  end
 | 
						|
 | 
						|
  def create_keys
 | 
						|
    gen_cert
 | 
						|
    @ef ||= OpenSSL::X509::ExtensionFactory.new
 | 
						|
    @ef.subject_certificate = cert
 | 
						|
    @ef.issuer_certificate = cert
 | 
						|
    @ef.config = OpenSSL::Config.load(OpenSSL::Config::DEFAULT_CONFIG_FILE)
 | 
						|
 | 
						|
    cert.extensions = extensions
 | 
						|
    cert.add_extension @ef.create_extension('authorityKeyIdentifier',
 | 
						|
                                           'keyid:always,issuer:always')
 | 
						|
    cert.sign key, OpenSSL::Digest::SHA256.new
 | 
						|
  end
 | 
						|
end
 |