Skip to content

Instantly share code, notes, and snippets.

@nmarley
Last active April 29, 2022 21:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nmarley/071521d8f0576dd6e386 to your computer and use it in GitHub Desktop.
Save nmarley/071521d8f0576dd6e386 to your computer and use it in GitHub Desktop.
Ruby script to generate SSL certificates
#! /usr/bin/env ruby
#
# gencert.rb
# =====================================================================
# description: This script will accepts an FQDN as an argument
# and generates a Secure Sockets Layer (SSL)
# certificate request and a private key that corresponds
# to the request. It will not overwrite any existing
# files, so file <fqdn>.cnf , <fqdn>.csr , or <fqdn>.key
# exist, the program will print a message and exit.
#
# The private key is stored in <fqdn>.key , and the cert
# request is stored in <fqdn>.csr . The .csr file is
# what must be sent to a Certificate Authority (CA),
# such as Geotrust or Thawte.
# =====================================================================
require 'singleton'
require 'ostruct'
require 'openssl'
require 'pp'
class CertificateRequestFactory
include Singleton
class << self
def generate_request(args = {})
args = defaults.merge(args)
key = gen_key(args[:encryption_type], args[:encryption_bits])
csr = gen_csr(key: key, common_name: args[:fqdn])
OpenStruct.new(key: key, csr: csr)
end
private
def defaults
{
encryption_type: :rsa,
encryption_bits: 4096,
}
end
def csr_options
{
country: 'BE',
state: 'Oost-Vlaanderen',
city: 'Gent',
organization: 'Black Carrot Ventures',
department: 'Information Security',
email: 'infosec@blackcarrot.be',
}
end
def gen_key(type, bits)
klass = const_get("OpenSSL::PKey::#{type.to_s.upcase}")
key = klass.new(bits)
end
def gen_csr(args = {})
args = csr_options.merge(args)
key = args[:key]
req = OpenSSL::X509::Request.new
req.version = 0
req.subject = OpenSSL::X509::Name.new([
['C', args[:country], OpenSSL::ASN1::PRINTABLESTRING],
['ST', args[:state], OpenSSL::ASN1::PRINTABLESTRING],
['L', args[:city], OpenSSL::ASN1::PRINTABLESTRING],
['O', args[:organization], OpenSSL::ASN1::UTF8STRING],
['OU', args[:department], OpenSSL::ASN1::UTF8STRING],
['CN', args[:common_name], OpenSSL::ASN1::UTF8STRING],
['emailAddress', args[:email], OpenSSL::ASN1::UTF8STRING]
])
req.public_key = key.public_key
req.sign(key, OpenSSL::Digest::SHA1.new)
req
end
end
end
if __FILE__ == $0
progname = File.basename($0)
usage = "usage: #{progname} <fqdn>"
if ( ARGV.count <= 0 )
$stderr.puts("No fqdn argument given")
$stderr.puts(usage)
exit(2)
end
fqdn = ARGV.shift
csrfile = fqdn + ".csr"
keyfile = fqdn + ".key"
req = CertificateRequestFactory.generate_request(fqdn: fqdn)
unless File.exist?(keyfile)
File.open(keyfile, "w") { |f| f.write(req.key) }
end
unless File.exist?(csrfile)
File.open(csrfile, "w") { |f| f.write(req.csr) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment