Last active
April 29, 2022 21:20
-
-
Save nmarley/071521d8f0576dd6e386 to your computer and use it in GitHub Desktop.
Ruby script to generate SSL certificates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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